iebutton.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # -*- coding: latin-1 -*-
  2. # PyWin32 Internet Explorer Button
  3. #
  4. # written by Leonard Ritter (paniq@gmx.net)
  5. # and Robert Förtsch (info@robert-foertsch.com)
  6. """
  7. This sample implements a simple IE Button COM server
  8. with access to the IWebBrowser2 interface.
  9. To demonstrate:
  10. * Execute this script to register the server.
  11. * Open Pythonwin's Tools -> Trace Collector Debugging Tool, so you can
  12. see the output of 'print' statements in this demo.
  13. * Open a new IE instance. The toolbar should have a new "scissors" icon,
  14. with tooltip text "IE Button" - this is our new button - click it.
  15. * Switch back to the Pythonwin window - you should see:
  16. IOleCommandTarget::Exec called.
  17. This is the button being clicked. Extending this to do something more
  18. useful is left as an exercise.
  19. Contribtions to this sample to make it a little "friendlier" welcome!
  20. """
  21. # imports section
  22. import sys, os
  23. from win32com import universal
  24. from win32com.client import gencache, DispatchWithEvents, Dispatch
  25. from win32com.client import constants, getevents
  26. import win32com.server.register
  27. import win32com
  28. import pythoncom
  29. import win32api
  30. # This demo uses 'print' - use win32traceutil to see it if we have no
  31. # console.
  32. try:
  33. win32api.GetConsoleTitle()
  34. except win32api.error:
  35. import win32traceutil
  36. from win32com.axcontrol import axcontrol
  37. import array, struct
  38. # ensure we know the ms internet controls typelib so we have access to IWebBrowser2 later on
  39. win32com.client.gencache.EnsureModule('{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}',0,1,1)
  40. #
  41. IObjectWithSite_methods = ['SetSite','GetSite']
  42. IOleCommandTarget_methods = ['Exec','QueryStatus']
  43. _iebutton_methods_ = IOleCommandTarget_methods + IObjectWithSite_methods
  44. _iebutton_com_interfaces_ = [
  45. axcontrol.IID_IOleCommandTarget,
  46. axcontrol.IID_IObjectWithSite, # IObjectWithSite
  47. ]
  48. class Stub:
  49. """
  50. this class serves as a method stub,
  51. outputting debug info whenever the object
  52. is being called.
  53. """
  54. def __init__(self,name):
  55. self.name = name
  56. def __call__(self,*args):
  57. print('STUB: ',self.name,args)
  58. class IEButton:
  59. """
  60. The actual COM server class
  61. """
  62. _com_interfaces_ = _iebutton_com_interfaces_
  63. _public_methods_ = _iebutton_methods_
  64. _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
  65. _button_text_ = 'IE Button'
  66. _tool_tip_ = 'An example implementation for an IE Button.'
  67. _icon_ = ''
  68. _hot_icon_ = ''
  69. def __init__( self ):
  70. # put stubs for non-implemented methods
  71. for method in self._public_methods_:
  72. if not hasattr(self,method):
  73. print('providing default stub for %s' % method)
  74. setattr(self,method,Stub(method))
  75. def QueryStatus (self, pguidCmdGroup, prgCmds, cmdtextf):
  76. # 'cmdtextf' is the 'cmdtextf' element from the OLECMDTEXT structure,
  77. # or None if a NULL pointer was passed.
  78. result = []
  79. for id, flags in prgCmds:
  80. flags |= axcontrol.OLECMDF_SUPPORTED | axcontrol.OLECMDF_ENABLED
  81. result.append((id, flags))
  82. if cmdtextf is None:
  83. cmdtext = None # must return None if nothing requested.
  84. # IE never seems to want any text - this code is here for
  85. # demo purposes only
  86. elif cmdtextf == axcontrol.OLECMDTEXTF_NAME:
  87. cmdtext = "IEButton Name"
  88. else:
  89. cmdtext = "IEButton State"
  90. return result, cmdtext
  91. def Exec(self, pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn):
  92. print(pguidCmdGroup, nCmdID, nCmdExecOpt, pvaIn)
  93. print("IOleCommandTarget::Exec called.")
  94. #self.webbrowser.ShowBrowserBar(GUID_IETOOLBAR, not is_ietoolbar_visible())
  95. def SetSite(self,unknown):
  96. if unknown:
  97. # first get a command target
  98. cmdtarget = unknown.QueryInterface(axcontrol.IID_IOleCommandTarget)
  99. # then travel over to a service provider
  100. serviceprovider = cmdtarget.QueryInterface(pythoncom.IID_IServiceProvider)
  101. # finally ask for the internet explorer application, returned as a dispatch object
  102. self.webbrowser = win32com.client.Dispatch(serviceprovider.QueryService('{0002DF05-0000-0000-C000-000000000046}',pythoncom.IID_IDispatch))
  103. else:
  104. # lose all references
  105. self.webbrowser = None
  106. def GetClassID(self):
  107. return self._reg_clsid_
  108. def register(classobj):
  109. import winreg
  110. subKeyCLSID = "SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\%38s" % classobj._reg_clsid_
  111. try:
  112. hKey = winreg.CreateKey( winreg.HKEY_LOCAL_MACHINE, subKeyCLSID )
  113. subKey = winreg.SetValueEx( hKey, "ButtonText", 0, winreg.REG_SZ, classobj._button_text_ )
  114. winreg.SetValueEx( hKey, "ClsidExtension", 0, winreg.REG_SZ, classobj._reg_clsid_ ) # reg value for calling COM object
  115. winreg.SetValueEx( hKey, "CLSID", 0, winreg.REG_SZ, "{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}" ) # CLSID for button that sends command to COM object
  116. winreg.SetValueEx( hKey, "Default Visible", 0, winreg.REG_SZ, "Yes" )
  117. winreg.SetValueEx( hKey, "ToolTip", 0, winreg.REG_SZ, classobj._tool_tip_ )
  118. winreg.SetValueEx( hKey, "Icon", 0, winreg.REG_SZ, classobj._icon_)
  119. winreg.SetValueEx( hKey, "HotIcon", 0, winreg.REG_SZ, classobj._hot_icon_)
  120. except WindowsError:
  121. print("Couldn't set standard toolbar reg keys.")
  122. else:
  123. print("Set standard toolbar reg keys.")
  124. def unregister(classobj):
  125. import winreg
  126. subKeyCLSID = "SOFTWARE\\Microsoft\\Internet Explorer\\Extensions\\%38s" % classobj._reg_clsid_
  127. try:
  128. hKey = winreg.CreateKey( winreg.HKEY_LOCAL_MACHINE, subKeyCLSID )
  129. subKey = winreg.DeleteValue( hKey, "ButtonText" )
  130. winreg.DeleteValue( hKey, "ClsidExtension" ) # for calling COM object
  131. winreg.DeleteValue( hKey, "CLSID" )
  132. winreg.DeleteValue( hKey, "Default Visible" )
  133. winreg.DeleteValue( hKey, "ToolTip" )
  134. winreg.DeleteValue( hKey, "Icon" )
  135. winreg.DeleteValue( hKey, "HotIcon" )
  136. winreg.DeleteKey( winreg.HKEY_LOCAL_MACHINE, subKeyCLSID )
  137. except WindowsError:
  138. print("Couldn't delete Standard toolbar regkey.")
  139. else:
  140. print("Deleted Standard toolbar regkey.")
  141. #
  142. # test implementation
  143. #
  144. class PyWin32InternetExplorerButton(IEButton):
  145. _reg_clsid_ = "{104B66A9-9E68-49D1-A3F5-94754BE9E0E6}"
  146. _reg_progid_ = "PyWin32.IEButton"
  147. _reg_desc_ = 'Test Button'
  148. _button_text_ = 'IE Button'
  149. _tool_tip_ = 'An example implementation for an IE Button.'
  150. _icon_ = ''
  151. _hot_icon_ = _icon_
  152. def DllRegisterServer():
  153. register(PyWin32InternetExplorerButton)
  154. def DllUnregisterServer():
  155. unregister(PyWin32InternetExplorerButton)
  156. if __name__ == '__main__':
  157. win32com.server.register.UseCommandLine(PyWin32InternetExplorerButton,
  158. finalize_register = DllRegisterServer,
  159. finalize_unregister = DllUnregisterServer)