[pygtk] Embedding a Win32 window or ActiveX control in a pygtk
application
Alif Wahid
alif.wahid at gmail.com
Thu Jun 9 11:01:44 WST 2005
for the "Enter" key, you can import gtk.keysyms module, which comes
with PyGtk. that has all the constants defined for keys. i tried you
code with gtk.keysyms.Return in place of that numeric constant you
used and it worked!
alif.
On 6/9/05, Richie Hindle <richie at entrian.com> wrote:
>
> [Guillaume]
> > I don't remember all details but I did embed a Flash file into a GTK
> > window some time ago:
> > [...]
> > axcontainer=gtk.DrawingArea()
>
> Aha! Parenting the control to a DrawingArea was the step I was missing.
> Thanks!
>
> I've now got this working, and an example application (a poor man's webbrowser,
> embedding IE in pygtk via AtlAxWin and ctypes) is below. There are a few things
> I couldn't make work:
>
> o My keyboard accelerator (Alt+A to focus the address box) doesn't work
> when IE has the focus. Any ideas? How do pygtk accelerators work under the
> surface?
>
> o Clicking a Gtk control when the IE control has the focus doesn't focus
> the Gtk control. I worked around this by putting an event handler on the
> Gtk controls for "button-press-event", but it would need to be done for
> every Gtk control - is there a better solution?
>
> o IE's accelerator keys (eg. Tab and Alt+Left) don't work. In a pure Win32
> app, I'd fix this by calling IOleInPlaceActiveObject::TranslateAccelerator()
> in the message pump, but can I get access to the message pump in pygtk?
>
> o Pressing Enter in the address box should have the same effect as pressing
> the Go button - I've done this, but it's a hack. Is there a better way?
>
> o I'm using 65293 as the code for the Enter key - does pygtk have a constant
> for this?
>
> This is my first pygtk program, so any criticism or suggestions will be
> gratefully received!
>
> -------------------------------- snip snip --------------------------------
>
> """A poor man's webbrowser, embedding IE in pygtk via AtlAxWin and ctypes."""
>
> import win32con
>
> from ctypes import *
> from ctypes.wintypes import *
> from ctypes.com import IUnknown
> from ctypes.com.automation import IDispatch, VARIANT
> from ie6_gen import IWebBrowser2 # Copy ie6_gen from ctypes\win32\com\samples
> kernel32 = windll.kernel32
> user32 = windll.user32
> atl = windll.atl # If this fails, you need atl.dll
>
> import pygtk
> pygtk.require("2.0")
> import gtk
>
> class GUI:
> def __init__(self):
> # Create the main GTK window.
> self.main = gtk.Window(gtk.WINDOW_TOPLEVEL)
> self.main.set_title("Poor man's browser [TM]")
> self.main.connect("destroy", gtk.main_quit)
> self.main.set_size_request(750, 550)
> self.main.realize()
>
> # Create a VBox to house the address bar and the IE control.
> self.mainVBox = gtk.VBox()
> self.main.add(self.mainVBox)
> self.mainVBox.show()
>
> # Create the address bar.
> self.addressEntry = gtk.Entry()
> self.addressEntry.show()
> self.addressEntry.connect("key-press-event", self.on_addressEntry_key)
> self.addressLabel = gtk.Label()
> self.addressLabel.set_text_with_mnemonic("_Address: ")
> self.addressLabel.set_mnemonic_widget(self.addressEntry)
> self.addressLabel.show()
> self.goButton = gtk.Button(" Go ")
> self.goButton.show()
> self.goButton.connect("clicked", self.on_goButton_clicked)
> self.addressHbox = gtk.HBox()
> self.addressHbox.show()
> self.addressHbox.add(self.addressLabel)
> self.addressHbox.add(self.addressEntry)
> self.addressHbox.add(self.goButton)
> self.addressHbox.set_child_packing(self.addressLabel,
> False, True, 2, gtk.PACK_START)
> self.addressHbox.set_child_packing(self.goButton,
> False, True, 0, gtk.PACK_END)
> self.mainVBox.add(self.addressHbox)
> self.mainVBox.set_child_packing(self.addressHbox,
> False, True, 0, gtk.PACK_START)
>
> # Create a DrawingArea to host IE and add it to the hbox.
> self.container = gtk.DrawingArea()
> self.mainVBox.add(self.container)
> self.container.show()
>
> # Make the container accept the focus and pass it to the control;
> # this makes the Tab key pass focus to IE correctly.
> self.container.set_property("can-focus", True)
> self.container.connect("focus", self.on_container_focus)
>
> # Resize the AtlAxWin window with its container.
> self.container.connect("size-allocate", self.on_container_size)
>
> # Create an instance of IE via AtlAxWin.
> atl.AtlAxWinInit()
> hInstance = kernel32.GetModuleHandleA(None)
> parentHwnd = self.container.window.handle
> self.atlAxWinHwnd = \
> user32.CreateWindowExA(0, "AtlAxWin", "http://www.pygtk.org",
> win32con.WS_VISIBLE | win32con.WS_CHILD |
> win32con.WS_HSCROLL | win32con.WS_VSCROLL,
> 0, 0, 100, 100, parentHwnd, None, hInstance, 0)
>
> # Get the IWebBrowser2 interface for the IE control.
> pBrowserUnk = POINTER(IUnknown)()
> atl.AtlAxGetControl(self.atlAxWinHwnd, byref(pBrowserUnk))
> self.pBrowser = POINTER(IWebBrowser2)()
> pBrowserUnk.QueryInterface(byref(IWebBrowser2._iid_),
> byref(self.pBrowser))
>
> # Create a Gtk window that refers to the native AtlAxWin window.
> self.gtkAtlAxWin = gtk.gdk.window_foreign_new(long(self.atlAxWinHwnd))
>
> # By default, clicking a GTK widget doesn't grab the focus away from
> # a native Win32 control.
> self.addressEntry.connect("button-press-event", self.on_widget_click)
>
> def on_goButton_clicked(self, widget):
> v = byref(VARIANT())
> self.pBrowser.Navigate(self.addressEntry.get_text(), v, v, v, v)
>
> def on_addressEntry_key(self, widget, event):
> if event.keyval == 65293: # "Enter"; is there a constant for this?
> self.on_goButton_clicked(None)
>
> def on_widget_click(self, widget, data):
> self.main.window.focus()
>
> def on_container_size(self, widget, sizeAlloc):
> self.gtkAtlAxWin.move_resize(0, 0, sizeAlloc.width, sizeAlloc.height)
>
> def on_container_focus(self, widget, data):
> # Pass the focus to IE. First get the HWND of the IE control; this
> # is a bit of a hack but I couldn't make IWebBrowser2._get_HWND work.
> rect = RECT()
> user32.GetWindowRect(self.atlAxWinHwnd, byref(rect))
> ieHwnd = user32.WindowFromPoint(POINT(rect.left, rect.top))
> user32.SetFocus(ieHwnd)
>
> # Show the main window and run the message loop.
> gui = GUI()
> gui.main.show()
> gtk.main()
>
> -------------------------------- snip snip --------------------------------
>
> --
> Richie Hindle
> richie at entrian.com
>
> _______________________________________________
> pygtk mailing list pygtk at daa.com.au
> http://www.daa.com.au/mailman/listinfo/pygtk
> Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
>
--
"Heaven is the peaceful place on earth...New Zealand."
-- Alif Wahid.
More information about the pygtk
mailing list