Win32: ByRef equivalent in pythoncom for function callbacks?
Mike Fletcher
mfletch at tpresence.com
Fri Oct 6 03:01:36 EDT 2000
Okay, I've spent a bit of time trying to do this right with "for demand" to
make a quick demo for DOM access via IE, and I got it working for two or
three runs. Then somehow the world went screwy and the same code stopped
functioning as it should. It's possible that I clobbered the working
version with an older version, but I don't see any problem with my current
code.
I'm creating a Dispatch object for the IHTMLTextContainer interface of the
DOM Body element, and this appears to be correct. This interface does
define a scrollTop property (both put and get), but when I attempt to access
the property, I get a com_error. Any pointers or slaps upside the head for
obvious problems would be appreciated. Note: my original code using solely
Dispatch objects with no type library was able to directly take
self.Document.body.scrollTop, so I suppose it's possible that the dispatch
object was on one run not able to get the IHTMLTextContainer module, and in
using base Dispatch might have been able to do the same trick. To show
this, replace the Dispatch call with:
self.body = Dispatch(
body._oleobj_,
## "HTMLBody",
## IHTMLTextContainer_CLSID,
)
And you'll see that the body becomes a DispHTMLBody instance, which works
properly, allowing you to use scrollTop as a property. From what I
understand, however, this is not the proper way to get an interface handle.
On the other hand, it works :o) .
For the simplified demo, I'm just importing directly in the pythonwin
interactive environment. The current (nonfunctional) code with traceback
follows.
Enjoy yourselves,
Mike
8<____________ htmlwindow.py _________
'''Demo getting the IHTMLWindow2 pointer from a WebBrowser control
'''
# from portals.htmldemo import htmlwindow
from win32com.client import *
from win32com.server import util, policy
from win32com.client import gencache
from pywin.tools.browser import Browse
from pywin.debugger import set_trace
##from pdb import set_trace
import pythoncom, traceback
HTMLLib_CLSID = '{3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}'
IHTMLTextContainer_CLSID = '{3050F230-98B5-11CF-BB82-00AA00BDCE0B}'
IHTMLBody2_CLSID = '{332C4425-26CB-11D0-B483-00C04FD90119}'
try:
htmlmodule = gencache.EnsureModule(
HTMLLib_CLSID, 0, 4, 0,
bForDemand=1
)
## print dir( iemodule)
## print iemodule.DispHTMLBody
except (ImportError, pythoncom.error):
raise SystemExit( '''this demo requires IE 5.0 or above''' )
class IEEvents:
## def OnVisible( self, visible ):
## print 'visible', visible
def OnDownloadComplete( self, *args):
print 'NavigateComplete'
try:
print 'self.Document', self.Document
body = self.Document.body
print 'body', body
if body:
## set_trace()
self.body = Dispatch(
body._oleobj_,
"HTMLBody",
IHTMLTextContainer_CLSID,
)
print 'body is', self.body
self.htmlwindow = self.Document.parentWindow
self.SinkTest()
except:
traceback.print_exc()
return 1
def SinkTest( self ):
print 'SinkTest'
sink = Sink(self.htmlwindow, self.body )
def transformarg(arg):
if type(arg)==dispatchType:
return Dispatch(arg)
elif type(arg)==UnicodeType:
return str(arg)
return arg
arg_transformer = lambda object, args: map(transformarg, args)
class Sink: # as in Kitchen ;o)
CLSID = CLSID_Sink =
pythoncom.MakeIID('{3050F625-98B5-11CF-BB82-00AA00BDCE0B}')
_arg_transformer_ = arg_transformer
_public_methods_ = [
## "Ononscroll",
]
_dispid_to_func_ = {
1016 : "Ononresize",
1025 : "Ononafterprint",
-2147418102 : "Ononhelp",
-2147418112 : "Ononblur",
-2147418111 : "Ononfocus",
1002 : "Ononerror",
1017 : "Ononbeforeunload",
1024 : "Ononbeforeprint",
1008 : "Ononunload",
1003 : "Ononload",
1014 : "Ononscroll",
}
def __init__( self, window, body ):
self.window = window
self.body = body
advise( self.window, self)
def Ononscroll( self, *args):
try:
event = self.window.event
## set_trace()
print 'body', self.body
print 'scroll', self.body.scrollTop
except:
traceback.print_exc()
return 1
def advise( window, sink ):
cpc = window._oleobj_.QueryInterface(
pythoncom.IID_IConnectionPointContainer
)
cp = cpc.FindConnectionPoint(
# this is the clsID of the IHTMLWindow2 interface
sink.CLSID_Sink,
)
cookie=cp.Advise(
util.wrap(sink)
)
sink._olecp,sink._olecp_cookie = cp,cookie
ie = DispatchWithEvents("InternetExplorer.Application", IEEvents)
ie.Visible = 1
ie.Navigate( 'www.tpresence.com' )
8<________________ traceback __________
...
body <win32com.gen_py.Microsoft HTML Object Library.IHTMLTextContainer>
scrollTraceback (innermost last):
File "/portals\htmldemo\htmlwindow.py", line 89, in Ononscroll
except:
File "D:\bin\lang\Python\win32com\client\__init__.py", line 347, in
__getattr__
return apply(self._ApplyTypes_, args)
File "D:\bin\lang\Python\win32com\client\__init__.py", line 341, in
_ApplyTypes_
return self._get_good_object_(apply(self._oleobj_.InvokeTypes, (dispid,
0, wFlags, retType, argTypes) + args), user, resultCLSID)
com_error: (-2147352573, 'Member not found.', None, None)
body <win32com.gen_py.Microsoft HTML Object Library.IHTMLTextContainer>
-----Original Message-----
From: Mark Hammond
To: Mike Fletcher; python-list at python.org
Sent: 10/4/2000 9:07 AM
Subject: RE: Win32: ByRef equivalent in pythoncom for function callbacks?
> What I did was strip the particular event handler class out of the
mshtml
> Makepy interface file (which will not import, likely because
> it's 1.9 MB),
Note there is a new "for demand" option that will create a package, and
only generate the specific interfaces when actually needed - for exactly
this reason! Most of the gencache functions have a bForDemand param...
Python talking to a DOM - that seems to be happening a bit, recently ;-)
Mark.
More information about the Python-list
mailing list