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