1#---------------------------------------------------------------------- 2# Name: wx.lib.activexwrapper 3# Purpose: a wxWindow derived class that can hold an ActiveX control 4# 5# Author: Robin Dunn 6# 7# Copyright: (c) 2000-2018 by Total Control Software 8# Licence: wxWindows license 9#---------------------------------------------------------------------- 10# 11/30/2003 - Jeff Grimmett (grimmtooth@softhome.net) 11# 12# o Updated for wx namespace 13# o Tested with updated demo 14# 15 16import wx 17 18try: 19 import win32ui 20 import pywin.mfc.activex 21 import win32com.client 22except ImportError: 23 import sys 24 if hasattr(sys, "frozen"): 25 import os, win32api 26 dllpath = os.path.join(win32api.GetSystemDirectory(), 'MFC71.DLL') 27 if sys.version[:3] >= '2.4' and not os.path.exists(dllpath): 28 message = "%s not found" % dllpath 29 else: 30 raise # original error message 31 else: 32 message = "ActiveXWrapper requires PythonWin. Please install the PyWin32 package." 33 raise ImportError(message) 34 35##from win32con import WS_TABSTOP, WS_VISIBLE 36WS_TABSTOP = 0x00010000 37WS_VISIBLE = 0x10000000 38 39#---------------------------------------------------------------------- 40 41 42def MakeActiveXClass(CoClass, eventClass=None, eventObj=None): 43 """ 44 Dynamically construct a new class that derives from wxWindow, the 45 ActiveX control and the appropriate COM classes. This new class 46 can be used just like the wxWindow class, but will also respond 47 appropriately to the methods and properties of the COM object. If 48 this class, a derived class or a mix-in class has method names 49 that match the COM object's event names, they will be called 50 automatically. 51 52 CoClass -- A COM control class from a module generated by 53 makepy.py from a COM TypeLibrary. Can also accept a 54 CLSID. 55 56 eventClass -- If given, this class will be added to the set of 57 base classes that the new class is drived from. It is 58 good for mix-in classes for catching events. 59 60 eventObj -- If given, this object will be searched for attributes 61 by the new class's __getattr__ method, (like a mix-in 62 object.) This is useful if you want to catch COM 63 callbacks in an existing object, (such as the parent 64 window.) 65 66 """ 67 68 69 if type(CoClass) == type(""): 70 # use the CLSID to get the real class 71 CoClass = win32com.client.CLSIDToClass(CoClass) 72 73 # determine the base classes 74 axEventClass = CoClass.default_source 75 baseClasses = [pywin.mfc.activex.Control, wx.Window, CoClass, axEventClass] 76 if eventClass: 77 baseClasses.append(eventClass) 78 baseClasses = tuple(baseClasses) 79 80 # define the class attributes 81 className = 'AXControl_'+CoClass.__name__ 82 classDict = { '__init__' : axw__init__, 83 '__getattr__' : axw__getattr__, 84 'axw_OnSize' : axw_OnSize, 85 'axw_OEB' : axw_OEB, 86 '_name' : className, 87 '_eventBase' : axEventClass, 88 '_eventObj' : eventObj, 89 'Cleanup' : axw_Cleanup, 90 } 91 92 # make a new class object 93 classObj = type(className, baseClasses, classDict) 94 return classObj 95 96 97 98 99# These functions will be used as methods in the new class 100def axw__init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): 101 102 # init base classes 103 pywin.mfc.activex.Control.__init__(self) 104 wx.Window.__init__( self, parent, -1, pos, size, style|wx.NO_FULL_REPAINT_ON_RESIZE) 105 #self.this.own(False) # this should be set in wx.Window.__init__ when it calls _setOORInfo, but... 106 107 win32ui.EnableControlContainer() 108 self._eventObj = self._eventObj # move from class to instance 109 110 # create a pythonwin wrapper around this wxWindow 111 handle = self.GetHandle() 112 self._wnd = win32ui.CreateWindowFromHandle(handle) 113 114 # create the control 115 sz = self.GetSize() 116 self.CreateControl(self._name, WS_TABSTOP | WS_VISIBLE, 117 (0, 0, sz.width, sz.height), self._wnd, ID) 118 119 # init the ax events part of the object 120 self._eventBase.__init__(self, self._dispobj_) 121 122 # hook some wx events 123 self.Bind(wx.EVT_SIZE, self.axw_OnSize) 124 125def axw__getattr__(self, attr): 126 try: 127 return pywin.mfc.activex.Control.__getattr__(self, attr) 128 except (AttributeError, win32ui.error): 129 try: 130 eo = self.__dict__['_eventObj'] 131 return getattr(eo, attr) 132 except AttributeError: 133 raise AttributeError('Attribute not found: %s' % attr) 134 135 136def axw_OnSize(self, event): 137 sz = self.GetClientSize() # get wxWindow size 138 self.MoveWindow((0, 0, sz.width, sz.height), 1) # move the AXControl 139 140 141def axw_OEB(self, event): 142 pass 143 144 145def axw_Cleanup(self): 146 #del self._wnd 147 self.close() 148 pass 149 150 151 152 153 154