Setting contentEditable in a wxPython IEHtmlWindow

wxPython's iewin.IEHtmlWindow lets you host the Internet Explorer browser control in a wxPython window.

Doing so is quite simple:

import wx
from wx.lib import iewin

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="IEHtmlWindow")
        self.ie = iewin.IEHtmlWindow(self)
        self.ie.Navigate("http://example.com/") # your URL here

app = wx.App(False)
MyFrame().Show()

app.MainLoop()

IEHtmlWindow has a ctrl member that you can use to manipulate a page's DOM. One of the cool things that this allows you to do is edit a specific element on a page.

To do this, you first need to get the desired element:

element = self.ie.ctrl.Document.getElementById("some_item_id")

And then set contentEditable to "true".

However, getElementByID returns an IHTMLElement interface, and contentEditable is only supported by the IHTMLElement3 interface and higher (IE has been around for a while, and there are now something like 6 iterations of this interface…). We therefore need to call QueryInterface on our element in order to get an IHTMLElement3.

The QueryInterface method call takes the class of the interface we want, which lives in the MSHTML module generated by comtypes (iewin ensures it's generated), so we need to import that.

from comtypes.gen import MSHTML

Then, we get the IHTMLElement3 interface, and set contentEditable to "true" like this:

element = self.ie.ctrl.Document.getElementById("my_element")
element3 = element.QueryInterface(MSHTML.IHTMLElement3)
element3.contentEditable = "true"

Since we can't manipulate the DOM until the document is loaded, it's a good idea to put this code in the DocumentComplete event handler (which we get called by setting ourselves as the event sink).

So putting it all together:

import wx
from wx.lib import iewin
from comtypes.gen import MSHTML

class MyFrame(wx.Frame):
    def __init__(self):
        """Init IEHtmlWindow and set ourselves as event sink"""
        wx.Frame.__init__(self, None, title="IEHtmlWindow")
        self.ie = iewin.IEHtmlWindow(self)
        self.ie.AddEventSink(self)
        self.ie.Navigate("http://example.com/") # your URL here

    def DocumentComplete(self, this, pDisp, URL):
        """
        Called when the HTML document finishes loading.
        If we were waiting on any actions to perform
        when the document was complete, we execute them here.
        "
""
        element = self.ie.ctrl.Document.getElementById("my_element")
        element3 = element.QueryInterface(MSHTML.IHTMLElement3)
        element3.contentEditable = "true"

app = wx.App(False)
MyFrame().Show()

app.MainLoop()

That's it. Not bad for 26 lines of code, including docstrings.

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>