Obtaining the HWND for the WebBrowser control (244310)



The information in this article applies to:

  • Microsoft Internet Explorer (Programming) 4.0
  • Microsoft Internet Explorer (Programming) 4.01
  • Microsoft Internet Explorer (Programming) 4.01 SP1
  • Microsoft Internet Explorer (Programming) 4.01 SP2
  • Microsoft Internet Explorer (Programming) 5

This article was previously published under Q244310

SYMPTOMS

Hosting the WebBrowser control in either a Visual Basic or Visual C++ application and calling its HWND property usually returns the following HRESULT of E_FAIL:
Method HWND of IWebBrowser2 failed.

CAUSE

The HWND property is not a valid property of the WebBrowser control.

RESOLUTION

WARNING: These techniques may not work for frame windows in future versions of Internet Explorer after 5.01. The advice that follows is only guaranteed to work for the top-level WebBrowser control.

Visual C++ developers can use the IOleWindow interface of the WebBrowser control and call its GetWindow() method to retrieve the WebBrowser's HWND:
IOleWindow *pOWin;
HWND hBWnd;

HRESULT hRes = m_pBrowserApp->QueryInterface(IID_IOleWindow, (void **)&pOWin);
if (SUCCEEDED(hRes)) {
    hRes = pOWin->GetWindow(&hBWnd);
    if (SUCCEEDED(hRes)) {
        // Place hBWnd-manipulating code here
    }
}	
				

Visual Basic developers can use the following code, which takes the HWND of the hosting form and examines all its children until it finds the window with a window class of "Shell Embedding". This is the topmost window of the WebBrowser control.

CAUTION: The Internet Explorer window class name may change in future browser versions. Use this workaround with care.
   Option Explicit

   Public Const GW_HWNDNEXT = 2
   Public Const GW_CHILD = 5
   Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
   Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

Public Function GetBrowserWindow(hwndBrowserContainer As Long) As Long
    Dim RetVal As Long
    Dim Result As Long
    Dim hwndPeer As Long
    Dim ClassString As String * 256
     
      
    hwndPeer = GetWindow(hwndBrowserContainer, GW_CHILD)
    While (Result = 0) And (hwndPeer <> 0)
        hwndPeer = GetWindow(hwndPeer, GW_HWNDNEXT)
        RetVal = GetClassName(hwndPeer, ClassString, 256)
        If hwndPeer <> 0 Then
            RetVal = GetClassName(hwndPeer, ClassString, 256)
            If Left$(ClassString, InStr(ClassString, Chr$(0)) - 1) = "Shell Embedding" Then
                Result = 1
            End If
        End If
    Wend
                
    GetBrowserWindow = hwndPeer
End Function
				
Please note that neither of these techniques are needed when you automate Internet Explorer. For automation, C++ and Visual Basic users can both use the HWND property of the InternetExplorer object.

STATUS

This behavior is by design.

Modification Type:MajorLast Reviewed:12/29/2004
Keywords:kbprb kbWebBrowser KB244310