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