activex.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. """Support for ActiveX control hosting in Pythonwin.
  2. """
  3. import win32ui, win32uiole
  4. from . import window
  5. # XXX - we are still "classic style" classes in py2x, so we need can't yet
  6. # use 'type()' everywhere - revisit soon, as py2x will move to new-style too...
  7. try:
  8. from types import ClassType as new_type
  9. except ImportError:
  10. new_type = type # py3k
  11. class Control(window.Wnd):
  12. """An ActiveX control base class. A new class must be derived from both
  13. this class and the Events class. See the demos for more details.
  14. """
  15. def __init__(self):
  16. self.__dict__["_dispobj_"] = None
  17. window.Wnd.__init__(self)
  18. def _GetControlCLSID( self ):
  19. return self.CLSID
  20. def _GetDispatchClass(self):
  21. return self.default_interface
  22. def _GetEventMap(self):
  23. return self.default_source._dispid_to_func_
  24. def CreateControl(self, windowTitle, style, rect, parent, id, lic_string=None):
  25. clsid = str(self._GetControlCLSID())
  26. self.__dict__["_obj_"] = win32ui.CreateControl(clsid, windowTitle, style, rect, parent, id, None, False, lic_string)
  27. klass = self._GetDispatchClass()
  28. dispobj = klass(win32uiole.GetIDispatchForWindow(self._obj_))
  29. self.HookOleEvents()
  30. self.__dict__["_dispobj_"] = dispobj
  31. def HookOleEvents(self):
  32. dict = self._GetEventMap()
  33. for dispid, methodName in dict.items():
  34. if hasattr(self, methodName):
  35. self._obj_.HookOleEvent( getattr(self, methodName), dispid )
  36. def __getattr__(self, attr):
  37. # Delegate attributes to the windows and the Dispatch object for this class
  38. try:
  39. return window.Wnd.__getattr__(self, attr)
  40. except AttributeError:
  41. pass
  42. return getattr(self._dispobj_, attr)
  43. def __setattr__(self, attr, value):
  44. if hasattr(self.__dict__, attr):
  45. self.__dict__[attr] = value
  46. return
  47. try:
  48. if self._dispobj_:
  49. self._dispobj_.__setattr__(attr, value)
  50. return
  51. except AttributeError:
  52. pass
  53. self.__dict__[attr] = value
  54. def MakeControlClass( controlClass, name = None ):
  55. """Given a CoClass in a generated .py file, this function will return a Class
  56. object which can be used as an OCX control.
  57. This function is used when you do not want to handle any events from the OCX
  58. control. If you need events, then you should derive a class from both the
  59. activex.Control class and the CoClass
  60. """
  61. if name is None:
  62. name = controlClass.__name__
  63. return new_type("OCX" + name, (Control, controlClass), {})
  64. def MakeControlInstance( controlClass, name = None ):
  65. """As for MakeControlClass(), but returns an instance of the class.
  66. """
  67. return MakeControlClass(controlClass, name)()