Eternal Windowsの次の記事のC++コードをpythonに変換しようと思いました。
http://eternalwindows.jp/browser/mshtml/mshtml07.html
これでコンパイルを通すところまではできましたが、ボタンクリックしてもメッセージを出してくれない。。。 うーむ。
この方式は、一旦、諦めるか。
ただ、少なくともIHTMLDocument3やIHTMLDocument2を使えるようになった効果は大きい!
### iecontrol4.py ### __author__ = "w.y" __version__ = "0.0.0.4" # Win32モジュール import win32gui from comtypes.gen.MSHTML import IHTMLWindow2,IHTMLDocument2,IHTMLDocument3,IHTMLElement from comtypes.gen.MSHTML import BSTR,IDispatch from comtypes.automation import VARIANT,VT_DISPATCH from ctypes import windll,c_ulong,byref,POINTER from time import sleep class __clsIETabs(object): lsHandle = [] lsHandlePrev = [] lsTitle = [] lsTitlePrev = [] lsUrl = [] lsUrlPrev = [] lsHandleChange = [] lsHandleClose = [] def setHandle(self, value): self.lsHandle.append(value) return True def removeHandle(self, value): self.lsHandle.remove(value) return True def setTitle(self, value): self.lsTitle.append(value) return True def setUrl(self, value): self.lsUrl.append(value) return True def resetIETabs(self): self.lsHandlePrev.clear() self.lsTitlePrev.clear() self.lsUrlPrev.clear() for index, handle in enumerate(self.lsHandle): self.lsHandlePrev.append(handle); self.lsTitlePrev.append(self.lsTitle[index]); self.lsUrlPrev.append(self.lsUrl[index]); self.lsHandle.clear() self.lsTitle.clear() self.lsUrl.clear() return True def getIETabsChange(self): self.lsHandleChange.clear() for indexNow, hWndNow in enumerate(self.lsHandle) : flChange = True for indexPrev,hWndPrev in enumerate(self.lsHandlePrev) : if ((hWndNow == hWndPrev) and (self.lsTitle[indexNow] == self.lsTitlePrev[indexPrev]) and (self.lsUrl[indexNow] == self.lsUrlPrev[indexPrev])): flChange = False if flChange : self.lsHandleChange.append(hWndNow) return self.lsHandleChange def getIETabsClose(self): self.lsHandleClose.clear() self.lsHandleClose = list(set(self.lsHandlePrev)-set(self.lsHandle)) return self.lsHandleClose def __checkIETab(hWnd,IETabs): if (win32gui.GetClassName(hWnd) == 'Internet Explorer_Server'): #print(str(hWnd)+' : '+win32gui.GetClassName(hWnd)+' : '+win32gui.GetWindowText(hWnd)) IETabs.setHandle(hWnd); class clsEventHandler(IDispatch): m_pWin2 = POINTER(IHTMLWindow2)() def __init__(self,pWin2): super().__init__() m_pWin2 = pWin2 windll.user32.MessageBoxW(None, u'生成されました!', u'メッセージボックス!', 0x00000040) def _IDispatch__com_Invoke(): super()._IDispatch__com_Invoke() print('ボタンが押されましたっ!') windll.user32.MessageBoxW(None, u'メッセージぼっくす!', u'メッセージボックス!', 0x00000040) def _Invoke(): super()._Invoke() print('ボタンが押されましたっ!') windll.user32.MessageBoxW(None, u'メッセージぼっくす!', u'メッセージボックス!', 0x00000040) def _invoke(): super()._invoke() print('ボタンが押されましたっ!') windll.user32.MessageBoxW(None, u'メッセージぼっくす!', u'メッセージボックス!', 0x00000040) def Invoke(): super().Invoke() print('ボタンが押されましたっ!') windll.user32.MessageBoxW(None, u'メッセージぼっくす!', u'メッセージボックス!', 0x00000040) def run(): #初期化:IEタブのクラスを生成、無限ループフラグをセット IETabs = __clsIETabs() flContinue = True user32 = windll.user32 #無限ループIEタブを監視 while(flContinue): #古いIEタブリストの削除 IETabs.resetIETabs() #IEタブリスト(ウインドウハンドル)の取得 win32gui.EnumChildWindows(win32gui.FindWindow(u'IEFrame',None),lambda hWnd, _: __checkIETab(hWnd,IETabs), None) #IEタブリスト(タイトルとUrl)の取得 uMsg = user32.RegisterWindowMessageW(u'WM_HTML_GETOBJECT') for hIETab in IETabs.lsHandle: try : lRes2 = c_ulong(0) pLRes2 = byref(lRes2) user32.SendMessageTimeoutW(hWnd, uMsg, 0, 0,2, 1000, pLRes2) # 2 == SMTO_ABORTIFHUNG pDoc2 = POINTER(IHTMLDocument2)() windll.oleacc.ObjectFromLresult(lRes2, IHTMLDocument2._iid_, 0, byref(pDoc2)) IETabs.setTitle(pDoc2.title) IETabs.setUrl(pDoc2.url) except : IETabs.setTitle('no title') IETabs.setUrl('no url') print('IETabError!') #変化したIEタブ、閉じたIEタブの検出 print('Change : ',IETabs.getIETabsChange()) for hWnd in IETabs.getIETabsChange(): # タイトル/URL/エレメントの取得 lRes2 = c_ulong(0) pLRes2 = byref(lRes2) user32.SendMessageTimeoutW(hWnd, uMsg, 0, 0,2, 1000, pLRes2) # 2 == SMTO_ABORTIFHUNG pDoc2 = POINTER(IHTMLDocument2)() windll.oleacc.ObjectFromLresult(lRes2, IHTMLDocument2._iid_, 0, byref(pDoc2)) lRes3 = c_ulong(0) pLRes3 = byref(lRes3) user32.SendMessageTimeoutW(hWnd, uMsg, 0, 0,2, 1000, pLRes3) # 2 == SMTO_ABORTIFHUNG pDoc3 = POINTER(IHTMLDocument3)() windll.oleacc.ObjectFromLresult(lRes3, IHTMLDocument3._iid_, 0, byref(pDoc3)) pElementItem01 = POINTER(IHTMLElement)() pElementItem02 = POINTER(IHTMLElement)() strBstr = BSTR() pDoc3._IHTMLDocument3__com_getElementById('btn01',byref(pElementItem01)) pDoc3._IHTMLDocument3__com_getElementById('str_Value009',byref(pElementItem02)) #pElementItem02._IHTMLElement__com__get_innerHTML(byref(strBstr)) #print(strBstr) pWin2 = POINTER(IHTMLWindow2)() pDoc2._IHTMLDocument2__com__get_parentWindow(byref(pWin2)); var = VARIANT() var.vt = VT_DISPATCH; var.pdispVal = clsEventHandler(byref(pWin2)); try: pElementItem01._IHTMLElement__com__set_onclick(var); pElementItem02._IHTMLElement__com__set_onclick(var); print('set!') except: print('except!') print('Close : ',IETabs.getIETabsClose()) sleep(1) if __name__ == '__main__': run()
でも、ここまで良くやったと思う。大幅なレベルアップ!