def getevents(clsid): """Determine the default outgoing interface for a class, given either a clsid or progid. It returns a class - you can conveniently derive your own handler from this class and implement the appropriate methods. This method relies on the classes produced by makepy. You must use either makepy or the gencache module to ensure that the appropriate support classes have been generated for the com server that you will be handling events from. Beware of COM circular references. When the Events class is connected to the COM object, the COM object itself keeps a reference to the Python events class. Thus, neither the Events instance or the COM object will ever die by themselves. The 'close' method on the events instance must be called to break this chain and allow standard Python collection rules to manage object lifetimes. Note that DispatchWithEvents() does work around this problem by the use of a proxy object, but if you use the getevents() function yourself, you must make your own arrangements to manage this circular reference issue. Beware of creating Python circular references: this will happen if your handler has a reference to an object that has a reference back to the event source. Call the 'close' method to break the chain. Example: >>>win32com.client.gencache.EnsureModule('{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}',0,1,1) <module 'win32com.gen_py..... >>> >>> class InternetExplorerEvents(win32com.client.getevents("InternetExplorer.Application.1")): ... def OnVisible(self, Visible): ... print "Visibility changed: ", Visible ... >>> >>> ie=win32com.client.Dispatch("InternetExplorer.Application.1") >>> events=InternetExplorerEvents(ie) >>> ie.Visible=1 Visibility changed: 1 >>> """ # find clsid given progid or clsid clsid = str(pywintypes.IID(clsid)) # return default outgoing interface for that class klass = gencache.GetClassForCLSID(clsid) try: return klass.default_source except AttributeError: # See if we have a coclass for the interfaces. try: return gencache.GetClassForCLSID( klass.coclass_clsid).default_source except AttributeError: return None
def __WrapDispatch(dispatch, userName = None, resultCLSID = None, typeinfo = None, \ UnicodeToString = NeedUnicodeConversions, clsctx = pythoncom.CLSCTX_SERVER, WrapperClass = None): """ Helper function to return a makepy generated class for a CLSID if it exists, otherwise cope by using CDispatch. """ if resultCLSID is None: try: typeinfo = dispatch.GetTypeInfo() if typeinfo is not None: # Some objects return NULL, some raise exceptions... resultCLSID = str(typeinfo.GetTypeAttr()[0]) except (pythoncom.com_error, AttributeError): pass if resultCLSID is not None: import gencache # Attempt to load generated module support # This may load the module, and make it available klass = gencache.GetClassForCLSID(resultCLSID) if klass is not None: return klass(dispatch) # Return a "dynamic" object - best we can do! if WrapperClass is None: WrapperClass = CDispatch return dynamic.Dispatch(dispatch, userName, WrapperClass, typeinfo, UnicodeToString=UnicodeToString, clsctx=clsctx)