When hosting an ATL HTML control, ATL creates a host window and uses the
IAxWinAmbientDispatch interface to allow you to override ATL's default implementation of the
IDocHostUIHandler interface.
IAxWinAmbientDispatch exposes properties that you can use to control the host behavior, such as allowing context menus, setting default host flags, and so on.
There are two ways to control the context menu behavior in an ATL HTML control:
- Cancel the default context menu.
- Display a custom context menu.
Cancel the Default Context Menu
To turn off context menus, perform the following steps:
- Use the IAxWinAmbientDispatch::put_AllowContextMenu method to set the m_bAllowContextMenu property to true.
- In the control's OnCreate method that the ATL Wizard generated, add the following code:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CAxWindow wnd(m_hWnd);
HRESULT hr = wnd.CreateControl(IDH_BRHTMLCTRL);
if (SUCCEEDED(hr))
hr = wnd.SetExternalDispatch(static_cast<IBRHtmlCtrlUI*>(this));
CComPtr<IUnknown> spUnk; //**ADDED**
AtlAxGetHost(m_hWnd, &spUnk); //**ADDED**
CComQIPtr<IAxWinAmbientDispatch> spWinAmb(spUnk); //**ADDED**
spWinAmb->put_AllowContextMenu(VARIANT_FALSE); //**ADDED**
if (SUCCEEDED(hr))
hr = wnd.QueryControl(IID_IWebBrowser2, (void**)&m_spBrowser);
return SUCCEEDED(hr) ? 0 : -1;
}
Display a Custom Context Menu
If you want to display your own custom context menu, you must use the
SetExternalUIHandler function of the
CAxWindow class to override the default implementation of
IDocHostUIHandler.
This method accepts a
IDocHostUIHandlerDispatch pointer instead of a
IDocHostUIHandler pointer. The
IDocHostUIHandlerDispatch interface is defined in the ATL header file (Atliface.h) and has the exact same methods. The parameters of some of these methods differ slightly from
IDocHostUIHandler in that they use Automation-compatible types. To implement
IDocHostUIHandlerDispatch, perform the following steps:
- In the derivation list for your control class, add IDocHostUIHandlerDispatch as follows:
NOTE: Before you add this line of code, make sure that you type a comma at the end of your derivation list.
public IDispatchImpl<IDocHostUIHandlerDispatch, &IID_IDocHostUIHandlerDispatch, &LIBID_ATLLib>
Instead of implementing all of the IDispatch methods, we can use the IDispatchImpl class. - Add your interface to the COM interface map as follows:
COM_INTERFACE_ENTRY(IDocHostUIHandlerDispatch)
- Implement all of the methods for IDocHostUIHandlerDispatch. You can copy the function headers from Atliface.h and safely return E_NOTIMPL for methods that you are not interested in.
- In the OnCreate method that the ATL Wizard generated, set the external handler as follows:
hr = wnd.SetExternalUIHandler(static_cast<IDocHostUIHandlerDispatch*>(this));
- To cancel the context menu, add the following code in your IDocHostUIHandlerDispatch::ShowContextMenu implementation:
*dwRetVal = S_OK; //This is what the WebBrowser control is looking for.
//You can show your own context menu here.
return S_OK;