123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- # -*- coding: latin-1 -*-
- # PyWin32 Internet Explorer Toolbar
- #
- # written by Leonard Ritter (paniq@gmx.net)
- # and Robert Förtsch (info@robert-foertsch.com)
- """
- This sample implements a simple IE Toolbar COM server
- supporting Windows XP styles and access to
- the IWebBrowser2 interface.
- It also demonstrates how to hijack the parent window
- to catch WM_COMMAND messages.
- """
- # imports section
- import sys, os
- from win32com import universal
- from win32com.client import gencache, DispatchWithEvents, Dispatch
- from win32com.client import constants, getevents
- import win32com
- import pythoncom
- import winreg
- from win32com.shell import shell
- from win32com.shell.shellcon import *
- from win32com.axcontrol import axcontrol
- try:
- # try to get styles (winxp)
- import winxpgui as win32gui
- except:
- # import default module (win2k and lower)
- import win32gui
- import win32ui
- import win32con
- import commctrl
- import array, struct
- # ensure we know the ms internet controls typelib so we have access to IWebBrowser2 later on
- win32com.client.gencache.EnsureModule('{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}',0,1,1)
- #
- IDeskBand_methods = ['GetBandInfo']
- IDockingWindow_methods = ['ShowDW','CloseDW','ResizeBorderDW']
- IOleWindow_methods = ['GetWindow','ContextSensitiveHelp']
- IInputObject_methods = ['UIActivateIO','HasFocusIO','TranslateAcceleratorIO']
- IObjectWithSite_methods = ['SetSite','GetSite']
- IPersistStream_methods = ['GetClassID','IsDirty','Load','Save','GetSizeMax']
- _ietoolbar_methods_ = IDeskBand_methods + IDockingWindow_methods + \
- IOleWindow_methods + IInputObject_methods + \
- IObjectWithSite_methods + IPersistStream_methods
- _ietoolbar_com_interfaces_ = [
- shell.IID_IDeskBand, # IDeskBand
- axcontrol.IID_IObjectWithSite, # IObjectWithSite
- pythoncom.IID_IPersistStream,
- axcontrol.IID_IOleCommandTarget,
- ]
- class WIN32STRUCT:
- def __init__(self, **kw):
- full_fmt = ""
- for name, fmt, default in self._struct_items_:
- self.__dict__[name] = None
- if fmt == "z":
- full_fmt += "pi"
- else:
- full_fmt += fmt
- for name, val in kw.items():
- self.__dict__[name] = val
- def __setattr__(self, attr, val):
- if not attr.startswith("_") and attr not in self.__dict__:
- raise AttributeError(attr)
- self.__dict__[attr] = val
- def toparam(self):
- self._buffs = []
- full_fmt = ""
- vals = []
- for name, fmt, default in self._struct_items_:
- val = self.__dict__[name]
- if fmt == "z":
- fmt = "Pi"
- if val is None:
- vals.append(0)
- vals.append(0)
- else:
- str_buf = array.array("c", val+'\0')
- vals.append(str_buf.buffer_info()[0])
- vals.append(len(val))
- self._buffs.append(str_buf) # keep alive during the call.
- else:
- if val is None:
- val = default
- vals.append(val)
- full_fmt += fmt
- return struct.pack(*(full_fmt,) + tuple(vals))
- class TBBUTTON(WIN32STRUCT):
- _struct_items_ = [
- ("iBitmap", "i", 0),
- ("idCommand", "i", 0),
- ("fsState", "B", 0),
- ("fsStyle", "B", 0),
- ("bReserved", "H", 0),
- ("dwData", "I", 0),
- ("iString", "z", None),
- ]
- class Stub:
- """
- this class serves as a method stub,
- outputting debug info whenever the object
- is being called.
- """
- def __init__(self,name):
- self.name = name
-
- def __call__(self,*args):
- print('STUB: ',self.name,args)
- class IEToolbarCtrl:
- """
- a tiny wrapper for our winapi-based
- toolbar control implementation.
- """
- def __init__(self,hwndparent):
- styles = win32con.WS_CHILD \
- | win32con.WS_VISIBLE \
- | win32con.WS_CLIPSIBLINGS \
- | win32con.WS_CLIPCHILDREN \
- | commctrl.TBSTYLE_LIST \
- | commctrl.TBSTYLE_FLAT \
- | commctrl.TBSTYLE_TRANSPARENT \
- | commctrl.CCS_TOP \
- | commctrl.CCS_NODIVIDER \
- | commctrl.CCS_NORESIZE \
- | commctrl.CCS_NOPARENTALIGN
- self.hwnd = win32gui.CreateWindow('ToolbarWindow32', None, styles,
- 0, 0, 100, 100,
- hwndparent, 0, win32gui.dllhandle,
- None)
- win32gui.SendMessage(self.hwnd, commctrl.TB_BUTTONSTRUCTSIZE, 20, 0)
- def ShowWindow(self,mode):
- win32gui.ShowWindow(self.hwnd,mode)
- def AddButtons(self,*buttons):
- tbbuttons = ''
- for button in buttons:
- tbbuttons += button.toparam()
- return win32gui.SendMessage(self.hwnd, commctrl.TB_ADDBUTTONS,
- len(buttons), tbbuttons)
- def GetSafeHwnd(self):
- return self.hwnd
- class IEToolbar:
- """
- The actual COM server class
- """
- _com_interfaces_ = _ietoolbar_com_interfaces_
- _public_methods_ = _ietoolbar_methods_
- _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
- # if you copy and modify this example, be sure to change the clsid below
- _reg_clsid_ = "{F21202A2-959A-4149-B1C3-68B9013F3335}"
- _reg_progid_ = "PyWin32.IEToolbar"
- _reg_desc_ = 'PyWin32 IE Toolbar'
- def __init__( self ):
- # put stubs for non-implemented methods
- for method in self._public_methods_:
- if not hasattr(self,method):
- print('providing default stub for %s' % method)
- setattr(self,method,Stub(method))
- def GetWindow(self):
- return self.toolbar.GetSafeHwnd()
- def Load(self, stream):
- # called when the toolbar is loaded
- pass
- def Save(self, pStream, fClearDirty):
- # called when the toolbar shall save its information
- pass
- def CloseDW(self, dwReserved):
- del self.toolbar
-
- def ShowDW(self, bShow):
- if bShow:
- self.toolbar.ShowWindow(win32con.SW_SHOW)
- else:
- self.toolbar.ShowWindow(win32con.SW_HIDE)
- def on_first_button(self):
- print("first!")
- self.webbrowser.Navigate2('http://starship.python.net/crew/mhammond/')
- def on_second_button(self):
- print("second!")
- def on_third_button(self):
- print("third!")
- def toolbar_command_handler(self,args):
- hwnd,message,wparam,lparam,time,point = args
- if lparam == self.toolbar.GetSafeHwnd():
- self._command_map[wparam]()
- def SetSite(self,unknown):
- if unknown:
- # retrieve the parent window interface for this site
- olewindow = unknown.QueryInterface(pythoncom.IID_IOleWindow)
- # ask the window for its handle
- hwndparent = olewindow.GetWindow()
- # first get a command target
- cmdtarget = unknown.QueryInterface(axcontrol.IID_IOleCommandTarget)
- # then travel over to a service provider
- serviceprovider = cmdtarget.QueryInterface(pythoncom.IID_IServiceProvider)
- # finally ask for the internet explorer application, returned as a dispatch object
- self.webbrowser = win32com.client.Dispatch(serviceprovider.QueryService('{0002DF05-0000-0000-C000-000000000046}',pythoncom.IID_IDispatch))
- # now create and set up the toolbar
- self.toolbar = IEToolbarCtrl(hwndparent)
- buttons = [
- ('Visit PyWin32 Homepage',self.on_first_button),
- ('Another Button', self.on_second_button),
- ('Yet Another Button', self.on_third_button),
- ]
- self._command_map = {}
- # wrap our parent window so we can hook message handlers
- window = win32ui.CreateWindowFromHandle(hwndparent)
- # add the buttons
- for i in range(len(buttons)):
- button = TBBUTTON()
- name,func = buttons[i]
- id = 0x4444+i
- button.iBitmap = -2
- button.idCommand = id
- button.fsState = commctrl.TBSTATE_ENABLED
- button.fsStyle = commctrl.TBSTYLE_BUTTON
- button.iString = name
- self._command_map[0x4444+i] = func
- self.toolbar.AddButtons(button)
- window.HookMessage(self.toolbar_command_handler,win32con.WM_COMMAND)
- else:
- # lose all references
- self.webbrowser = None
- def GetClassID(self):
- return self._reg_clsid_
- def GetBandInfo(self, dwBandId, dwViewMode, dwMask):
- ptMinSize = (0,24)
- ptMaxSize = (2000,24)
- ptIntegral = (0,0)
- ptActual = (2000,24)
- wszTitle = 'PyWin32 IE Toolbar'
- dwModeFlags = DBIMF_VARIABLEHEIGHT
- crBkgnd = 0
- return (ptMinSize,ptMaxSize,ptIntegral,ptActual,wszTitle,dwModeFlags,crBkgnd)
- # used for HKLM install
- def DllInstall( bInstall, cmdLine ):
- comclass = IEToolbar
- # register plugin
- def DllRegisterServer():
- comclass = IEToolbar
- # register toolbar with IE
- try:
- print("Trying to register Toolbar.\n")
- hkey = winreg.CreateKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Internet Explorer\\Toolbar" )
- subKey = winreg.SetValueEx( hkey, comclass._reg_clsid_, 0, winreg.REG_BINARY, "\0" )
- except WindowsError:
- print("Couldn't set registry value.\nhkey: %d\tCLSID: %s\n" % ( hkey, comclass._reg_clsid_ ))
- else:
- print("Set registry value.\nhkey: %d\tCLSID: %s\n" % ( hkey, comclass._reg_clsid_ ))
- # TODO: implement reg settings for standard toolbar button
- # unregister plugin
- def DllUnregisterServer():
- comclass = IEToolbar
- # unregister toolbar from internet explorer
- try:
- print("Trying to unregister Toolbar.\n")
- hkey = winreg.CreateKey( winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Internet Explorer\\Toolbar" )
- winreg.DeleteValue( hkey, comclass._reg_clsid_ )
- except WindowsError:
- print("Couldn't delete registry value.\nhkey: %d\tCLSID: %s\n" % ( hkey, comclass._reg_clsid_ ))
- else:
- print("Deleting reg key succeeded.\n")
- # entry point
- if __name__ == '__main__':
- import win32com.server.register
- win32com.server.register.UseCommandLine( IEToolbar )
-
- # parse actual command line option
- if "--unregister" in sys.argv:
- DllUnregisterServer()
- else:
- DllRegisterServer()
- else:
- # import trace utility for remote debugging
- import win32traceutil
|