In a recent small project, to develop a plug-in, you need to perform operations on the webpage content of a third-party system. The operation content is still complicated. Naturally, you choose to use BHO.
Half of them are stuck because the website has a showmodal mode window, which needs to be controlled as well.
However, I have searched the Dom and IE interfaces and have not found anything that can control or capture the content in the pop-up window.
Although you can rewrite the code of the pop-up window, use window instead. the open dialog box is displayed and captured again. However, because the pop-up window of the Website still contains complicated parameters, it is not convenient to switch, so the Code cannot be changed.
Since I cannot start with IE, I can only change the direction and start with Windows window. because the pop-up window is also a window, you can capture the pop-up window handle, traverse the webbrowser control handle, and convert it to the Document Object. the document object can be used to control the webpage at will.
The key code is as follows:
Lower hooks in the 'bho class = setwindowshookex (hooktype. wh_callwndprocret, addressof modcallback. callwndretproc, 0, cscript "btnrenewcard ()", "jscript"
In this case, callwndretproc in the standard module starts to work. The Code is as follows (the department code is omitted ):
Public Function CallWndRetProc(ByVal code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long On Error GoTo ErrorLine Dim hwnd As Long Dim script As MSHTML.HTMLScriptElement If code <> 0 Then CallWndRetProc = CallNextHookEx(hWndRetProcHook, code, wParam, lParam) Exit Function End If CopyMemory hCWPRETSTRUCT, ByVal lParam, LenB(hCWPRETSTRUCT)
If hCWPRETSTRUCT.Message = WM_PARENTNOTIFY Then Debug.Print hCWPRETSTRUCT.wParam, hCWPRETSTRUCT.hwnd If hCWPRETSTRUCT.wParam = WM_CREATE Then EnumChildWindows hCWPRETSTRUCT.hwnd, AddressOf EnumChildProc, hwnd
'Note that the following code is annotated and has been deleted in the actual project. Here, we will only demonstrate the code. I will explain why to comment it out later. 'If hwnd = 0 then' msgbox "failed to get the browser information. Please try again. ", vbexclamation 'exit function' end if
'Set newhtmldom = iedomfromhwnd (hwnd) 'if not (newhtmldom is nothing) then' set script = newhtmldom. createelement ("script") 'script. TEXT = "Var getcardscript = function () {" & vbcrlf & _ '"getscrapcardscript (); "& vbcrlf & _ '"} "& vbcrlf & _'" Var refreshcard = function () {"& vbcrlf & _ '" If (haserrmsg ()) {"& vbcrlf & _ '" return; "& vbcrlf & _'"} "& vbcrlf & _ '" writeflag = true; "& vbcrlf & _ '" Var noticeinfo = {}; "& vbcrlf & _ '" // set the specific error message when the comments field is delivered "& vbcrlf & _'" If (writeflag = true) {"& vbcrlf & _ '" noticeinfo. result = "" 1 ""; "& vbcrlf & _ '" // noticeinfo. comments = "" succeeded ""; "& vbcrlf & _ '"} "& vbcrlf & _'" else {"& vbcrlf & _ '" noticeinfo. result = "" 2 ""; "& vbcrlf & _ '" noticeinfo. errorcode = writeflag; "& vbcrlf & _ '" // noticeinfo. comments = "" failed ""; "& vbcrlf & _ '"} "& vbcrlf & _'" addbizstate ("" noticeinfo "", noticeinfo ); "& vbcrlf & _ '" scrapcardreturnnotice (); "& vbcrlf & _'"} "'script. language = "JavaScript" ''debug. print instr (0, "authkey", htmldom. scripts (5 ). text, vbtextcompare) 'while newhtmldom. readystate <> "complete" 'doevents' wend' newhtmldom. body. appendchild script 'else' msgbox "failed to get the browsing object. ", vbexclamation 'end if 'unhookwindowshookex else end if callwndretproc = callnexthookex (response, code, wparam, lparam) Exit functionerrorline: msgbox" An exception occurs. "& err. description, vbcritical callwndretproc = callnexthookex (hwndretprochook, code, wparam, lparam) end Function
The showmodal method of IE will generate the wm_parentnotify message and wm_create message in the pop-up window, so only the two messages are monitored. after the pop-up window is monitored, use enumchildwindows to traverse all the sub-windows in the pop-up window to get the webbrowser handle. in the above code, we can see that enumchildwindows has a large part of annotation code.
My original intention was to use the last parameter of enumchildwindows to output the webbrowser handle found by the enumwindowproc sub-program. I named this parameter byref. this code runs normally under my win7 and outputs a webbrowser handle. however, when the project is completed and moved to Windows XP for testing, the processed data cannot be output. this parameter is not specified in msdn and can only be input or output! In addition, I am running quite correctly in win7, and I cannot explain it.
At first, I thought it was a problem with the user32.dll version. I copied this file from win7 to the DLL and IE root directories of XP. the problem still exists, so I had no choice but to cancel using enumchildwindows to return a handle, it is processed in the enumwindowproc sub-program, so the above Code is commented.
In addition, I noticed that in the above code, the code for canceling the hook is commented on separately. My intention is to unhook the webbrowser control after obtaining it, this code runs quite well in win7, but it won't work if it is switched to XP. So I also commented on this line of code and changed it to unhook.
The following is the enumwindowproc sub-program.
Function EnumChildProc(ByVal hwnd As Long, ByRef lParam As Long) As Long Dim script As MSHTML.HTMLScriptElement If IsIEServerWindow(hwnd) Then lParam = hwnd
'After finding the handle, convert the handle to the Document Object. Set newhtmldom = iedomfromhwnd (hwnd) if not (newhtmldom is nothing) then set script = newhtmldom. createelement ("script ")
'Rewrite the code in the webpage below.
Script. TEXT = "Var getcardscript = function () {" & vbcrlf & _ "getscrapcardscript ();" & vbcrlf & _ "}" & vbcrlf & _ "Var refreshcard = function () {"& vbcrlf & _" If (haserrmsg () {"& vbcrlf & _" return; "& vbcrlf & _"} "& vbcrlf & _" writeflag = true; "& vbcrlf & _" Var noticeinfo = {}; "& vbcrlf & _" // error message set when the comments field is delivered "& vbcrlf & _" If (writeflag = true) {"& vbcrlf & _" noticeinfo. result = "" 1 ""; "& vbcrlf & _" // noticeinfo. comments = "" succeeded ""; "& vbcrlf & _"} "& vbcrlf & _" else {"& vbcrlf & _" noticeinfo. result = "" 2 ""; "& vbcrlf & _" noticeinfo. errorcode = writeflag; "& vbcrlf & _" // noticeinfo. comments = "" failed ""; "& vbcrlf & _"} "& vbcrlf & _" addbizstate ("" noticeinfo "", noticeinfo ); "& vbcrlf & _" scrapcardreturnnotice (); "& vbcrlf & _"} "script. language = "JavaScript" 'debug. print instr (0, "authkey", htmldom. scripts (5 ). text, vbtextcompare)
'The following section is indispensable. because obtaining the handle and Document Object is quite short, the webpage is not fully loaded and the Code cannot be rewritten. Therefore, you must wait until the webpage is loaded and then rewrite the Page code. while newhtmldom. readystate <> "complete" doevents Wend newhtmldom. body. appendchild script else msgbox "failed to get the browsing object. ", vbexclamation end if enumchildproc = 0 else enumchildproc = 1 end ifend Function
The following describes how to convert a handle to a document object.
'Determine whether the browser control is used
Function isieserverwindow (byval hwnd as long) as Boolean 'determines whether it is a browser control dim lres as long dim sclassname as string sclassname = string (100, 0) lres = getclassname (hwnd, sclassname, len (sclassname) sclassname = left (sclassname, lres) isieserverwindow = strcomp (sclassname, "Internet assumer_server", vbtextcompare) = 0end functionfunction callback (byref hwnd as long) as ihtmldocument 'get the DOM object dim iid_ihtmldocument as olelib through the handle. UUID dim hwndchild as longdim lres as longdim lmsg as longdim HR as longset kernel = nothingif hwnd <> 0 then' if not isieserverwindow (hwnd) Then 'enumchildwindows hwnd, addressof Kernel, hwnd 'end if isieserverwindow (hwnd) then' registers the message lmsg = registerwindowmessage ("wm_html_getobject") 'sends the message sendmessagetimeout hwnd, lmsg, 0, 0, smto_abortifhung, 1000, lres 'msgbox "lres" & lres if lres then with iid_ihtmldocument. data1 = & h626fc520 'encoding. data2 = & ha41e. data3 = & h11cf. data4 (0) = & ha7. data4 (1) = & h31. data4 (2) = & H0. data4 (3) = & ha0. data4 (4) = & hc9. data4 (5) = & H8. data4 (6) = & h26. data4 (7) = & h37 end
hr = ObjectFromLresult(lRes, IID_IHTMLDocument, 0, IEDOMFromhWnd) 'MsgBox "HR:" & hr End If End IfEnd IfEnd Function
The document object obtained by using the active accessibility component.
The above code completes the control of the IE pop-up Module window. some of the differences between API calls in Windows 7 and XP have led me to take some detours. I still don't understand how these differences are produced. I hope people who know the truth can give me some advice.