codekingpro/portable-devtools
114k
1# -*- coding: latin-1 -*-2 3# PyWin32 Internet Explorer Toolbar4#5# written by Leonard Ritter (paniq@gmx.net)6# and Robert F�rtsch (info@robert-foertsch.com)7 8 9"""10This sample implements a simple IE Toolbar COM server11supporting Windows XP styles and access to12the IWebBrowser2 interface.13 14It also demonstrates how to hijack the parent window15to catch WM_COMMAND messages.16"""17 18# imports section19import sys20import winreg21 22import pythoncom23import win32com24from win32com import universal25from win32com.axcontrol import axcontrol26from win32com.client import Dispatch, DispatchWithEvents, constants, gencache, getevents27from win32com.shell import shell28from win32com.shell.shellcon import *29 30try:31 # try to get styles (winxp)32 import winxpgui as win32gui33except:34 # import default module (win2k and lower)35 import win32gui36 37import array38import struct39 40import commctrl41import win32con42import win32ui43 44# ensure we know the ms internet controls typelib so we have access to IWebBrowser2 later on45win32com.client.gencache.EnsureModule("{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1)46 47#48IDeskBand_methods = ["GetBandInfo"]49IDockingWindow_methods = ["ShowDW", "CloseDW", "ResizeBorderDW"]50IOleWindow_methods = ["GetWindow", "ContextSensitiveHelp"]51IInputObject_methods = ["UIActivateIO", "HasFocusIO", "TranslateAcceleratorIO"]52IObjectWithSite_methods = ["SetSite", "GetSite"]53IPersistStream_methods = ["GetClassID", "IsDirty", "Load", "Save", "GetSizeMax"]54 55_ietoolbar_methods_ = (56 IDeskBand_methods57 + IDockingWindow_methods58 + IOleWindow_methods59 + IInputObject_methods60 + IObjectWithSite_methods61 + IPersistStream_methods62)63_ietoolbar_com_interfaces_ = [64 shell.IID_IDeskBand, # IDeskBand65 axcontrol.IID_IObjectWithSite, # IObjectWithSite66 pythoncom.IID_IPersistStream,67 axcontrol.IID_IOleCommandTarget,68]69 70 71class WIN32STRUCT:72 def __init__(self, **kw):73 full_fmt = ""74 for name, fmt, default in self._struct_items_:75 self.__dict__[name] = None76 if fmt == "z":77 full_fmt += "pi"78 else:79 full_fmt += fmt80 for name, val in kw.items():81 self.__dict__[name] = val82 83 def __setattr__(self, attr, val):84 if not attr.startswith("_") and attr not in self.__dict__:85 raise AttributeError(attr)86 self.__dict__[attr] = val87 88 def toparam(self):89 self._buffs = []90 full_fmt = ""91 vals = []92 for name, fmt, default in self._struct_items_:93 val = self.__dict__[name]94 if fmt == "z":95 fmt = "Pi"96 if val is None:97 vals.append(0)98 vals.append(0)99 else:100 str_buf = array.array("c", val + "\0")101 vals.append(str_buf.buffer_info()[0])102 vals.append(len(val))103 self._buffs.append(str_buf) # keep alive during the call.104 else:105 if val is None:106 val = default107 vals.append(val)108 full_fmt += fmt109 return struct.pack(*(full_fmt,) + tuple(vals))110 111 112class TBBUTTON(WIN32STRUCT):113 _struct_items_ = [114 ("iBitmap", "i", 0),115 ("idCommand", "i", 0),116 ("fsState", "B", 0),117 ("fsStyle", "B", 0),118 ("bReserved", "H", 0),119 ("dwData", "I", 0),120 ("iString", "z", None),121 ]122 123 124class Stub:125 """126 this class serves as a method stub,127 outputting debug info whenever the object128 is being called.129 """130 131 def __init__(self, name):132 self.name = name133 134 def __call__(self, *args):135 print("STUB: ", self.name, args)136 137 138class IEToolbarCtrl:139 """140 a tiny wrapper for our winapi-based141 toolbar control implementation.142 """143 144 def __init__(self, hwndparent):145 styles = (146 win32con.WS_CHILD147 | win32con.WS_VISIBLE148 | win32con.WS_CLIPSIBLINGS149 | win32con.WS_CLIPCHILDREN150 | commctrl.TBSTYLE_LIST151 | commctrl.TBSTYLE_FLAT152 | commctrl.TBSTYLE_TRANSPARENT153 | commctrl.CCS_TOP154 | commctrl.CCS_NODIVIDER155 | commctrl.CCS_NORESIZE156 | commctrl.CCS_NOPARENTALIGN157 )158 self.hwnd = win32gui.CreateWindow(159 "ToolbarWindow32",160 None,161 styles,162 0,163 0,164 100,165 100,166 hwndparent,167 0,168 win32gui.dllhandle,169 None,170 )171 win32gui.SendMessage(self.hwnd, commctrl.TB_BUTTONSTRUCTSIZE, 20, 0)172 173 def ShowWindow(self, mode):174 win32gui.ShowWindow(self.hwnd, mode)175 176 def AddButtons(self, *buttons):177 tbbuttons = ""178 for button in buttons:179 tbbuttons += button.toparam()180 return win32gui.SendMessage(181 self.hwnd, commctrl.TB_ADDBUTTONS, len(buttons), tbbuttons182 )183 184 def GetSafeHwnd(self):185 return self.hwnd186 187 188class IEToolbar:189 """190 The actual COM server class191 """192 193 _com_interfaces_ = _ietoolbar_com_interfaces_194 _public_methods_ = _ietoolbar_methods_195 _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER196 # if you copy and modify this example, be sure to change the clsid below197 _reg_clsid_ = "{F21202A2-959A-4149-B1C3-68B9013F3335}"198 _reg_progid_ = "PyWin32.IEToolbar"199 _reg_desc_ = "PyWin32 IE Toolbar"200 201 def __init__(self):202 # put stubs for non-implemented methods203 for method in self._public_methods_:204 if not hasattr(self, method):205 print("providing default stub for %s" % method)206 setattr(self, method, Stub(method))207 208 def GetWindow(self):209 return self.toolbar.GetSafeHwnd()210 211 def Load(self, stream):212 # called when the toolbar is loaded213 pass214 215 def Save(self, pStream, fClearDirty):216 # called when the toolbar shall save its information217 pass218 219 def CloseDW(self, dwReserved):220 del self.toolbar221 222 def ShowDW(self, bShow):223 if bShow:224 self.toolbar.ShowWindow(win32con.SW_SHOW)225 else:226 self.toolbar.ShowWindow(win32con.SW_HIDE)227 228 def on_first_button(self):229 print("first!")230 self.webbrowser.Navigate2("http://starship.python.net/crew/mhammond/")231 232 def on_second_button(self):233 print("second!")234 235 def on_third_button(self):236 print("third!")237 238 def toolbar_command_handler(self, args):239 hwnd, message, wparam, lparam, time, point = args240 if lparam == self.toolbar.GetSafeHwnd():241 self._command_map[wparam]()242 243 def SetSite(self, unknown):244 if unknown:245 # retrieve the parent window interface for this site246 olewindow = unknown.QueryInterface(pythoncom.IID_IOleWindow)247 # ask the window for its handle248 hwndparent = olewindow.GetWindow()249 250 # first get a command target251 cmdtarget = unknown.QueryInterface(axcontrol.IID_IOleCommandTarget)252 # then travel over to a service provider253 serviceprovider = cmdtarget.QueryInterface(pythoncom.IID_IServiceProvider)254 # finally ask for the internet explorer application, returned as a dispatch object255 self.webbrowser = win32com.client.Dispatch(256 serviceprovider.QueryService(257 "{0002DF05-0000-0000-C000-000000000046}", pythoncom.IID_IDispatch258 )259 )260 261 # now create and set up the toolbar262 self.toolbar = IEToolbarCtrl(hwndparent)263 264 buttons = [265 ("Visit PyWin32 Homepage", self.on_first_button),266 ("Another Button", self.on_second_button),267 ("Yet Another Button", self.on_third_button),268 ]269 270 self._command_map = {}271 # wrap our parent window so we can hook message handlers272 window = win32ui.CreateWindowFromHandle(hwndparent)273 274 # add the buttons275 for i in range(len(buttons)):276 button = TBBUTTON()277 name, func = buttons[i]278 id = 0x4444 + i279 button.iBitmap = -2280 button.idCommand = id281 button.fsState = commctrl.TBSTATE_ENABLED282 button.fsStyle = commctrl.TBSTYLE_BUTTON283 button.iString = name284 self._command_map[0x4444 + i] = func285 self.toolbar.AddButtons(button)286 window.HookMessage(self.toolbar_command_handler, win32con.WM_COMMAND)287 else:288 # lose all references289 self.webbrowser = None290 291 def GetClassID(self):292 return self._reg_clsid_293 294 def GetBandInfo(self, dwBandId, dwViewMode, dwMask):295 ptMinSize = (0, 24)296 ptMaxSize = (2000, 24)297 ptIntegral = (0, 0)298 ptActual = (2000, 24)299 wszTitle = "PyWin32 IE Toolbar"300 dwModeFlags = DBIMF_VARIABLEHEIGHT301 crBkgnd = 0302 return (303 ptMinSize,304 ptMaxSize,305 ptIntegral,306 ptActual,307 wszTitle,308 dwModeFlags,309 crBkgnd,310 )311 312 313# used for HKLM install314def DllInstall(bInstall, cmdLine):315 comclass = IEToolbar316 317 318# register plugin319def DllRegisterServer():320 comclass = IEToolbar321 322 # register toolbar with IE323 try:324 print("Trying to register Toolbar.\n")325 hkey = winreg.CreateKey(326 winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Internet Explorer\\Toolbar"327 )328 subKey = winreg.SetValueEx(329 hkey, comclass._reg_clsid_, 0, winreg.REG_BINARY, "\0"330 )331 except WindowsError:332 print(333 "Couldn't set registry value.\nhkey: %d\tCLSID: %s\n"334 % (hkey, comclass._reg_clsid_)335 )336 else:337 print(338 "Set registry value.\nhkey: %d\tCLSID: %s\n" % (hkey, comclass._reg_clsid_)339 )340 # TODO: implement reg settings for standard toolbar button341 342 343# unregister plugin344def DllUnregisterServer():345 comclass = IEToolbar346 347 # unregister toolbar from internet explorer348 try:349 print("Trying to unregister Toolbar.\n")350 hkey = winreg.CreateKey(351 winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Internet Explorer\\Toolbar"352 )353 winreg.DeleteValue(hkey, comclass._reg_clsid_)354 except WindowsError:355 print(356 "Couldn't delete registry value.\nhkey: %d\tCLSID: %s\n"357 % (hkey, comclass._reg_clsid_)358 )359 else:360 print("Deleting reg key succeeded.\n")361 362 363# entry point364if __name__ == "__main__":365 import win32com.server.register366 367 win32com.server.register.UseCommandLine(IEToolbar)368 369 # parse actual command line option370 if "--unregister" in sys.argv:371 DllUnregisterServer()372 else:373 DllRegisterServer()374else:375 # import trace utility for remote debugging376 import win32traceutil377 