Hello,
Thanks for providing this forum to ask questions for MS technicians who know the inside of IE.
I have a BHO that shows some context menu items with the default IE items together. The approach was from an article on MSDN http://msdn.microsoft.com/library/default.asp url=/workshop/browser/hosting/wbcustomization.asp
The approach is good for only one BHO to add context menu items. But if more than two BHOs are existing, this approach seems not working.
Is there any good solution for this problem

Is it possible to let multiple BHOs add their own context menu items?
jeka804
There's no problem having multiple BHOs adding multiple menu items.
Are you sure you're using different GUIDs for your BHOs Most likely one of them is not registered correctly.
Troels
Steve_j_maas
SelArom
The short answer: do not use IDocHostUIHandler from a BHO to replace the standard context menu. You will invariably override other BHOs and possibly expose options that are supposed to be locked down by GPO.
The next best thing: register a custom menu extension that calls a method in a class that you implement. Unfortunately, you cannot design flyout menus or specify menu icons with this approach.
See http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1426354&SiteID=1
xRuntime
I don't see how this is possible.
The sample code shows the menu loaded from SHDOCLC.DLL and then modified.
This means each BHO would load the base IE menu, modify it and display it.
Therefore with multiple BHOs the last one to have ShowContextMenu would win.
In order for this to work there would have to be some kind of chaining mechanism available.
Perhaps one where ShowContextMenu(...) passes in the current hMenu.
Then the handlers can just append to it.
KjellSJ
Troels,
Thanks for your comment. I am sure that each BHO has a different GUID and BHOs are registered properly. If you ever implemented BHOs and let them work together with different context menu items, please share your sample code here.
Here is my sample code without error handling.
STDMETHODIMP CBho::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispReserved)
{
HRESULT hr = S_FALSE;
CComPtr<IOleCommandTarget> spCT;
hr = pcmdTarget->QueryInterface(IID_IOleCommandTarget, (void**)&spCT);
CComPtr<IOleWindow> spWnd;
hr = pcmdTarget->QueryInterface(IID_IOleWindow, (void**)&spWnd);
hr = spWnd->GetWindow(&m_hDocWnd);
HINSTANCE hiSHDOCLC = LoadLibrary(_T("SHDOCLC.DLL"));
HMENU hDefaultCtxMenu = LoadMenu(hiSHDOCLC, MAKEINTRESOURCE(IDR_BROWSE_CONTEXT_MENU));
HMENU hSubMenu = GetSubMenu(hDefaultCtxMenu, dwID);
// Get the language submenu
CComVariant var;
hr = spCT->Exec(&CGID_ShellDocView, SHDVID_GETMIMECSETMENU, 0, NULL, &var);
MENUITEMINFO mii = {0};
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
mii.hSubMenu = (HMENU) var.byref;
// Add language submenu to Encoding context item
SetMenuItemInfo(hSubMenu, IDM_LANGUAGE, FALSE, &mii);
// Insert Shortcut Menu Extensions from registry
CComVariant var1;
V_VT(&var1) = VT_INT_PTR;
V_BYREF(&var1) = hSubMenu;
CComVariant var2;
V_VT(&var2) = VT_I4;
V_I4(&var2) = dwID;
hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2);
// Insert our menu at the top of the context menu
g_hCtxMenu = LoadMenu(_AtlBaseModule.m_hInst, MAKEINTRESOURCE(IDR_CTX));
::InsertMenu(hSubMenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR) g_hCtxMenu, szMenuName);
// Subclass IE window.
g_lpCtxMenuWndProc = SetWindowLongPtr(m_hDocWnd, GWL_WNDPROC, (LONG_PTR)CtxMenuWndProc);
// Show shortcut menu
int nCmd = ::TrackPopupMenu(hSubMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
ppt->x,
ppt->y,
0,
m_hDocWnd,
(RECT*)NULL);
if (IsOurCommand(nCmd))
DoCMD(nCmd);
else
SendToIE(nCmd);
DestroyMenu(hDefaultCtxMenu);
FreeLibrary(hiSHDOCLC);
return S_OK;
}
irohan_fernando