def Record(name, object): """Creates a new record object, given the name of the record, and an object from the same type library. Example usage would be: app = win32com.client.Dispatch("Some.Application") point = win32com.client.Record("SomeAppPoint", app) point.x = 0 point.y = 0 app.MoveTo(point) """ # XXX - to do - probably should allow "object" to already be a module object. import gencache object = gencache.EnsureDispatch(object) module = sys.modules[object.__class__.__module__] # to allow us to work correctly with "demand generated" code, # we must use the typelib CLSID to obtain the module # (otherwise we get the sub-module for the object, which # does not hold the records) # thus, package may be module, or may be module's parent if demand generated. package = gencache.GetModuleForTypelib(module.CLSID, module.LCID, module.MajorVersion, module.MinorVersion) try: struct_guid = package.RecordMap[name] except KeyError: raise ValueError, "The structure '%s' is not defined in module '%s'" % ( name, package) return pythoncom.GetRecordFromGuids(module.CLSID, module.MajorVersion, module.MinorVersion, module.LCID, struct_guid)
def CastTo(ob, target): """'Cast' a COM object to another interface""" # todo - should support target being an IID if hasattr(target, "index"): # string like # for now, we assume makepy for this to work. if not ob.__class__.__dict__.has_key("CLSID"): # Eeek - no makepy support - try and build it. ob = gencache.EnsureDispatch(ob) if not ob.__class__.__dict__.has_key("CLSID"): raise ValueError, "Must be a makepy-able object for this to work" clsid = ob.CLSID # Lots of hoops to support "demand-build" - ie, generating # code for an interface first time it is used. We assume the # interface name exists in the same library as the object. # This is generally the case - only referenced typelibs may be # a problem, and we can handle that later. Maybe <wink> # So get the generated module for the library itself, then # find the interface CLSID there. mod = gencache.GetModuleForCLSID(clsid) # Get the 'root' module. mod = gencache.GetModuleForTypelib(mod.CLSID, mod.LCID, mod.MajorVersion, mod.MinorVersion) # Find the CLSID of the target target_clsid = mod.NamesToIIDMap.get(target) if target_clsid is None: raise ValueError, "The interface name '%s' does not appear in the " \ "same library as object '%r'" % (target, ob) mod = gencache.GetModuleForCLSID(target_clsid) target_class = getattr(mod, target) # resolve coclass to interface target_class = getattr(target_class, "default_interface", target_class) return target_class(ob) # auto QI magic happens raise ValueError, "This object can not be cast"