def WithEvents(disp, user_event_class): """Similar to DispatchWithEvents - except that the returned object is *not* also usable as the original Dispatch object - that is the returned object is not dispatchable. The difference is best summarised by example. >>> class IEEvents: ... def OnVisible(self, visible): ... print "Visible changed:", visible ... >>> ie = Dispatch("InternetExplorer.Application") >>> ie_events = WithEvents(ie, IEEvents) >>> ie.Visible = 1 Visible changed: 1 Compare with the code sample for DispatchWithEvents, where you get a single object that is both the interface and the event handler. Note that the event handler instance will *not* be able to use 'self.' to refer to IE's methods and properties. This is mainly useful where using DispatchWithEvents causes circular reference problems that the simple proxy doesn't deal with """ disp = Dispatch(disp) # Eeek - no makepy support - try and build it. if not disp.__class__.__dict__.get("CLSID"): try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] tlb, index = ti.GetContainingTypeLib() tla = tlb.GetLibAttr() gencache.EnsureModule( tla[0], tla[1], tla[3], tla[4], bValidateFile=0) # Get the class from the module. disp_class = gencache.GetClassForProgID(str(disp_clsid)) except pythoncom.com_error: raise TypeError( "This COM object can not automate the makepy process - please run makepy manually for this object" ) else: disp_class = disp.__class__ # Get the clsid clsid = disp_class.CLSID # Create a new class that derives from 2 classes - the event sink # class and the user class. try: from types import ClassType as new_type except ImportError: new_type = type # py3k events_class = getevents(clsid) if events_class is None: raise ValueError("This COM object does not support events.") result_class = new_type("COMEventClass", (events_class, user_event_class), {}) # This only calls the first base class __init__. instance = result_class(disp) if hasattr(user_event_class, "__init__"): user_event_class.__init__(instance) return instance
def WithEvents(disp, user_event_class): """Similar to DispatchWithEvents - except that the returned object is *not* also usable as the original Dispatch object - that is the returned object is not dispatchable. The difference is best summarised by example. >>> class IEEvents: ... def OnVisible(self, visible): ... print "Visible changed:", visible ... >>> ie = Dispatch("InternetExplorer.Application") >>> ie_events = WithEvents(ie, IEEvents) >>> ie.Visible = 1 Visible changed: 1 Compare with the code sample for DispatchWithEvents, where you get a single object that is both the interface and the event handler. Note that the event handler instance will *not* be able to use 'self.' to refer to IE's methods and properties. This is mainly useful where using DispatchWithEvents causes circular reference problems that the simple proxy doesn't deal with """ disp = Dispatch(disp) if not disp.__class__.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it. try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] tlb, index = ti.GetContainingTypeLib() tla = tlb.GetLibAttr() gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) # Get the class from the module. disp_class = gencache.GetClassForProgID(str(disp_clsid)) except pythoncom.com_error: raise TypeError( "This COM object can not automate the makepy process - please run makepy manually for this object" ) else: disp_class = disp.__class__ # Get the clsid clsid = disp_class.CLSID # Create a new class that derives from 2 classes - the event sink # class and the user class. try: from types import ClassType as new_type except ImportError: new_type = type # py3k events_class = getevents(clsid) if events_class is None: raise ValueError("This COM object does not support events.") result_class = new_type("COMEventClass", (events_class, user_event_class), {}) instance = result_class(disp) # This only calls the first base class __init__. if hasattr(user_event_class, "__init__"): user_event_class.__init__(instance) return instance
def MakeControlClass(controlClass, name=None): """Given a CoClass in a generated .py file, this function will return a Class object which can be used as an OCX control. This function is used when you do not want to handle any events from the OCX control. If you need events, then you should derive a class from both the activex.Control class and the CoClass """ if name is None: name = controlClass.__name__ return new_type("OCX" + name, (Control, controlClass), {})
def MakeControlClass( controlClass, name = None ): """Given a CoClass in a generated .py file, this function will return a Class object which can be used as an OCX control. This function is used when you do not want to handle any events from the OCX control. If you need events, then you should derive a class from both the activex.Control class and the CoClass """ if name is None: name = controlClass.__name__ return new_type("OCX" + name, (Control, controlClass), {})
def DispatchWithEvents(clsid, user_event_class): """Create a COM object that can fire events to a user defined class. clsid -- The ProgID or CLSID of the object to create. user_event_class -- A Python class object that responds to the events. This requires makepy support for the COM object being created. If this support does not exist it will be automatically generated by this function. If the object does not support makepy, a TypeError exception will be raised. The result is a class instance that both represents the COM object and handles events from the COM object. It is important to note that the returned instance is not a direct instance of the user_event_class, but an instance of a temporary class object that derives from three classes: * The makepy generated class for the COM object * The makepy generated class for the COM events * The user_event_class as passed to this function. If this is not suitable, see the getevents function for an alternative technique of handling events. Object Lifetimes: Whenever the object returned from this function is cleaned-up by Python, the events will be disconnected from the COM object. This is almost always what should happen, but see the documentation for getevents() for more details. Example: >>> class IEEvents: ... def OnVisible(self, visible): ... print "Visible changed:", visible ... >>> ie = DispatchWithEvents("InternetExplorer.Application", IEEvents) >>> ie.Visible = 1 Visible changed: 1 >>> """ # Create/Get the object. disp = Dispatch(clsid) # Eeek - no makepy support - try and build it. if not disp.__class__.__dict__.get("CLSID"): try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] tlb, index = ti.GetContainingTypeLib() tla = tlb.GetLibAttr() gencache.EnsureModule( tla[0], tla[1], tla[3], tla[4], bValidateFile=0) # Get the class from the module. disp_class = gencache.GetClassForProgID(str(disp_clsid)) except pythoncom.com_error: raise TypeError( "This COM object can not automate the makepy process - please run makepy manually for this object" ) else: disp_class = disp.__class__ # If the clsid was an object, get the clsid clsid = disp_class.CLSID # Create a new class that derives from 3 classes - the dispatch class, the event sink class and the user class. # XXX - we are still "classic style" classes in py2x, so we need can't yet # use 'type()' everywhere - revisit soon, as py2x will move to new-style # too... try: from types import ClassType as new_type except ImportError: new_type = type # py3k events_class = getevents(clsid) if events_class is None: raise ValueError("This COM object does not support events.") result_class = new_type("COMEventClass", (disp_class, events_class, user_event_class), {"__setattr__": _event_setattr_}) # This only calls the first base class __init__. instance = result_class(disp._oleobj_) events_class.__init__(instance, instance) if hasattr(user_event_class, "__init__"): user_event_class.__init__(instance) return EventsProxy(instance)
def DispatchWithEvents(clsid, user_event_class): """Create a COM object that can fire events to a user defined class. clsid -- The ProgID or CLSID of the object to create. user_event_class -- A Python class object that responds to the events. This requires makepy support for the COM object being created. If this support does not exist it will be automatically generated by this function. If the object does not support makepy, a TypeError exception will be raised. The result is a class instance that both represents the COM object and handles events from the COM object. It is important to note that the returned instance is not a direct instance of the user_event_class, but an instance of a temporary class object that derives from three classes: * The makepy generated class for the COM object * The makepy generated class for the COM events * The user_event_class as passed to this function. If this is not suitable, see the getevents function for an alternative technique of handling events. Object Lifetimes: Whenever the object returned from this function is cleaned-up by Python, the events will be disconnected from the COM object. This is almost always what should happen, but see the documentation for getevents() for more details. Example: >>> class IEEvents: ... def OnVisible(self, visible): ... print "Visible changed:", visible ... >>> ie = DispatchWithEvents("InternetExplorer.Application", IEEvents) >>> ie.Visible = 1 Visible changed: 1 >>> """ # Create/Get the object. disp = Dispatch(clsid) if not disp.__class__.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it. try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] tlb, index = ti.GetContainingTypeLib() tla = tlb.GetLibAttr() gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) # Get the class from the module. disp_class = gencache.GetClassForProgID(str(disp_clsid)) except pythoncom.com_error: raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object") else: disp_class = disp.__class__ # If the clsid was an object, get the clsid clsid = disp_class.CLSID # Create a new class that derives from 3 classes - the dispatch class, the event sink class and the user class. # XXX - we are still "classic style" classes in py2x, so we need can't yet # use 'type()' everywhere - revisit soon, as py2x will move to new-style too... try: from types import ClassType as new_type except ImportError: new_type = type # py3k events_class = getevents(clsid) if events_class is None: raise ValueError("This COM object does not support events.") result_class = new_type("COMEventClass", (disp_class, events_class, user_event_class), {"__setattr__" : _event_setattr_}) instance = result_class(disp._oleobj_) # This only calls the first base class __init__. events_class.__init__(instance, instance) if hasattr(user_event_class, "__init__"): user_event_class.__init__(instance) return EventsProxy(instance)