You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.8 KiB
94 lines
2.8 KiB
import logging
|
|
|
|
from ctypes import *
|
|
from comtypes.hresult import *
|
|
|
|
from comtypes import COMObject, IUnknown
|
|
from comtypes.automation import IDispatch, IEnumVARIANT
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# XXX When the COMCollection class is ready, insert it into __all__
|
|
__all__ = ["VARIANTEnumerator"]
|
|
|
|
|
|
class VARIANTEnumerator(COMObject):
|
|
"""A universal VARIANTEnumerator class. Instantiate it with a
|
|
collection of items that support the IDispatch interface."""
|
|
_com_interfaces_ = [IEnumVARIANT]
|
|
|
|
def __init__(self, items):
|
|
self.items = items # keep, so that we can restore our iterator (in Reset, and Clone).
|
|
self.seq = iter(self.items)
|
|
super(VARIANTEnumerator, self).__init__()
|
|
|
|
def Next(self, this, celt, rgVar, pCeltFetched):
|
|
if not rgVar: return E_POINTER
|
|
if not pCeltFetched: pCeltFetched = [None]
|
|
pCeltFetched[0] = 0
|
|
try:
|
|
for index in range(celt):
|
|
item = next(self.seq)
|
|
p = item.QueryInterface(IDispatch)
|
|
rgVar[index].value = p
|
|
pCeltFetched[0] += 1
|
|
except StopIteration:
|
|
pass
|
|
## except:
|
|
## # ReportException? return E_FAIL?
|
|
## import traceback
|
|
## traceback.print_exc()
|
|
|
|
if pCeltFetched[0] == celt:
|
|
return S_OK
|
|
return S_FALSE
|
|
|
|
def Skip(self, this, celt):
|
|
# skip some elements.
|
|
try:
|
|
for _ in range(celt):
|
|
next(self.seq)
|
|
except StopIteration:
|
|
return S_FALSE
|
|
return S_OK
|
|
|
|
def Reset(self, this):
|
|
self.seq = iter(self.items)
|
|
return S_OK
|
|
|
|
# Clone not implemented
|
|
|
|
################################################################
|
|
|
|
# XXX Shouldn't this be a mixin class?
|
|
# And isn't this class borked anyway?
|
|
|
|
class COMCollection(COMObject):
|
|
"""Abstract base class which implements Count, Item, and _NewEnum."""
|
|
def __init__(self, itemtype, collection):
|
|
self.collection = collection
|
|
self.itemtype = itemtype
|
|
super(COMCollection, self).__init__()
|
|
|
|
def _get_Item(self, this, pathname, pitem):
|
|
if not pitem:
|
|
return E_POINTER
|
|
item = self.itemtype(pathname)
|
|
return item.IUnknown_QueryInterface(None,
|
|
pointer(pitem[0]._iid_),
|
|
pitem)
|
|
|
|
def _get_Count(self, this, pcount):
|
|
if not pcount:
|
|
return E_POINTER
|
|
pcount[0] = len(self.collection)
|
|
return S_OK
|
|
|
|
def _get__NewEnum(self, this, penum):
|
|
if not penum:
|
|
return E_POINTER
|
|
enum = VARIANTEnumerator(self.itemtype, self.collection)
|
|
return enum.IUnknown_QueryInterface(None,
|
|
pointer(IUnknown._iid_),
|
|
penum)
|