• Welcome to Jose's Read Only Forum 2023.
 

How to get IHTMLDocument2 from a HWND

Started by José Roca, August 29, 2011, 12:12:24 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca


Adapted from the Microsoft Knowledge Base article of the same name: http://support.microsoft.com/kb/249232

This article shows how to get the IHTMLDocument2 interface from a HWND. If Microsoft Active Accessibility (MSAA) is installed, you can send the WM_HTML_GETOBJECT message to the document's window (with the window class "Internet Explorer_Server") and then pass the result from SendMessageTimeout to an MSAA function, ObjectFromLresult, to get a fully marshaled IHTMLDocument2 pointer.

NOTE: Before Internet Explorer 5.5, frames were implemented by hosting a new instance of Shdocvw.dll, and each frame had a separate window associated with it. Internet Explorer 5.5 implements native frames for better performance, and all frames are rendered by the same instance of Shdocvw.dll. Since there will not be a HWND for each frame for Internet Explorer 5.5 and later, the sample code described in this section will work to get to the document of the main window only. You can still get to each frame's document by using the frames collection of the main document.


' ########################################################################################
' Adapted from the following Microsoft Knowledge Base article: http://support.microsoft.com/kb/249232
' Demonstrates how to get the IHTMLDocument2 interface from a HWND. If Microsoft Active
' Accessibility (MSAA) is installed, you can send the WM_HTML_GETOBJECT message to the
' document's window (with the window class "Internet Explorer_Server") and then pass the
' result from SendMessageTimeout to an MSAA function, ObjectFromLresult, to get a fully
' marshaled IHTMLDocument2 pointer.
' ########################################################################################

' CSED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
%UNICODE = 1

#INCLUDE "OLEACC.INC"   ' // Accessibility
#INCLUDE "EXDISP.INC"   ' // WebBrowser Control
#INCLUDE "MSHTML.INC"   ' // MSHTML

' ========================================================================================
' Callback for EnumChildWindows
' ========================================================================================
FUNCTION EnumChildProc(BYVAL hwnd AS DWORD, BYVAL lParam AS DWORD PTR) AS LONG

   LOCAL wszClassName AS WSTRINGZ * %MAX_PATH
   GetClassName(hwnd, wszClassName, %MAX_PATH)
   IF wszClassName = "Internet Explorer_Server" THEN
      IF lParam <> %NULL THEN @lParam = hWnd
      FUNCTION = %FALSE
   ELSE
      FUNCTION = %TRUE
   END IF

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN () AS LONG

   LOCAL hr AS LONG                              ' // HRESULT
   LOCAL hWndExplorer AS DWORD                   ' // Internet Explorer handle
   LOCAL hWndChild AS DWORD                      ' // Child window handle
   LOCAL dwMsg AS DWORD                          ' // Message to send
   LOCAL lRes AS DWORD                           ' // Result of the message processing
   LOCAL pIHTMLDocument2 AS IHTMLDocument2       ' // IHTMLDocument2 interface pointer

   ' // Find the window handle of a running instance of Internet Explorer
   hWndExplorer = FindWindow("IEFrame", BYVAL %NULL)
   IF ISFALSE hWndExplorer THEN
      MSGBOX "Internet Explorer isn't running"
      EXIT FUNCTION
   END IF

   ' // Enumerate its child windows
   EnumChildWindows hWndExplorer, CODEPTR(EnumChildProc), VARPTR(hWndChild)
   IF ISFALSE hWndChild THEN EXIT FUNCTION

   ' // Register the WM_HTML_GETOBJECT message
   dwMsg = RegisterWindowMessage("WM_HTML_GETOBJECT")
   IF ISFALSE dwMsg THEN EXIT FUNCTION

   ' // Send a mensage to get an LRESULT
   SendMessageTimeout hWndChild, dwMsg, 0, 0, %SMTO_ABORTIFHUNG, 1000, lRes
   IF ISFALSE lRes THEN EXIT FUNCTION

   ' // Retrieve a reference to the IHTMLDocument2 interface from the LRESULT
   hr = ObjectFromLresult(lRes, $IID_IHTMLDocument2, 0, pIHTMLDocument2)
   IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION

   ' // Change the background color of the document to red
   pIHTMLDocument2.bgColor = "red"

   ' // Cleanup
   pIHTMLDocument2 = NOTHING
   MSGBOX "Web page background color changed to red"

END FUNCTION
' ========================================================================================