ctypes-commit Mailing List for ctypes (Page 45)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2005-07-07 11:18:40
|
Update of /cvsroot/ctypes/ctypes/win32/com/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3324 Modified Files: Tag: branch_1_0 readtlb.py Log Message: Need to import VARIANT_BOOL in the generated header. Index: readtlb.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/tools/readtlb.py,v retrieving revision 1.29.4.1 retrieving revision 1.29.4.2 diff -C2 -d -r1.29.4.1 -r1.29.4.2 *** readtlb.py 7 Jul 2005 11:15:43 -0000 1.29.4.1 --- readtlb.py 7 Jul 2005 11:18:32 -0000 1.29.4.2 *************** *** 602,606 **** from ctypes.com import IUnknown, GUID, STDMETHOD, HRESULT from ctypes.com.automation import IDispatch, BSTR, VARIANT, dispinterface, \ ! DISPMETHOD, DISPPARAMS, EXCEPINFO """ --- 602,606 ---- from ctypes.com import IUnknown, GUID, STDMETHOD, HRESULT from ctypes.com.automation import IDispatch, BSTR, VARIANT, dispinterface, \ ! DISPMETHOD, DISPPARAMS, EXCEPINFO, VARIANT_BOOL """ |
From: Thomas H. <th...@us...> - 2005-07-07 11:17:08
|
Update of /cvsroot/ctypes/ctypes/win32/com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2704 Modified Files: Tag: branch_1_0 ChangeLog Log Message: *** empty log message *** Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/ChangeLog,v retrieving revision 1.8.4.2 retrieving revision 1.8.4.3 diff -C2 -d -r1.8.4.2 -r1.8.4.3 *** ChangeLog 18 May 2005 07:06:00 -0000 1.8.4.2 --- ChangeLog 7 Jul 2005 11:16:56 -0000 1.8.4.3 *************** *** 1,2 **** --- 1,7 ---- + 2005-07-07 Thomas Heller <th...@py...> + + * tools\readtlb.py: Code for VARIANT_BOOL must be generated as + c_short, not c_int. + 2005-05-18 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2005-07-07 11:15:52
|
Update of /cvsroot/ctypes/ctypes/win32/com/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2178 Modified Files: Tag: branch_1_0 readtlb.py Log Message: Important bugfix: Code for VARIANT_BOOL was generated as c_int, but should be VARIANT_BOOL aka c_short. Index: readtlb.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/win32/com/tools/readtlb.py,v retrieving revision 1.29 retrieving revision 1.29.4.1 diff -C2 -d -r1.29 -r1.29.4.1 *** readtlb.py 6 Sep 2004 19:19:07 -0000 1.29 --- readtlb.py 7 Jul 2005 11:15:43 -0000 1.29.4.1 *************** *** 80,84 **** VT_DISPATCH: "POINTER(IDispatch)", ! VT_BOOL: "c_int", # we don't have a c_bool (or com_bool?) type yet VT_VARIANT: "VARIANT", VT_UNKNOWN: "POINTER(IUnknown)", --- 80,84 ---- VT_DISPATCH: "POINTER(IDispatch)", ! VT_BOOL: "VARIANT_BOOL", VT_VARIANT: "VARIANT", VT_UNKNOWN: "POINTER(IUnknown)", |
From: Thomas H. <th...@us...> - 2005-07-07 09:18:11
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5129 Modified Files: Tag: branch_1_0 automation.py Log Message: Repair the IEnumVARIANT methods. Allow VT_DISPATCH and VT_UNKNOWN to be retrived from VARIANT. Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.12.2.7 retrieving revision 1.12.2.8 diff -C2 -d -r1.12.2.7 -r1.12.2.8 *** automation.py 6 Jul 2005 10:06:36 -0000 1.12.2.7 --- automation.py 7 Jul 2005 09:17:58 -0000 1.12.2.8 *************** *** 237,243 **** --- 237,258 ---- else: return self._.VT_CY / 10000. + elif vt == VT_UNKNOWN: + ptr = cast(self._.c_void_p, POINTER(IUnknown)).__ctypes_from_outparam__() + # cast doesn't call AddRef (it should, imo!) + ptr.AddRef() + return ptr + elif vt == VT_DISPATCH: + ptr = cast(self._.c_void_p, POINTER(IDispatch)).__ctypes_from_outparam__() + # cast doesn't call AddRef (it should, imo!) + ptr.AddRef() + return ptr else: raise "NYI", vt + """ + VT_DISPATCH + VT_UNKNOWN + """ + # these are missing: ## getter[VT_ERROR] *************** *** 301,316 **** return self def next(self): ! item, fetched = self.Next(1) if fetched: ! return item raise StopIteration def __getitem__(self, index): self.Reset() self.Skip(index) ! item, fetched = self.Next(1) if fetched: ! return item raise IndexError, index --- 316,334 ---- return self + # does not yet work because retrieving VT_DISPATCH from VARIANT does not yet work. def next(self): ! var = VARIANT() ! fetched = self.Next(1, byref(var)) if fetched: ! return var.value raise StopIteration def __getitem__(self, index): + var = VARIANT() self.Reset() self.Skip(index) ! fetched = self.Next(1) if fetched: ! return var.value raise IndexError, index |
From: Thomas H. <th...@us...> - 2005-07-06 13:22:13
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6236 Modified Files: Tag: branch_1_0 __init__.py Log Message: Add some comments about _NewEnum. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.13 retrieving revision 1.25.2.14 diff -C2 -d -r1.25.2.13 -r1.25.2.14 *** __init__.py 6 Jul 2005 10:46:20 -0000 1.25.2.13 --- __init__.py 6 Jul 2005 13:22:00 -0000 1.25.2.14 *************** *** 503,510 **** return length ## def __iter__(self): ! ## print "__iter__", self._NewEnum def __getitem__(self, index): try: mth = self.Item --- 503,524 ---- return length + # _NewEnum should be a propget property, with dispid -4. See: + # http://msdn.microsoft.com/library/en-us/automat/htm/chap2_2ws9.asp + # http://msdn.microsoft.com/library/en-us/automat/htm/chap4_64j7.asp + # + # Sometimes, however, it is a method. + + # The following does not yet work, so it is disabled. + # See comtypes.automation.IEnumVARIANT ## def __iter__(self): ! ## enum = self._NewEnum ! ## if isinstance(enum, type(self.__iter__)): ! ## enum = enum() ! ## from comtypes.automation import IEnumVARIANT ! ## return enum.QueryInterface(IEnumVARIANT) def __getitem__(self, index): + # We should probably try to insist on a Count method also. + # And/Or we should insits that the Item method has a dispid of DISPID_VALUE ( 0 ). try: mth = self.Item *************** *** 513,521 **** try: result = mth(index + 1) - print "__getitem__", bool(result) except WindowsError, detail: raise IndexError, "invalid index" ! if not result: raise IndexError, "invalid index" return result --- 527,536 ---- try: result = mth(index + 1) except WindowsError, detail: raise IndexError, "invalid index" ! if not result: # we got a NULL com pointer raise IndexError, "invalid index" + # Hm, _NewEnum returns a IEnumVARIANT pointer. + # This has items of IUnknown*. What does .Item() have? What about 'wrap'? return result |
From: Thomas H. <th...@us...> - 2005-07-06 10:46:33
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv22416 Modified Files: Tag: branch_1_0 __init__.py Log Message: Start to add support for dispinterfaces. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.12 retrieving revision 1.25.2.13 diff -C2 -d -r1.25.2.12 -r1.25.2.13 *** __init__.py 1 Jul 2005 18:53:47 -0000 1.25.2.12 --- __init__.py 6 Jul 2005 10:46:20 -0000 1.25.2.13 *************** *** 81,87 **** --- 81,90 ---- def __new__(self, name, bases, namespace): methods = namespace.pop("_methods_", None) + dispmethods = namespace.pop("_disp_methods_", None) cls = type.__new__(self, name, bases, namespace) if methods is not None: setattr(cls, "_methods_", methods) + if dispmethods is not None: + setattr(cls, "_disp_methods_", dispmethods) # If we sublass a COM interface, for example: *************** *** 108,113 **** --- 111,145 ---- if name == "_methods_": self._make_methods(value) + elif name == "_disp_methods_": + self._make_dispmethods(value) type.__setattr__(self, name, value) + def _make_dispmethods(self, methods): + # create dispinterface methods and properties on the interface 'self' + for m in methods: + what, name, idlflags, restype, argspec = m + # argspec is a sequence of tuples, each tuple is: + # ([paramflags], type, name) + try: + memid = [x for x in idlflags if isinstance(x, int)][0] + except IndexError: + raise TypeError, "no dispid found in idlflags" + if what == "DISPPROPERTY": # DISPPROPERTY + assert not argspec # XXX does not yet work for properties with parameters + accessor = self._disp_property(memid, idlflags) + setattr(self, name, accessor) + elif what == "DISPMETHOD": # DISPMETHOD + # method + pass + + def _disp_property(self, memid, idlflags): + def get(obj): + return obj.Invoke(memid, _invkind=2) # DISPATCH_PROPERTYGET + if "readonly" in idlflags: + return property(get) + def set(obj, value): + return obj.Invoke(memid, value, _invkind=4) # DISPATCH_PROPERTYPUT + return property(get, set) + def __get_baseinterface_methodcount(self): "Return the number of com methods in the base interfaces" *************** *** 125,129 **** self.__dict__["_iid_"] except KeyError: ! raise AttributeError, "must define _iid_" vtbl_offset = self.__get_baseinterface_methodcount() --- 157,161 ---- self.__dict__["_iid_"] except KeyError: ! raise AttributeError, "this class must define an _iid_" vtbl_offset = self.__get_baseinterface_methodcount() *************** *** 315,327 **** def DISPMETHOD(idlflags, restype, name, *argspec): "Specifies a method of a dispinterface" ! # XXX WRONG WRONG WRONG ! return COMMETHOD(idlflags, restype, name, *argspec) def DISPPROPERTY(idlflags, proptype, name): "Specifies a property of a dispinterface" ! # XXX WRONG WRONG WRONG ! #? return COMMETHOD(idlflags, HRESULT, name, ([], proptype, 'rhs') ) ! return COMMETHOD(idlflags, HRESULT, name, (['out', 'retval'], POINTER(proptype), 'rhs') ) ## sample generated code: --- 347,363 ---- def DISPMETHOD(idlflags, restype, name, *argspec): "Specifies a method of a dispinterface" ! return "DISPMETHOD", name, idlflags, restype, argspec def DISPPROPERTY(idlflags, proptype, name): "Specifies a property of a dispinterface" ! return "DISPPROPERTY", name, idlflags, proptype, ()#, argspec + # COMMETHOD returns: + # restype, methodname, tuple(argtypes), tuple(paramflags), tuple(idlflags), helptext + # + # paramflags is a sequence of (flags (integer), paramname (string) + # tuple(idlflags) is for the method itself: (dispid, 'readonly') + # + # Example: (HRESULT, 'Width', (c_long,), (2, 'rhs'), (4, 'readonly'), None) ## sample generated code: *************** *** 397,403 **** defval = pointer(v) else: ! msg = "'optional' only allowed for VARIANT and VARIANT*, not for %s" \ ! % typ.__name__ ! warnings.warn(msg, IDLWarning, stacklevel=2) defval = typ() paramflags.append((pflags, argname, defval)) --- 433,439 ---- defval = pointer(v) else: ! ## msg = "'optional' only allowed for VARIANT and VARIANT*, not for %s" \ ! ## % typ.__name__ ! ## warnings.warn(msg, IDLWarning, stacklevel=2) defval = typ() paramflags.append((pflags, argname, defval)) *************** *** 475,483 **** except AttributeError: raise TypeError, "unsubscriptable object" ! else: ! try: ! return mth(index + 1) ! except WindowsError, detail: ! raise IndexError, detail ################################################################ --- 511,522 ---- except AttributeError: raise TypeError, "unsubscriptable object" ! try: ! result = mth(index + 1) ! print "__getitem__", bool(result) ! except WindowsError, detail: ! raise IndexError, "invalid index" ! if not result: ! raise IndexError, "invalid index" ! return result ################################################################ |
From: Thomas H. <th...@us...> - 2005-07-06 10:45:57
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21806 Modified Files: Tag: branch_1_0 client.py Log Message: CreateObject is more flexible with the first parameter. wrap() returns NULL COM pointers unchanged. Should it better return None? Index: client.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/Attic/client.py,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** client.py 1 Jul 2005 20:13:20 -0000 1.1.2.1 --- client.py 6 Jul 2005 10:45:22 -0000 1.1.2.2 *************** *** 31,35 **** from comtypes import GUID, CoCreateInstance ! from comtypes import CLSCTX_INPROC_SERVER, CLSCTX_LOCAL_SERVER from comtypes.automation import IDispatch from comtypes.typeinfo import IProvideClassInfo --- 31,35 ---- from comtypes import GUID, CoCreateInstance ! from comtypes import CLSCTX_INPROC_SERVER, CLSCTX_LOCAL_SERVER, CLSCTX_SERVER from comtypes.automation import IDispatch from comtypes.typeinfo import IProvideClassInfo *************** *** 43,48 **** if not os.path.isdir(gen_dir): gen_dir = None ! # for testing ! gen_dir = None def _my_import(fullname): --- 43,48 ---- if not os.path.isdir(gen_dir): gen_dir = None ! ### for testing ! ##gen_dir = None def _my_import(fullname): *************** *** 155,158 **** --- 155,160 ---- interface found. """ + if not punk: # NULL COM pointer + return punk # or should we return None? # find the typelib and the interface name try: *************** *** 193,206 **** def CreateObject(progid, ! clsctx=CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, friendly_name=None): ! """Create a COM object from 'progid', and try to QueryInterface it ! to the most useful interface, generating typelib support on ! demand. In the worst case, an IUnknown pointer is returned. 'clsctx' specifies how to create the object. ! 'friendly_name' allows to specify a readable name for the typelib wrapper. """ ! punk = CoCreateInstance(GUID.from_progid(progid), clsctx=clsctx) return wrap(punk, friendly_name) --- 195,223 ---- def CreateObject(progid, ! clsctx=CLSCTX_SERVER, friendly_name=None): ! """Create a COM object from 'progid', and try to QueryInterface() ! it to the most useful interface, generating typelib support on ! demand. A pointer to this interface is returned. + 'progid' may be a string like "InternetExplorer.Application", + a string specifying a clsid, a GUID instance, or an object with + a _clsid_ attribute. 'clsctx' specifies how to create the object. ! 'friendly_name' allows to specify a readable alias name for the typelib wrapper. """ ! if hasattr(progid, '_clsid_'): ! progid = progid._clsid_ ! ! if isinstance(progid, GUID): ! clsid = progid ! elif isinstance(progid, basestring): ! if progid.startswith("{"): ! clsid = GUID(progid) ! else: ! clsid = GUID.from_progid(progid) ! else: ! raise TypeError, progid ! punk = CoCreateInstance(clsid, clsctx=clsctx) return wrap(punk, friendly_name) |
From: Thomas H. <th...@us...> - 2005-07-06 10:43:06
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20384 Modified Files: Tag: branch_1_0 typedesc.py Log Message: Fix for external symbol which are structures or com interfaces. Index: typedesc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/typedesc.py,v retrieving revision 1.1.2.6 retrieving revision 1.1.2.7 diff -C2 -d -r1.1.2.6 -r1.1.2.7 *** typedesc.py 1 Jul 2005 19:03:05 -0000 1.1.2.6 --- typedesc.py 6 Jul 2005 10:42:54 -0000 1.1.2.7 *************** *** 13,16 **** --- 13,20 ---- self.docs = docs + def get_head(self): + # codegen might call this + return self + class SAFEARRAYType(object): def __init__(self, typ): |
From: Thomas H. <th...@us...> - 2005-07-06 10:41:31
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19525 Modified Files: Tag: branch_1_0 tlbparser.py Log Message: Remove invalid comment. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/tlbparser.py,v retrieving revision 1.4.2.8 retrieving revision 1.4.2.9 diff -C2 -d -r1.4.2.8 -r1.4.2.9 *** tlbparser.py 1 Jul 2005 19:02:19 -0000 1.4.2.8 --- tlbparser.py 6 Jul 2005 10:41:18 -0000 1.4.2.9 *************** *** 296,300 **** flags = fd.lprgelemdescParam[p]._.paramdesc.wParamFlags if flags & typeinfo.PARAMFLAG_FHASDEFAULT: - # XXX should be handled by VARIANT itself var = fd.lprgelemdescParam[p]._.paramdesc.pparamdescex[0].varDefaultValue default = var.value --- 296,299 ---- |
From: Thomas H. <th...@us...> - 2005-07-06 10:40:23
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18815 Modified Files: Tag: branch_1_0 codegenerator.py Log Message: Generate a _disp_methods_ list for dispinterfaces. _methods_ is empty for dispinterfaces. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/codegenerator.py,v retrieving revision 1.6.2.10 retrieving revision 1.6.2.11 diff -C2 -d -r1.6.2.10 -r1.6.2.11 *** codegenerator.py 1 Jul 2005 19:02:20 -0000 1.6.2.10 --- codegenerator.py 6 Jul 2005 10:40:11 -0000 1.6.2.11 *************** *** 221,224 **** --- 221,225 ---- print >> self.stream, " _iid_ = GUID(%r)" % head.itf.iid print >> self.stream, " _idlflags_ = %s" % head.itf.idlflags + print >> self.stream, " _methods_ = []" def DispInterfaceBody(self, body): *************** *** 236,240 **** self.need_dispid() self.need_DISPMETHOD() ! print >> self.stream, "%s._methods_ = [" % body.itf.name for m in body.itf.members: if isinstance(m, typedesc.DispMethod): --- 237,241 ---- self.need_dispid() self.need_DISPMETHOD() ! print >> self.stream, "%s._disp_methods_ = [" % body.itf.name for m in body.itf.members: if isinstance(m, typedesc.DispMethod): |
From: Thomas H. <th...@us...> - 2005-07-06 10:06:49
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3054 Modified Files: Tag: branch_1_0 automation.py Log Message: VARIANT.from_param. Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.12.2.6 retrieving revision 1.12.2.7 diff -C2 -d -r1.12.2.6 -r1.12.2.7 *** automation.py 4 Jul 2005 19:02:26 -0000 1.12.2.6 --- automation.py 6 Jul 2005 10:06:36 -0000 1.12.2.7 *************** *** 146,149 **** --- 146,153 ---- self.value = args[0] + def from_param(cls, value): + return cls(value) + from_param = classmethod(from_param) + # see also c:/sf/pywin32/com/win32com/src/oleargs.cpp 54 def _set_value(self, value): |
From: Thomas H. <th...@us...> - 2005-07-04 19:02:36
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19959 Modified Files: Tag: branch_1_0 automation.py Log Message: A better POINTER(VARIANT).from_param method. More complete IDispatch.Invoke(). Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.12.2.5 retrieving revision 1.12.2.6 diff -C2 -d -r1.12.2.5 -r1.12.2.6 *** automation.py 1 Jul 2005 19:07:05 -0000 1.12.2.5 --- automation.py 4 Jul 2005 19:02:26 -0000 1.12.2.6 *************** *** 272,282 **** comtypes._VARIANT_type_hack = VARIANT ! # A little magic. Override the default .from_param classmethod of ! # POINTER(VARIANT). This allows to pass values which can be stored in ! # VARIANTs as function parameters declared as POINTER(VARIANT). ! # See InternetExplorer's Navigate method, for example. def _from_param(self, arg): if isinstance(arg, POINTER(VARIANT)): return arg return pointer(VARIANT(arg)) POINTER(VARIANT).from_param = classmethod(_from_param) --- 272,288 ---- comtypes._VARIANT_type_hack = VARIANT ! _carg_obj = type(byref(c_int())) ! ! # Override the default .from_param classmethod of POINTER(VARIANT). ! # This allows to pass values which can be stored in VARIANTs as ! # function parameters declared as POINTER(VARIANT). See ! # InternetExplorer's Navigate method, for example. def _from_param(self, arg): + # POINTER(VARIANT)? if isinstance(arg, POINTER(VARIANT)): return arg + # byref(VARIANT)? + if isinstance(arg, _carg_obj) and isinstance(arg._obj, VARIANT): + return arg return pointer(VARIANT(arg)) POINTER(VARIANT).from_param = classmethod(_from_param) *************** *** 398,407 **** _invkind = kw.pop("_invkind", 1) # DISPATCH_METHOD _lcid = kw.pop("_lcid", 0) result = VARIANT() excepinfo = EXCEPINFO() argerr = c_uint() ! ! if _invkind == 1: # method dp = DISPPARAMS() dp.cArgs = len(args) --- 404,415 ---- _invkind = kw.pop("_invkind", 1) # DISPATCH_METHOD _lcid = kw.pop("_lcid", 0) + if kw: + raise ValueError, "named parameters not yet implemented" + result = VARIANT() excepinfo = EXCEPINFO() argerr = c_uint() ! if _invkind == DISPATCH_METHOD: dp = DISPPARAMS() dp.cArgs = len(args) *************** *** 410,421 **** for i, a in enumerate(args): dp.rgvarg[len(args) - i - 1].value = a ! ! elif _invkind == 4: # propput assert len(args) == 1 dp = DISPPARAMS() dp.cArgs = 1 dp.cNamedArgs = 1 ! dp.rgvarg = pointer(VARIANT()) ! dp.rgvarg[0].value = args[0] dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT)) --- 418,435 ---- for i, a in enumerate(args): dp.rgvarg[len(args) - i - 1].value = a ! ! elif _invkind == DISPATCH_PROPERTYGET: ! dp = DISPPARAMS() ! dp.cArgs = len(args) ! dp.cNamedArgs = 0 ! for i, a in enumerate(args): ! dp.rgvarg[len(args) - i - 1].value = a ! ! elif _invkind == DISPATCH_PROPERTYPUT: # propput assert len(args) == 1 dp = DISPPARAMS() dp.cArgs = 1 dp.cNamedArgs = 1 ! dp.rgvarg = pointer(VARIANT(args[0])) dp.rgdispidNamedArgs = pointer(DISPID(DISPID_PROPERTYPUT)) *************** *** 430,433 **** --- 444,449 ---- raise + return result.value + # all the DISP_E_ values from windows.h *************** *** 468,500 **** from comtypes.safearray import SAFEARRAY return POINTER(SAFEARRAY) - - ################################################################ - - if 0 and __name__ == "__main__": - oledll.ole32.CoInitialize(None) - p = POINTER(IDispatch)() - - clsid = GUID.from_progid("InternetExplorer.Application") - # Internet.Explorer - oledll.ole32.CoCreateInstance(byref(clsid), - None, - 7, # CLSCTX - byref(p._iid_), - byref(p)) - for i in range(p.GetTypeInfoCount()): - print p.GetTypeInfo(i) - - id_quit = p.GetIDsOfNames("Quit")[0] - id_visible = p.GetIDsOfNames("Visible")[0] - id_navigate = p.GetIDsOfNames("Navigate2")[0] - print p.GetIDsOfNames("Navigate2", "URL", "Flags", "TargetFrameName", "PostData", "Headers") - - try: - ## p.Invoke(id_visible, True, wFlags = 4) - ## p.Invoke(id_navigate, "http://www.python.org/", 1) - import time - ## time.sleep(3) - print p.Invoke(id_quit) - ## p.Invoke(id_quit, True, wFlags = 1) - finally: - oledll.ole32.CoUninitialize() --- 484,485 ---- |
From: Thomas H. <th...@us...> - 2005-07-01 20:13:31
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30871 Added Files: Tag: branch_1_0 client.py Log Message: The high-level clientside COM module. --- NEW FILE: client.py --- # comtypes.client """high level client level COM support module.""" # Nearly done (just have to doc it in the docstrings): # - provide a way to specify a friendly typelib name in CreateObject # (for py2exe, and for the programmer) # - generate the friendly_name module in comtypes.gen # - generate the friendly_name module even if the unfriendly module # already exists # Must rename make_module and _make_module!!! ################################################################ # # TODO: # # - rename make_module into _make_module, on other words make it private # - rename wrap # # - think about constants in typelib wrappers # # - a GetObject function? # # - make CreateObject also accept a GUID (string and instance?) # # - beautify the code generator output (import statements at the top) # ################################################################ import sys, os, new from ctypes import * from comtypes import GUID, CoCreateInstance from comtypes import CLSCTX_INPROC_SERVER, CLSCTX_LOCAL_SERVER from comtypes.automation import IDispatch from comtypes.typeinfo import IProvideClassInfo import comtypes.gen # determine the place where generated modules live # Fix this to recreate the comtypes\gen\__init__.py file if it was # accidentially deleted! gen_dir = comtypes.gen.__path__[0] if not os.path.isdir(gen_dir): gen_dir = None # for testing gen_dir = None def _my_import(fullname): # helper function to import dotted modules mod = __import__(fullname) for name in fullname.split(".")[1:]: mod = getattr(mod, name) return mod def _name_module(tlib): libattr = tlib.GetLibAttr() modname = "_%s_%s_%s_%s" % \ (str(libattr.guid)[1:-1].replace("-", "_"), libattr.lcid, libattr.wMajorVerNum, libattr.wMinorVerNum) return "comtypes.gen." + modname FORCE = False def make_module(tlib, friendly_name=None): """Create a module wrapping a COM typelibrary on demand. 'tlib' must be an ITypeLib COM pointer instance. 'friendly_name' specifies the directory plus basename of a module importing everything from the typelib wrapper. Determines the module name from the typelib attributes, then tries to import. If that fails, the module is regenerated in the comtypes.gen package. If the comtypes.gen __path__ is not a directory (in a frozen executable it lives in a zip archive), the module is only created in memory. Example: make_module(LoadTypeLibEx("shdocvw.dll"), friendly_name="IE_typelib") would create a module named comtypes.gen._EAB22AC0_30C1_11CF_A7EB_0000C05BAE0B_0_1_1 containing the wrapper code for the type library used by InternetExplorer. The 'comtypes.gen.IE_typelib' module is created as an alias. """ fullname = _name_module(tlib) mod = _make_module(tlib, fullname) if friendly_name is None: return mod try: return _my_import("comtypes.gen." + friendly_name) except: modname = fullname.split(".")[-1] code = "from comtypes.gen import %s\nglobals().update(%s.__dict__)\n" % (modname, modname) if gen_dir is None: mod = new.module("comtypes.gen." + friendly_name) exec code in mod.__dict__ sys.modules[mod.__name__] = mod setattr(comtypes.gen, friendly_name, mod) return mod # create in file system, and import it ofi = open(os.path.join(gen_dir, friendly_name + ".py"), "w") ofi.write(code) ofi.close() return _my_import("comtypes.gen." + friendly_name) def _make_module(tlib, fullname): # helper which creates and imports the real typelib wrapper module. modname = fullname.split(".")[-1] try: mod = _my_import(fullname) except Exception: # We generate the module on ANY error we get. from comtypes.tools.tlbparser import generate_module import time start = time.clock() if gen_dir is None: import cStringIO ofi = cStringIO.StringIO() else: ofi = open(os.path.join(gen_dir, modname + ".py"), "w") # use warnings.warn, maybe? print "# Generating", modname generate_module(tlib, ofi, make_module, _name_module) ## print "# generating took %s seconds" % (time.clock() - start) if gen_dir is None: code = ofi.getvalue() mod = new.module(fullname) exec code in mod.__dict__ sys.modules[fullname] = mod setattr(comtypes.gen, modname, mod) else: ofi.close() mod = _my_import(fullname) reload(mod) return mod else: # first import above succeeded. return mod # XXX rename this! def wrap(punk, friendly_name=None): """Try to QueryInterface a COM pointer to the 'most useful' interface. Get type information for the provided object, either via IDispatch.GetTypeInfo(), or via IProvideClassInfo.GetClassInfo(). Generate a wrapper module for the typelib, and QI for the interface found. """ # find the typelib and the interface name try: pci = punk.QueryInterface(IProvideClassInfo) tinfo = pci.GetClassInfo() # TypeInfo for the CoClass # find the interface marked as default for index in range(tinfo.GetTypeAttr().cImplTypes): if tinfo.GetImplTypeFlags(index) == 1: break else: # should we simply use the first interface now? raise TypeError, "No default interface found" href = tinfo.GetRefTypeOfImplType(index) tinfo = tinfo.GetRefTypeInfo(href) except WindowsError: # XXX we need a COMError! try: pdisp = punk.QueryInterface(IDispatch) # TypeInfo for the interface tinfo = pdisp.GetTypeInfo() except WindowsError: return punk itf_name = tinfo.GetDocumentation(-1)[0] # interface name tlib = tinfo.GetContainingTypeLib()[0] # typelib # import the wrapper, generating it on demand mod = make_module(tlib, friendly_name) # Python interface class interface = getattr(mod, itf_name) # QI for this interface result = punk.QueryInterface(interface) # Hm, this makes the constants in the module (but not only the # constants) available to the returned object. result._constants = mod return result # Should we do this for POINTER(IUnknown) also? POINTER(IDispatch).__ctypes_from_outparam__ = wrap def CreateObject(progid, clsctx=CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, friendly_name=None): """Create a COM object from 'progid', and try to QueryInterface it to the most useful interface, generating typelib support on demand. In the worst case, an IUnknown pointer is returned. 'clsctx' specifies how to create the object. 'friendly_name' allows to specify a readable name for the typelib wrapper. """ punk = CoCreateInstance(GUID.from_progid(progid), clsctx=clsctx) return wrap(punk, friendly_name) ################################################################ # # Hm, don't these belong into comtypes\__init__.py? And, if we derive # this from c_wchar_p, we could even avoid the __ctypes_from_outparm__ # method, because that already returns a unicode string. class TaskMemString(POINTER(c_wchar)): """A zero terminated unicode string, freed by CoTaskMemFree after use. """ # When retrieved from an 'out' parameter, the #__ctypes_from_outparam__ method is called. Return a Python #unicode string, instead of the LP_c_wchar instance itself. # _type_ = c_wchar # the type pointed to def __ctypes_from_outparam__(self): return wstring_at(self) def __del__(self, _free=windll.ole32.CoTaskMemFree): _free(self) # code generation could probably generate commented out code (or not commented out?) # with "magic_replace(POINTER(c_wchar), TaskMemString)" and a comment about that. def magic_replace(old, new, debug=False): """This function is used to replace POINTER types in generated code. It must be called in the module where the replacement should take place, BEFORE the generated code is executed. The ctypes' POINTER symbol must be available before the call, this function replaces the POINTER function with a specialized one in the calling module. from ctypes import * POINTER = magic_replace(POINTER(c_wchar), TaskMemString) After that, POINTER is modified to return POINTER(TaskMemString) whenever POINTER(POINTER(c_wchar)) is called. Uses sys._getframe to change the globals in the calling module. """ frame = sys._getframe(1) POINTER = frame.f_globals["POINTER"] def hack_POINTER(typ): if typ == old: ## if debug: ## print "returns %s instead of %s" % (POINTER(new), POINTER(typ)) return POINTER(new) return POINTER(typ) frame.f_globals["POINTER"] = hack_POINTER return hack_POINTER __all__ = ["CreateObject", "magic_replace", "make_module", "wrap", "TaskMemString"] |
From: Thomas H. <th...@us...> - 2005-07-01 19:09:02
|
Update of /cvsroot/ctypes/ctypes/comtypes/gen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv29140 Added Files: Tag: branch_1_0 .cvsignore Log Message: Ignore generated files. --- NEW FILE: .cvsignore --- _*_0.py _*_1.py _*_2.py _*_3.py _*_4.py _*_5.py _*_6.py _*_7.py _*_8.py _*_9.py *.pyc *.pyo |
From: Thomas H. <th...@us...> - 2005-07-01 19:07:19
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28571 Modified Files: Tag: branch_1_0 automation.py Added Files: Tag: branch_1_0 safearray.py Log Message: Very thin safearray support. Index: automation.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/automation.py,v retrieving revision 1.12.2.4 retrieving revision 1.12.2.5 diff -C2 -d -r1.12.2.4 -r1.12.2.5 *** automation.py 30 Jun 2005 19:16:17 -0000 1.12.2.4 --- automation.py 1 Jul 2005 19:07:05 -0000 1.12.2.5 *************** *** 466,470 **** def _midlSAFEARRAY(aType): ! from comtypes.sa import SAFEARRAY return POINTER(SAFEARRAY) --- 466,470 ---- def _midlSAFEARRAY(aType): ! from comtypes.safearray import SAFEARRAY return POINTER(SAFEARRAY) --- NEW FILE: safearray.py --- # very thin safearray support from ctypes import * from comtypes.typeinfo import SAFEARRAYBOUND from comtypes.automation import VT_I4, VT_R8 class SAFEARRAY(Structure): _fields_ = [("cDims", c_ushort), ("fFeatures", c_ushort), ("cbElements", c_ulong), ("cLocks", c_ulong), ("pvData", c_void_p), ("rgsabound", SAFEARRAYBOUND * 1)] def dump(self): print "cDims", self.cDims print "fFeatures", self.fFeatures print "cLocks", self.cLocks print "cbElements", self.cbElements def __getitem__(self, index): ix = c_int(index) data = c_double() res = windll.oleaut32.SafeArrayGetElement(byref(self), byref(ix), byref(data)) if res: raise WinError(res) return data.value def __iter__(self): ix = c_int() data = c_double() get = windll.oleaut32.SafeArrayGetElement while 1: if get(byref(self), byref(ix), byref(data)): raise StopIteration yield data.value ix.value += 1 if __name__ == "__main__": rgsa = (SAFEARRAYBOUND * 2)() rgsa[0].lLBound = 0 rgsa[0].cElements = 8 rgsa[1].lLBound = 0 rgsa[1].cElements = 5 windll.oleaut32.SafeArrayCreate.restype = POINTER(SAFEARRAY) array = windll.oleaut32.SafeArrayCreate(VT_I4, len(rgsa), rgsa)[0] array.dump() for i, data in enumerate(array): print i, data ##print array[-1] print array[:] |
From: Thomas H. <th...@us...> - 2005-07-01 19:03:15
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25768 Modified Files: Tag: branch_1_0 typedesc.py Log Message: Cleanup a bit. Index: typedesc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/typedesc.py,v retrieving revision 1.1.2.5 retrieving revision 1.1.2.6 diff -C2 -d -r1.1.2.5 -r1.1.2.6 *** typedesc.py 1 Jul 2005 17:12:10 -0000 1.1.2.5 --- typedesc.py 1 Jul 2005 19:03:05 -0000 1.1.2.6 *************** *** 1,3 **** ! # More type descriptions from parsed COM typelibaries. from ctypes.wrap.typedesc import * --- 1,4 ---- ! # More type descriptions from parsed COM typelibaries, extending those ! # in ctypes.wrap.typedesc from ctypes.wrap.typedesc import * *************** *** 107,112 **** def add_interface(self, itf, idlflags): self.interfaces.append((itf, idlflags)) - - if __name__ == "__main__": - import tlbparser - tlbparser.test() --- 108,109 ---- |
From: Thomas H. <th...@us...> - 2005-07-01 19:02:40
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25531 Modified Files: Tag: branch_1_0 tlbparser.py codegenerator.py Log Message: Recursive typelib wrapper generation now works. Index: tlbparser.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/tlbparser.py,v retrieving revision 1.4.2.7 retrieving revision 1.4.2.8 diff -C2 -d -r1.4.2.7 -r1.4.2.8 *** tlbparser.py 30 Jun 2005 20:16:11 -0000 1.4.2.7 --- tlbparser.py 1 Jul 2005 19:02:19 -0000 1.4.2.8 *************** *** 457,475 **** ################################################################ - def _register(self, name, value, tlib=None): - modname = self._typelib_module(tlib) - self.items["%s.%s" % (modname, name)] = value - def _typelib_module(self, tlib=None): if tlib is None: tlib = self.tlib ! la = tlib.GetLibAttr() ! ## return "_%s_%s_%s_%s" % \ ! ## (str(la.guid)[1:-1].replace("-", "_"), ! ## la.lcid, la.wMajorVerNum, la.wMinorVerNum) ! # this string doesn't have any meaning outside (except when filtering ! # in the codegenerator by names - which we don't do for COM typelibs), ! # so it does not have to be the same as the module name. ! return "%s%s%s%s" % (la.guid, la.lcid, la.wMajorVerNum, la.wMinorVerNum) def parse_typeinfo(self, tinfo): --- 457,470 ---- ################################################################ def _typelib_module(self, tlib=None): if tlib is None: tlib = self.tlib ! # return a string that uniquely identifies a typelib. ! # The string doesn't have any meaning outside this instance. ! return str(tlib.GetLibAttr()) ! ! def _register(self, name, value, tlib=None): ! modname = self._typelib_module(tlib) ! self.items["%s.%s" % (modname, name)] = value def parse_typeinfo(self, tinfo): *************** *** 484,488 **** if tlib != self.tlib: typ = typedesc.External(tlib, - ## self._typelib_module(tlib), name, tlib.GetDocumentation(-1)[:2]) --- 479,482 ---- *************** *** 607,611 **** gen.generate_code(items.values()) ! def generate_module(tlib, ofi, make_module): known_symbols = {} for name in ("comtypes.typeinfo", "comtypes.automation", "comtypes", "ctypes"): --- 601,605 ---- gen.generate_code(items.values()) ! def generate_module(tlib, ofi, make_module, name_module): known_symbols = {} for name in ("comtypes.typeinfo", "comtypes.automation", "comtypes", "ctypes"): *************** *** 623,626 **** --- 617,621 ---- gen = Generator(ofi, make_module = make_module, + name_module = name_module, use_decorators=sys.version_info >= (2, 4), known_symbols=known_symbols, Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/codegenerator.py,v retrieving revision 1.6.2.9 retrieving revision 1.6.2.10 diff -C2 -d -r1.6.2.9 -r1.6.2.10 *** codegenerator.py 1 Jul 2005 17:12:10 -0000 1.6.2.9 --- codegenerator.py 1 Jul 2005 19:02:20 -0000 1.6.2.10 *************** *** 2,6 **** # contained in COM type libraries. ! import typedesc import ctypes.wrap.codegenerator --- 2,6 ---- # contained in COM type libraries. ! from comtypes.tools import typedesc import ctypes.wrap.codegenerator *************** *** 14,18 **** class Generator(ctypes.wrap.codegenerator.Generator): ! def __init__(self, ofi, make_module=None, *args, **kw): self._make_module = make_module self._externals = {} --- 14,19 ---- class Generator(ctypes.wrap.codegenerator.Generator): ! def __init__(self, ofi, make_module=None, name_module=None, *args, **kw): ! self._name_module = name_module self._make_module = make_module self._externals = {} *************** *** 60,91 **** # def External(self, ext): ! ## # ext.module - the module name ! # ext.docs - docstring of the type library ! # ext.name - the full name of the type (including module name) ! # ext.tlib - the ITypeLib pointer # ! # XXX ext.name is used by self.type_name()! ! if ext.tlib in self._externals: ! modname = self._externals[ext.tlib] ext.name = "%s.%s" % (modname, ext.symbol_name) return - if self._make_module: - # make_module will create (if needed), then import the - # module and return it. - libattr = ext.tlib.GetLibAttr() - print "NEED to generate module", libattr - result = self._make_module(ext.tlib) - ext.module = result.__name__ - ext.name = "%s.%s" % (ext.module, ext.symbol_name) - # 1. get the module name - # 2. register is in _externals - # 3. generate the module ! else: ! raise "CANNOT GENERATE NEEDED TYPELIB" ! ## if ext.docs: ! ## print >> self.imports, "# '%s' typelib (%s)" % ext.docs ! print >> self.imports, "import %s" % ext.module ! self._externals[ext.tlib] = ext.module def SAFEARRAYType(self, sa): --- 61,97 ---- # def External(self, ext): ! # ext.docs - docstring of typelib ! # ext.symbol_name - symbol to generate ! # ext.tlib - the ITypeLib pointer to the typelibrary containing the symbols definition # ! # ext.name filled in here ! ! # XXX This code should be refactored to NOT require that ! # _make_module and _name_module must be set on the Generator ! # instance. Should we pass a ModuleGenerator instance instead, ! # with make_module and name_module methods? ! ! # Or, are there other ways? ! ! libdesc = str(ext.tlib.GetLibAttr()) # str(TLIBATTR) is unique for a given typelib ! if libdesc in self._externals: # typelib wrapper already created ! modname = self._externals[libdesc] ! # we must fill in ext.name, it is used by self.type_name() ext.name = "%s.%s" % (modname, ext.symbol_name) return ! if self._name_module is None: ! ext.name = ext.symbol_name ! print "# Cannot create external symbol", ext.symbol_name ! return ! ! modname = self._name_module(ext.tlib) ! ext.name = "%s.%s" % (modname, ext.symbol_name) ! self._externals[libdesc] = modname ! print >> self.imports, "import", modname ! # it may be already generated in another instance of ! # Generator, but _make_module will catch this. ! if self._make_module is not None: ! self._make_module(ext.tlib) def SAFEARRAYType(self, sa): |
From: Thomas H. <th...@us...> - 2005-07-01 18:53:56
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21265 Modified Files: Tag: branch_1_0 __init__.py Log Message: Remove __hash__ again - it doesn't work. We would have to QI to IUnknown first... Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.11 retrieving revision 1.25.2.12 diff -C2 -d -r1.25.2.11 -r1.25.2.12 *** __init__.py 1 Jul 2005 17:08:22 -0000 1.25.2.11 --- __init__.py 1 Jul 2005 18:53:47 -0000 1.25.2.12 *************** *** 266,275 **** return cmp(super(_compointer_base, self).value, super(_compointer_base, other).value) - def __hash__(self): - # XXX Since ctypes instances are mutable, it is dangerous to define this! - # So, we should remember not to change them anymore after they are hashed. - ptr = super(_compointer_base, self).value - return hash(ptr) - # override the .value property of c_void_p # --- 266,269 ---- |
From: Thomas H. <th...@us...> - 2005-07-01 17:12:19
|
Update of /cvsroot/ctypes/ctypes/comtypes/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28718 Modified Files: Tag: branch_1_0 typedesc.py codegenerator.py Log Message: Recursive typelib wrapper generation does not yet work. On the way to fix it. Index: codegenerator.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/codegenerator.py,v retrieving revision 1.6.2.8 retrieving revision 1.6.2.9 diff -C2 -d -r1.6.2.8 -r1.6.2.9 *** codegenerator.py 30 Jun 2005 20:16:11 -0000 1.6.2.8 --- codegenerator.py 1 Jul 2005 17:12:10 -0000 1.6.2.9 *************** *** 63,77 **** # ext.docs - docstring of the type library # ext.name - the full name of the type (including module name) # # XXX ext.name is used by self.type_name()! ! if ext in self._externals: return if self._make_module: ! # make_module will create if needed then import the module ! # and return it. ! print "NEED to generate module", ext result = self._make_module(ext.tlib) ext.module = result.__name__ ! ext.name = "%s.%s" % (ext.module, ext.name) else: raise "CANNOT GENERATE NEEDED TYPELIB" --- 63,85 ---- # ext.docs - docstring of the type library # ext.name - the full name of the type (including module name) + # ext.tlib - the ITypeLib pointer # # XXX ext.name is used by self.type_name()! ! if ext.tlib in self._externals: ! modname = self._externals[ext.tlib] ! ext.name = "%s.%s" % (modname, ext.symbol_name) return if self._make_module: ! # make_module will create (if needed), then import the ! # module and return it. ! libattr = ext.tlib.GetLibAttr() ! print "NEED to generate module", libattr result = self._make_module(ext.tlib) ext.module = result.__name__ ! ext.name = "%s.%s" % (ext.module, ext.symbol_name) ! # 1. get the module name ! # 2. register is in _externals ! # 3. generate the module ! else: raise "CANNOT GENERATE NEEDED TYPELIB" *************** *** 79,84 **** ## print >> self.imports, "# '%s' typelib (%s)" % ext.docs print >> self.imports, "import %s" % ext.module ! ## self._externals[ext.module] = None ! self._externals[ext] = None def SAFEARRAYType(self, sa): --- 87,91 ---- ## print >> self.imports, "# '%s' typelib (%s)" % ext.docs print >> self.imports, "import %s" % ext.module ! self._externals[ext.tlib] = ext.module def SAFEARRAYType(self, sa): Index: typedesc.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/tools/typedesc.py,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** typedesc.py 30 Jun 2005 20:16:11 -0000 1.1.2.4 --- typedesc.py 1 Jul 2005 17:12:10 -0000 1.1.2.5 *************** *** 8,12 **** self.tlib = tlib # name of symbol ! self.name = name # type lib description self.docs = docs --- 8,12 ---- self.tlib = tlib # name of symbol ! self.symbol_name = name # type lib description self.docs = docs |
From: Thomas H. <th...@us...> - 2005-07-01 17:08:35
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26734 Modified Files: Tag: branch_1_0 __init__.py Log Message: Cleanup, and make COM interface pointers hashable (dangerous). Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.10 retrieving revision 1.25.2.11 diff -C2 -d -r1.25.2.10 -r1.25.2.11 *** __init__.py 1 Jul 2005 08:04:47 -0000 1.25.2.10 --- __init__.py 1 Jul 2005 17:08:22 -0000 1.25.2.11 *************** *** 2,15 **** import new import warnings - - class IDLWarning(UserWarning): - pass - try: set except NameError: from sets import Set as set - from ctypes import * from comtypes.GUID import GUID _GUID = GUID --- 2,14 ---- import new import warnings try: set except NameError: from sets import Set as set from ctypes import * + + class IDLWarning(UserWarning): + "Warn about questionable type information" + from comtypes.GUID import GUID _GUID = GUID *************** *** 18,28 **** ################################################################ CLSCTX_INPROC_SERVER = 1 CLSCTX_INPROC_HANDLER = 2 CLSCTX_LOCAL_SERVER = 4 ! CLSCTX_INPROC = 3 # Variable c_int ! CLSCTX_SERVER = 5 # Variable c_int ! CLSCTX_ALL = 7 # Variable c_int CLSCTX_INPROC_SERVER16 = 8 --- 17,28 ---- ################################################################ + # constants for object creation CLSCTX_INPROC_SERVER = 1 CLSCTX_INPROC_HANDLER = 2 CLSCTX_LOCAL_SERVER = 4 ! CLSCTX_INPROC = 3 ! CLSCTX_SERVER = 5 ! CLSCTX_ALL = 7 CLSCTX_INPROC_SERVER16 = 8 *************** *** 46,56 **** ################################################################ ! ole32 = oledll.ole32 ! # Still experimenting with COM shutdown without crashes... ! ole32.CoInitialize(None) class _Cleaner(object): ! def __del__(self, func=ole32.CoUninitialize): # Sometimes, CoUnititialize, running at Python shutdown, raises an exception. # We suppress this when __debug__ is False. --- 46,56 ---- ################################################################ ! # Initialization and shutdown ! _ole32 = oledll.ole32 ! _ole32.CoInitialize(None) class _Cleaner(object): ! def __del__(self, func=_ole32.CoUninitialize): # Sometimes, CoUnititialize, running at Python shutdown, raises an exception. # We suppress this when __debug__ is False. *************** *** 266,269 **** --- 266,275 ---- return cmp(super(_compointer_base, self).value, super(_compointer_base, other).value) + def __hash__(self): + # XXX Since ctypes instances are mutable, it is dangerous to define this! + # So, we should remember not to change them anymore after they are hashed. + ptr = super(_compointer_base, self).value + return hash(ptr) + # override the .value property of c_void_p # *************** *** 295,306 **** --- 301,315 ---- class helpstring(object): + "Specifies the helpstring for a COM method or property." def __init__(self, text): self.text = text class defaultvalue(object): + "Specifies the default value for parameters marked optional." def __init__(self, value): self.value = value class dispid(int): + "Specifies the DISPID of a method or property." pass *************** *** 311,318 **** --- 320,329 ---- def DISPMETHOD(idlflags, restype, name, *argspec): + "Specifies a method of a dispinterface" # XXX WRONG WRONG WRONG return COMMETHOD(idlflags, restype, name, *argspec) def DISPPROPERTY(idlflags, proptype, name): + "Specifies a property of a dispinterface" # XXX WRONG WRONG WRONG #? return COMMETHOD(idlflags, HRESULT, name, ([], proptype, 'rhs') ) *************** *** 329,333 **** ################################################################ ! PARAMFLAGS = { "in": 1, "out": 2, --- 340,344 ---- ################################################################ ! _PARAMFLAGS = { "in": 1, "out": 2, *************** *** 337,343 **** } ! def encode_idl(names): ! # sum up all values found in PARAMFLAGS, ignoring all others. ! result = sum([PARAMFLAGS.get(n, 0) for n in names]) return result & 3 # that's what _ctypes accept --- 348,354 ---- } ! def _encode_idl(names): ! # sum up all values found in _PARAMFLAGS, ignoring all others. ! result = sum([_PARAMFLAGS.get(n, 0) for n in names]) return result & 3 # that's what _ctypes accept *************** *** 350,354 **** def COMMETHOD(idlflags, restype, methodname, *argspec): ! "Specifies a COM method slot with idlflags" paramflags = [] argtypes = [] --- 361,368 ---- def COMMETHOD(idlflags, restype, methodname, *argspec): ! """Specifies a COM method slot with idlflags. ! ! XXX more ! """ paramflags = [] argtypes = [] *************** *** 359,457 **** helptext = "".join(helptext) or None - # XXX some thoughts: - # - # In _ctypes.c::_get_one(), it is difficult to decide what to do. - # - # The _get_one() function is called for each [out] parameter, with - # an instance of a ctypes type. The argument 'type' we have in - # paramflags is actually a POINTER to this type. - # - # What are the possibilities, what are the problems? - # - # 1. Simple, intergral, non-pointer data type: call the type's - # stgdict->getfunc() to build the result. stgdict->proto in this - # case is a one character Python string containing the type tag - # from the formattable. - # Sample: - # def Get(self): - # temp = c_int() - # self.__com_Get(byref(temp)) - # return temp.value - # - # 1a. Same as before, but an instance that owns some resources, - # like BSTR. We have to call SysFreeString() to free the resources. - # Sample: - # def Get(self): - # temp = BSTR() - # self.__com_Get(byref(temp)) - # temp2 = temp.value - # temp._free_resources_() - # return temp2 - # - # 1b. A structure, like VARIANT, that actually represents an - # integral data type. Again, we should return it's .value - # attribute, and, as in 1a, we have to call VariantClear() to free - # resources. Sample code same as in 1a. - # - # 2. POINTER to cominterface: In this case we would like _get_one() - # to return the result itself. - # Sample: - # def Get(self): - # temp = POINTER(IUnknown)() - # self.__com_Get(byref(temp)) - # return temp - # - # Exactly here in the code is at least ONE place where all this - # info is available, and we can execute arbitrary complicated - # Python code much easier than in C. - # - # We could pass simple info (in form of integer flags) to - # _ctypes.c in the paramflags tuple (there are a lots of bits - # unused in the PARAMFLAGS enum), but complicated stuff would also - # be possible. - # - # Another possibility would be to have this info in the types itself. - # Something like _from_outarg_. - # - - # What about coclass* in the parameter list? According to MSDN, - # this means the same as IUnknown*. - # So, it seems we should QueryInterface the received pointer - # for a 'better' interface, maybe the coclass' default interface? - # - # Several problems to solve: - # - How to preserve the type information in the generated code? - # - # The coclass could have the default interface as base class. - # - # The code generation could insert in entry into the - # _pointer_type_cache, so that - # POINTER(<coclass>) == <default_interface> - # - # The generated code could look like this (in STDMETHOD): - # ..., POINTER(<coclass>._com_interfaces_[0] - # - # Best would be if we could insert something that - # would allow the get_one() function to call specialized - # code that would QI for the default interface, and still - # contains the coclass itself. - - # Hm. This: - # - # class App(coclass): - # _ctype_ = IDefaultInterface - # @classmethod - # def from_param(self, parm): - # ... - # def from_outparm(self, value): - # # value is an instance of self._ctype_ - # ... - # - # All this needs to be specified very carefully. And I should - # collect links to ctypes-users posts where this was discussed. - for item in argspec: idl, typ, argname, defval = _unpack_argspec(*item) ! pflags = encode_idl(idl) if "optional" in idl: if defval is _NOTHING: --- 373,379 ---- helptext = "".join(helptext) or None for item in argspec: idl, typ, argname, defval = _unpack_argspec(*item) ! pflags = _encode_idl(idl) if "optional" in idl: if defval is _NOTHING: *************** *** 499,502 **** --- 421,435 ---- class IUnknown(object): + """The most basic COM interface. + + Each subclasses of IUnknown must define these class attributes: + + _iid_ - a GUID instance defining the identifier of this interface + + _methods_ - a list of methods for this interface. + + The _methods_ list must in VTable order. Methods are specified + with STDMETHOD or COMMETHOD calls. + """ __metaclass__ = _cominterface_meta _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") *************** *** 556,563 **** ################################################################ - ##@stdcall(HRESULT, 'ole32', - ## [POINTER(IID), POINTER(IUnknown), c_ulong, - ## POINTER(IID), POINTER(c_void_p)]) def CoCreateInstance(clsid, interface=IUnknown, clsctx=CLSCTX_ALL, punkouter=None): p = POINTER(interface)() iid = interface._iid_ --- 489,496 ---- ################################################################ def CoCreateInstance(clsid, interface=IUnknown, clsctx=CLSCTX_ALL, punkouter=None): + """The basic windows api to create a COM class object and return a + pointer to an interface. + """ p = POINTER(interface)() iid = interface._iid_ *************** *** 596,598 **** ## ] ! __all__ = ["CoClass", "IUnknown", "GUID", "HRESULT", "BSTR", "STDMETHOD"] --- 529,531 ---- ## ] ! ##__all__ = ["CoClass", "IUnknown", "GUID", "HRESULT", "BSTR", "STDMETHOD", "COMMETHOD"] |
From: Thomas H. <th...@us...> - 2005-07-01 15:11:23
|
Update of /cvsroot/ctypes/ctypes/comtypes/gen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26375 Added Files: Tag: branch_1_0 __init__.py Log Message: comtypes.gen package containing generated typelib wrappers. --- NEW FILE: __init__.py --- # comtypes.gen package, directory for generated files. |
From: Thomas H. <th...@us...> - 2005-07-01 15:10:07
|
Update of /cvsroot/ctypes/ctypes/comtypes/gen In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25413/gen Log Message: Directory /cvsroot/ctypes/ctypes/comtypes/gen added to the repository --> Using per-directory sticky tag `branch_1_0' |
From: Thomas H. <th...@us...> - 2005-07-01 13:27:12
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2698 Modified Files: Tag: branch_1_0 GUID.py Log Message: Don't import ctypes.wintypes. Index: GUID.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/GUID.py,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -C2 -d -r1.6 -r1.6.2.1 *** GUID.py 16 Mar 2005 07:23:16 -0000 1.6 --- GUID.py 1 Jul 2005 13:26:56 -0000 1.6.2.1 *************** *** 1,4 **** from ctypes import * ! from ctypes.wintypes import DWORD, WORD, BYTE _ole32 = oledll.ole32 --- 1,7 ---- from ctypes import * ! ! BYTE = c_byte ! WORD = c_ushort ! DWORD = c_ulong _ole32 = oledll.ole32 |
From: Thomas H. <th...@us...> - 2005-07-01 08:30:07
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11416 Modified Files: Tag: branch_1_0 .cvsignore Log Message: Ignore build and dist directories. Index: .cvsignore =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/.cvsignore,v retrieving revision 1.1 retrieving revision 1.1.4.1 diff -C2 -d -r1.1 -r1.1.4.1 *** .cvsignore 27 Aug 2004 19:30:01 -0000 1.1 --- .cvsignore 1 Jul 2005 08:29:59 -0000 1.1.4.1 *************** *** 1,2 **** - *.pyo *.pyc --- 1,4 ---- *.pyc + *.pyo + build + dist |
From: Thomas H. <th...@us...> - 2005-07-01 08:05:02
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv881 Modified Files: Tag: branch_1_0 __init__.py Added Files: Tag: branch_1_0 _meta.py Log Message: CoClass is ready. Metaclass magic is in a separate file. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.25.2.9 retrieving revision 1.25.2.10 diff -C2 -d -r1.25.2.9 -r1.25.2.10 *** __init__.py 30 Jun 2005 19:09:37 -0000 1.25.2.9 --- __init__.py 1 Jul 2005 08:04:47 -0000 1.25.2.10 *************** *** 346,350 **** return idl, typ, name, defval ! # will be overwritten when comtypes.automation is imported. _VARIANT_type_hack = None --- 346,350 ---- return idl, typ, name, defval ! # will be overwritten with VARIANT when comtypes.automation is imported. _VARIANT_type_hack = None *************** *** 569,597 **** ################################################################ # What's a coclass? # a POINTER to a coclass is allowed as parameter in a function declaration: # http://msdn.microsoft.com/library/en-us/midl/midl/oleautomation.asp ! ! ################ ! class CoClass(c_void_p): ! "pass" ! ! # The code generation assigns a __ctypes_from_outparam__ to each ! # POINTER(<coclass>) when the <coclass> is generated. Maybe we could ! # avoid having c_void_p as baseclass in CoClass, generate the ! # __ctypes_from_outparam__ method in a metaclass, and also have the ! # metaclass mix in the c_void_p (or whatever) into the POINTER(...) ! # type? See the IUnknown magic... ! ! # creation, and so on ! ! ## def create_instance(self): ! ## p = POINTER(self._com_interfaces_[0])() ! ## oledll.ole32.CoCreateInstance(byref(self._clsid_), ! ## None, ! ## 7, # CLSCTX ! ## byref(p._iid_), ! ## byref(p)) ! ## return p ################ --- 569,578 ---- ################################################################ + from comtypes._meta import _coclass_meta # What's a coclass? # a POINTER to a coclass is allowed as parameter in a function declaration: # http://msdn.microsoft.com/library/en-us/midl/midl/oleautomation.asp ! class CoClass(object): ! __metaclass__ = _coclass_meta ################ --- NEW FILE: _meta.py --- # comtypes._meta helper module from ctypes import POINTER, c_void_p, cast ################################################################ # metaclass for CoClass (in comtypes/__init__.py) def _wrap_coclass(self): # We are an IUnknown pointer, represented as a c_void_p instance, # but we really want this interface: itf = self._com_interfaces_[0] punk = cast(self, POINTER(itf)) return punk.QueryInterface(itf) # # The mro() of a POINTER(App) type, where class App is a subclass of CoClass: # # POINTER(App) # App # CoClass # c_void_p # _SimpleCData # _CData # object class _coclass_meta(type): # metaclass for CoClass # # If a CoClass subclass is created, create a POINTER(...) type for # that class, with bases <coclass> and c_void_p. Also, the # POINTER(...) type gets a __ctypes_from_outparam__ method which # will QueryInterface for the default interface: the first one on # the coclass' _com_interfaces_ list. def __new__(self, name, bases, namespace): cls = type.__new__(self, name, bases, namespace) if bases == (object,): return cls PTR = _coclass_pointer_meta("POINTER(%s)" % cls.__name__, (cls, c_void_p), {"__ctypes_from_outparam__": _wrap_coclass}) from ctypes import _pointer_type_cache _pointer_type_cache[cls] = PTR return cls # will not work if we change the order of the two base classes! class _coclass_pointer_meta(type(c_void_p), _coclass_meta): pass |