FIX: IDocHostUIHandler Not Queried for CLSID_WebBrowser_V1
ID: Q192501
|
The information in this article applies to:
-
Microsoft Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 5
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 this to be a bug in the Microsoft products listed
at the beginning of this article.
This bug was corrected in Internet Explorer 5.
MORE INFORMATION
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;
::GetClassName( hWnd, szClass, sizeof(szClass) );
if ( 0 == _tcscmp( szClass, gszIEClass ) )
{
// InternetExplorer_Server
hWndParent = ::GetParent( hWnd ); // Shell DocObject View
return ::GetParent( hWndParent ); // Shell Embedding
}
else
{
return NULL;
}
}
REFERENCES
For more information, please see the MSDN Web Workshop:
http://msdn.microsoft.com/workshop/default.asp
(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Mark Davis, Microsoft Corporation.
Additional query words:
kbWebBrowser kbIE401sp1bug kbIE401bug kbIE400bug kbIE500dp1fix
Keywords : kbcode kbIE400bug kbIE401bug kbWebBrowser kbIE401sp1bug kbIE500fix kbDSupport
Version : WINDOWS:4.0,4.01,4.01 SP1,5
Platform : WINDOWS
Issue type : kbbug