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 Exploer 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 
  21 from wxPython
.wx 
import * 
  23 if wxPlatform 
== '__WXMSW__': 
  24     from wxPython
.lib
.activexwrapper 
import MakeActiveXClass
 
  25     import win32com
.client
.gencache
 
  28         browserModule 
= win32com
.client
.gencache
.EnsureModule("{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1) 
  30         raise ImportError("IE4 or greater does not appear to be installed.") 
  33 #---------------------------------------------------------------------- 
  35 class TestPanel(wxWindow
): 
  36     def __init__(self
, parent
, log
, frame
=None): 
  37         wxWindow
.__init
__(self
, parent
, -1, 
  38                           style
=wxCLIP_CHILDREN|wxNO_FULL_REPAINT_ON_RESIZE
) 
  41         self
.current 
= "http://wxPython.org/" 
  44             self
.titleBase 
= frame
.GetTitle() 
  47         sizer 
= wxBoxSizer(wxVERTICAL
) 
  48         btnSizer 
= wxBoxSizer(wxHORIZONTAL
) 
  50         # Make a new class that derives from the WebBrowser class in the 
  51         # COM module imported above.  This class also derives from wxWindow and 
  52         # implements the machinery needed to integrate the two worlds. 
  53         theClass 
= MakeActiveXClass(browserModule
.WebBrowser
, 
  56         # Create an instance of that class 
  57         self
.ie 
= theClass(self
, -1) ##, style=wxSUNKEN_BORDER) 
  60         btn 
= wxButton(self
, wxNewId(), "Open", style
=wxBU_EXACTFIT
) 
  61         EVT_BUTTON(self
, btn
.GetId(), self
.OnOpenButton
) 
  62         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  64         btn 
= wxButton(self
, wxNewId(), "Home", style
=wxBU_EXACTFIT
) 
  65         EVT_BUTTON(self
, btn
.GetId(), self
.OnHomeButton
) 
  66         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  68         btn 
= wxButton(self
, wxNewId(), "<--", style
=wxBU_EXACTFIT
) 
  69         EVT_BUTTON(self
, btn
.GetId(), self
.OnPrevPageButton
) 
  70         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  72         btn 
= wxButton(self
, wxNewId(), "-->", style
=wxBU_EXACTFIT
) 
  73         EVT_BUTTON(self
, btn
.GetId(), self
.OnNextPageButton
) 
  74         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  76         btn 
= wxButton(self
, wxNewId(), "Stop", style
=wxBU_EXACTFIT
) 
  77         EVT_BUTTON(self
, btn
.GetId(), self
.OnStopButton
) 
  78         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  80         btn 
= wxButton(self
, wxNewId(), "Search", style
=wxBU_EXACTFIT
) 
  81         EVT_BUTTON(self
, btn
.GetId(), self
.OnSearchPageButton
) 
  82         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  84         btn 
= wxButton(self
, wxNewId(), "Refresh", style
=wxBU_EXACTFIT
) 
  85         EVT_BUTTON(self
, btn
.GetId(), self
.OnRefreshPageButton
) 
  86         btnSizer
.Add(btn
, 0, wxEXPAND|wxALL
, 2) 
  88         txt 
= wxStaticText(self
, -1, "Location:") 
  89         btnSizer
.Add(txt
, 0, wxCENTER|wxALL
, 2) 
  91         self
.location 
= wxComboBox(self
, wxNewId(), "", style
=wxCB_DROPDOWN
) 
  92         EVT_COMBOBOX(self
, self
.location
.GetId(), self
.OnLocationSelect
) 
  93         EVT_KEY_UP(self
.location
, self
.OnLocationKey
) 
  94         EVT_CHAR(self
.location
, self
.IgnoreReturn
) 
  95         btnSizer
.Add(self
.location
, 1, wxEXPAND|wxALL
, 2) 
  97         sizer
.Add(btnSizer
, 0, wxEXPAND
) 
  98         sizer
.Add(self
.ie
, 1, wxEXPAND
) 
 100         self
.ie
.Navigate(self
.current
) 
 101         self
.location
.Append(self
.current
) 
 104         self
.SetAutoLayout(true
) 
 105         EVT_SIZE(self
, self
.OnSize
) 
 107         EVT_WINDOW_DESTROY(self
, self
.OnDestroy
) 
 110     def OnDestroy(self
, evt
): 
 117     def OnSize(self
, evt
): 
 121     def OnLocationSelect(self
, evt
): 
 122         url 
= self
.location
.GetStringSelection() 
 123         self
.log
.write('OnLocationSelect: %s\n' % url
) 
 124         self
.ie
.Navigate(url
) 
 126     def OnLocationKey(self
, evt
): 
 127         if evt
.KeyCode() == WXK_RETURN
: 
 128             URL 
= self
.location
.GetValue() 
 129             self
.location
.Append(URL
) 
 130             self
.ie
.Navigate(URL
) 
 134     def IgnoreReturn(self
, evt
): 
 136         if evt
.KeyCode() != WXK_RETURN
: 
 139     def OnOpenButton(self
, event
): 
 140         dlg 
= wxTextEntryDialog(self
, "Open Location", 
 141                                 "Enter a full URL or local path", 
 142                                 self
.current
, wxOK|wxCANCEL
) 
 144         if dlg
.ShowModal() == wxID_OK
: 
 145             self
.current 
= dlg
.GetValue() 
 146             self
.ie
.Navigate(self
.current
) 
 149     def OnHomeButton(self
, event
): 
 150         self
.ie
.GoHome()    ## ET Phone Home! 
 152     def OnPrevPageButton(self
, event
): 
 155     def OnNextPageButton(self
, event
): 
 158     def OnStopButton(self
, evt
): 
 161     def OnSearchPageButton(self
, evt
): 
 164     def OnRefreshPageButton(self
, evt
): 
 169     # The following event handlers are called by the web browser COM 
 170     # control since  we passed self to MakeActiveXClass.  It will look 
 171     # here for matching attributes and call them if they exist.  See the 
 172     # module generated by makepy for details of method names, etc. 
 173     def OnBeforeNavigate2(self
, pDisp
, URL
, *args
): 
 174         self
.log
.write('OnBeforeNavigate2: %s\n' % URL
) 
 176     def OnNavigateComplete2(self
, pDisp
, URL
): 
 177         self
.log
.write('OnNavigateComplete2: %s\n' % URL
) 
 179         self
.location
.SetValue(URL
) 
 181     def OnTitleChange(self
, text
): 
 182         self
.log
.write('OnTitleChange: %s\n' % text
) 
 184             self
.frame
.SetTitle(self
.titleBase 
+ ' -- ' + text
) 
 186     def OnStatusTextChange(self
, text
): 
 187         self
.log
.write('OnStatusTextChange: %s\n' % text
) 
 189             self
.frame
.SetStatusText(text
) 
 192 #---------------------------------------------------------------------- 
 193 # for the demo framework... 
 195 def runTest(frame
, nb
, log
): 
 196     if wxPlatform 
== '__WXMSW__': 
 197         win 
= TestPanel(nb
, log
, frame
) 
 200         dlg 
= wxMessageDialog(frame
, 'This demo only works on MSW.', 
 201                           'Sorry', wxOK | wxICON_INFORMATION
) 
 208 #---------------------------------------------------------------------- 
 211 if __name__ 
== '__main__': 
 212     class TestFrame(wxFrame
): 
 214             wxFrame
.__init
__(self
, None, -1, "ActiveX test -- Internet Explorer", 
 216                              style
=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE
) 
 217             self
.CreateStatusBar() 
 218             self
.tp 
= TestPanel(self
, sys
.stdout
, self
) 
 219             EVT_CLOSE(self
, self
.OnCloseWindow
) 
 221         def OnCloseWindow(self
, evt
): 
 225     app 
= wxPySimpleApp()