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