3 This demo shows how to embed an ActiveX control in a wxPython 
   4 application, (Win32 only.) 
   7 The MakeActiveXClass function dynamically builds a new Class on the 
   8 fly, that has the same signature and semantics as wxWindow.  This 
   9 means that when you call the function you get back a new class that 
  10 you can use just like wxWindow, (set the size and position, use in a 
  11 sizer, etc.) except its contents will be the COM control. 
  14 This demo embeds the Internet Explorer WebBrowser control, and shows 
  15 how to receive events from the COM control.  (The title bar and status 
  16 bar are updated as pages change, in addition to the log messages being 
  24 if wx
.Platform 
== '__WXMSW__': 
  25     import  wx
.lib
.activexwrapper   
as  ax
 
  26     import  win32com
.client
.gencache
 
  29         browserModule 
= win32com
.client
.gencache
.EnsureModule( 
  30             "{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1 
  33         raise ImportError("IE4 or greater does not appear to be installed.") 
  36 #---------------------------------------------------------------------- 
  38 class TestPanel(wx
.Window
): 
  39     def __init__(self
, parent
, log
, frame
=None): 
  42             style
=wx
.CLIP_CHILDREN|wx
.NO_FULL_REPAINT_ON_RESIZE
 
  47         self
.current 
= "http://wxPython.org/" 
  51             self
.titleBase 
= frame
.GetTitle() 
  53         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
  54         btnSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
  56         # Make a new class that derives from the WebBrowser class in the 
  57         # COM module imported above.  This class also derives from wxWindow and 
  58         # implements the machinery needed to integrate the two worlds. 
  59         theClass 
= ax
.MakeActiveXClass( 
  60                         browserModule
.WebBrowser
, eventObj 
= self
 
  63         # Create an instance of that class 
  64         self
.ie 
= theClass(self
, -1) ##, style=wxSUNKEN_BORDER) 
  67         btn 
= wx
.Button(self
, wx
.NewId(), "Open", style
=wx
.BU_EXACTFIT
) 
  68         self
.Bind(wx
.EVT_BUTTON
, self
.OnOpenButton
, id=btn
.GetId()) 
  69         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  71         btn 
= wx
.Button(self
, wx
.NewId(), "Home", style
=wx
.BU_EXACTFIT
) 
  72         self
.Bind(wx
.EVT_BUTTON
, self
.OnHomeButton
, id=btn
.GetId()) 
  73         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  75         btn 
= wx
.Button(self
, wx
.NewId(), "<--", style
=wx
.BU_EXACTFIT
) 
  76         self
.Bind(wx
.EVT_BUTTON
, self
.OnPrevPageButton
, id=btn
.GetId()) 
  77         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  79         btn 
= wx
.Button(self
, wx
.NewId(), "-->", style
=wx
.BU_EXACTFIT
) 
  80         self
.Bind(wx
.EVT_BUTTON
, self
.OnNextPageButton
, id=btn
.GetId()) 
  81         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  83         btn 
= wx
.Button(self
, wx
.NewId(), "Stop", style
=wx
.BU_EXACTFIT
) 
  84         self
.Bind(wx
.EVT_BUTTON
, self
.OnStopButton
, id=btn
.GetId()) 
  85         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  87         btn 
= wx
.Button(self
, wx
.NewId(), "Search", style
=wx
.BU_EXACTFIT
) 
  88         self
.Bind(wx
.EVT_BUTTON
, self
.OnSearchPageButton
, id=btn
.GetId()) 
  89         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  91         btn 
= wx
.Button(self
, wx
.NewId(), "Refresh", style
=wx
.BU_EXACTFIT
) 
  92         self
.Bind(wx
.EVT_BUTTON
, self
.OnRefreshPageButton
, id=btn
.GetId()) 
  93         btnSizer
.Add(btn
, 0, wx
.EXPAND|wx
.ALL
, 2) 
  95         txt 
= wx
.StaticText(self
, -1, "Location:") 
  96         btnSizer
.Add(txt
, 0, wx
.CENTER|wx
.ALL
, 2) 
  98         self
.location 
= wx
.ComboBox(self
, wx
.NewId(), "", style
=wx
.CB_DROPDOWN
) 
  99         self
.Bind(wx
.EVT_COMBOBOX
, self
.OnLocationSelect
, id=self
.location
.GetId()) 
 100         self
.Bind(wx
.EVT_KEY_UP
, self
.OnLocationKey
, self
.location
) 
 101         self
.Bind(wx
.EVT_CHAR
, self
.IgnoreReturn
, self
.location
) 
 102         btnSizer
.Add(self
.location
, 1, wx
.EXPAND|wx
.ALL
, 2) 
 104         sizer
.Add(btnSizer
, 0, wx
.EXPAND
) 
 105         sizer
.Add(self
.ie
, 1, wx
.EXPAND
) 
 107         self
.ie
.Navigate(self
.current
) 
 108         self
.location
.Append(self
.current
) 
 111         self
.SetAutoLayout(True) 
 112         self
.Bind(wx
.EVT_SIZE
, self
.OnSize
) 
 113         self
.Bind(wx
.EVT_WINDOW_DESTROY
, self
.OnDestroy
) 
 116     def ShutdownDemo(self
): 
 117         # put the frame title back 
 119             self
.frame
.SetTitle(self
.titleBase
) 
 122     def OnDestroy(self
, evt
): 
 129     def OnSize(self
, evt
): 
 133     def OnLocationSelect(self
, evt
): 
 134         url 
= self
.location
.GetStringSelection() 
 135         self
.log
.write('OnLocationSelect: %s\n' % url
) 
 136         self
.ie
.Navigate(url
) 
 138     def OnLocationKey(self
, evt
): 
 139         if evt
.KeyCode() == wx
.WXK_RETURN
: 
 140             URL 
= self
.location
.GetValue() 
 141             self
.location
.Append(URL
) 
 142             self
.ie
.Navigate(URL
) 
 146     def IgnoreReturn(self
, evt
): 
 148         if evt
.KeyCode() != wx
.WXK_RETURN
: 
 151     def OnOpenButton(self
, event
): 
 152         dlg 
= wx
.TextEntryDialog(self
, "Open Location", 
 153                                 "Enter a full URL or local path", 
 154                                 self
.current
, wx
.OK|wx
.CANCEL
) 
 158         if dlg
.ShowModal() == wx
.ID_OK
: 
 159             self
.current 
= dlg
.GetValue() 
 160             self
.ie
.Navigate(self
.current
) 
 164     def OnHomeButton(self
, event
): 
 165         self
.ie
.GoHome()    ## ET Phone Home! 
 167     def OnPrevPageButton(self
, event
): 
 170     def OnNextPageButton(self
, event
): 
 173     def OnStopButton(self
, evt
): 
 176     def OnSearchPageButton(self
, evt
): 
 179     def OnRefreshPageButton(self
, evt
): 
 183     # The following event handlers are called by the web browser COM 
 184     # control since  we passed self to MakeActiveXClass.  It will look 
 185     # here for matching attributes and call them if they exist.  See the 
 186     # module generated by makepy for details of method names, etc. 
 187     def OnBeforeNavigate2(self
, pDisp
, URL
, *args
): 
 188         self
.log
.write('OnBeforeNavigate2: %s\n' % URL
) 
 190     def OnNavigateComplete2(self
, pDisp
, URL
): 
 191         self
.log
.write('OnNavigateComplete2: %s\n' % URL
) 
 193         self
.location
.SetValue(URL
) 
 195     def OnTitleChange(self
, text
): 
 196         self
.log
.write('OnTitleChange: %s\n' % text
) 
 198             self
.frame
.SetTitle(self
.titleBase 
+ ' -- ' + text
) 
 200     def OnStatusTextChange(self
, text
): 
 201         self
.log
.write('OnStatusTextChange: %s\n' % text
) 
 203             self
.frame
.SetStatusText(text
) 
 206 #---------------------------------------------------------------------- 
 207 # for the demo framework... 
 209 def runTest(frame
, nb
, log
): 
 210     if wx
.Platform 
== '__WXMSW__': 
 211         win 
= TestPanel(nb
, log
, frame
) 
 214         dlg 
= wx
.MessageDialog(frame
, 'This demo only works on MSW.', 
 215                           'Sorry', wx
.OK | wx
.ICON_INFORMATION
) 
 222 #---------------------------------------------------------------------- 
 225 if __name__ 
== '__main__': 
 226     class TestFrame(wx
.Frame
): 
 229                 self
, None, -1, "ActiveX test -- Internet Explorer", 
 231                 style
=wx
.DEFAULT_FRAME_STYLE|wx
.NO_FULL_REPAINT_ON_RESIZE
 
 234             self
.CreateStatusBar() 
 235             self
.tp 
= TestPanel(self
, sys
.stdout
, self
) 
 236             self
.Bind(wx
.EVT_CLOSE
, self
.OnCloseWindow
) 
 238         def OnCloseWindow(self
, evt
): 
 242     app 
= wx
.PySimpleApp()