Microsoft KB Archive/192501

= FIX: IDocHostUIHandler Not Queried for CLSID_WebBrowser_V1 =

Article ID: 192501

Article Last Modified on 5/11/2006

-

APPLIES TO


 * Microsoft Internet Explorer 4.0 128-Bit Edition
 * Microsoft Internet Explorer 4.01 Service Pack 2
 * Microsoft Internet Explorer 4.01 Service Pack 1
 * Microsoft Internet Explorer 5.0

-



This article was previously published under Q192501



SYMPTOMS
When hosting the Internet Explorer WebBrowser control, the host application can control the user interface by implementing the IDocHostUIHandler interface. This interface is obtained by Internet Explorer from the host's client site and allows the host to replace menus, toolbars and context menus.

If the WebBrowser control is instantiated using the CLSID_WebBrowser_V1 class identifier, the host is not queried for the IDocHostUIHandler interface.



RESOLUTION
If possible, create the WebBrowser control using the CLSID_WebBrowser class identifier. The Internet Explorer 3.0x automation and event interfaces are available from this object, but are not marked as default.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article. This bug was corrected in Internet Explorer 5.



CLSID_WebBrowser and CLSID_WebBrowser_V1 Differences
The WebBrowser control can be created using either the CLSID_WebBrowser or CLSID_WebBrowser_V1 class identifier and supports both the Internet Explorer 3.0x and 4.0x interfaces. The latter provides a mode compatible with Internet Explorer 3.0x by exposing those interfaces as default:   Class ID             Default Interface  Default Event Interface -   -  ---   CLSID_WebBrowser     IWebBrowser2       DWebBrowserEvents2 CLSID_WebBrowser_V1 IWebBrowser        DWebBrowserEvents

Replacing the Context Menu
If you are implementing the IDocHostUIHandler interface to replace the Internet Explorer context menu, and the host application is using the Microsoft Foundation Classes (MFC), you can override the default CWinApp implementation of PreTranslateMessage as follows.

Use this code in your CWinApp-derived class: BOOL CMyApp::PreTranslateMessage(MSG* pMsg) {

if ( WM_RBUTTONDOWN  == pMsg->message        || WM_RBUTTONDBLCLK == pMsg->message ) {        // Received right-click (dbl) CWnd* pFrame = AfxGetMainWnd;

CMyView* pView = ((CMyView*)((CFrameWnd*)pFrame)->GetActiveView);

if ( pView->IsWebBrowser( pMsg->hwnd ) ) {           // The WebBrowser control was clicked pView->DoContextMenu; return TRUE; }     }      return CWinApp::PreTranslateMessage(pMsg);

} Use this code in the MFC view class that hosts the WebBrowser control: void CMyView::DoContextMenu {     CMenu  Menu; CMenu* pPopup = NULL; POINT pt;

DWORD pos = GetMessagePos; pt.x = LOWORD(pos); pt.y = HIWORD(pos);

Menu.LoadMenu( IDR_MAINFRAME );  // Your menu here. pPopup = Menu.GetSubMenu( 0 ); if ( pPopup ) {        pPopup->TrackPopupMenu( TPM_LEFTALIGN|TPM_RIGHTBUTTON,                                 pt.x, pt.y, this ); pPopup->DestroyMenu; Menu.DestroyMenu; }

}

static TCHAR gszIEClass[] = "Internet Explorer_Server";

// Checks if message window is WebBrowser control. // Also works with nested frames. BOOL CMyView::IsWebBrowser(HWND hWnd) {     HWND hWndWBOC = (HWND)m_Browser.GetSafeHwnd; HWND hWndParent;

hWndParent = GetParentWBOC( hWnd );

while ( hWndParent != hWndWBOC          && hWndParent != NULL ) {        hWndParent = GetParentWBOC( ::GetParent( hWndParent ) ); }

return (hWndParent != NULL);

}

HWND CMyView::GetParentWBOC(HWND hWnd) {

TCHAR  szClass[sizeof(gszIEClass)+1]; HWND  hWndParent;



if ( 0 == _tcscmp( szClass, gszIEClass ) ) {        // InternetExplorer_Server hWndParent = ::GetParent( hWnd );  // Shell DocObject View return ::GetParent( hWndParent );  // Shell Embedding }     else {        return NULL; }

}

