[英]How to modify context menu of internet explorer using IDocHostUIHandler::ShowContextMenu?
I am trying to implement a custom menu for Internet Explorer 7.0. 我正在尝试为Internet Explorer 7.0实现自定义菜单。 For this i have to use
IDocHostUIHandler::ShowContextMenu
only. 为此,我只能使用
IDocHostUIHandler::ShowContextMenu
。 Till now i am able to implement a basic context menu with two options. 到现在为止,我可以实现带有两个选项的基本上下文菜单。 The problem is that they are disabled by default.
问题是默认情况下禁用它们。 The sample code for the same is:
相同的示例代码是:
HRESULT CWebEventHandler::ShowContextMenu(DWORD dwID,POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispObject)
{
if (false) // I will put some guard code here. as of now do not consider it
return S_FALSE; // Show standard context menus.
else
{
IOleWindow* pWnd = NULL;
HRESULT hr = pcmdTarget->QueryInterface(IID_IOleWindow,
(void**) &pWnd);
if (SUCCEEDED(hr))
{
HWND hwnd;
if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
{
HMENU menu = ::CreatePopupMenu();
::AppendMenu(menu, MF_STRING, ID_HELLO, L"&Hello" ); // ID_HELLO & ID_WORLD are two menu resource items
::AppendMenu(menu, MF_STRING, ID_WORLD, L"&World" );
long myRetVal = ::TrackPopupMenu(menu,
TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD,
ppt->x, ppt->y, NULL, hwnd, NULL);
// Send the command to the browser.
//
LRESULT myResult = ::SendMessage(hwnd, WM_COMMAND,
myRetVal, NULL);
}
pWnd->Release();
}
}
return S_OK;
}
Kindly suggest what is wrong with this code & why my menu entries are disabled?? 请提示此代码出了什么问题以及为什么我的菜单项被禁用了?
Thanks 谢谢
EDIT 编辑
The same post is available on this link also ( http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/13584f76-21bd-4764-b5b7-e81932561574 ) 在此链接上也可以找到相同的帖子( http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/13584f76-21bd-4764-b5b7-e81932561574 )
I'm sure you already figured this out, but in the second sample, you are doing: ::SendMessage(hwnd, WM_COMMAND,myRetVal, NULL); 我确定您已经弄清楚了,但是在第二个示例中,您正在做::: SendMessage(hwnd,WM_COMMAND,myRetVal,NULL);
after reverting: SetWindowLong(hwnd, GWL_WNDPROC, (LONG)g_lpPrevWndProc); 恢复后:SetWindowLong(hwnd,GWL_WNDPROC,(LONG)g_lpPrevWndProc);
Your callback will never get executed on the return 0; 您的回调将永远不会在返回0时执行; path, though, nor was there such a case in this particular sample.
但是,在此特定样本中也没有这种情况。
I think i have solved the problem. 我想我已经解决了问题。 After getting the hwnd object in
if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
install your own CALLBACK for context menu. 在
if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
获取hwnd对象后,请为上下文菜单安装您自己的CALLBACK。 In the callback 在回调中
if ((uMsg == WM_INITMENUPOPUP) && (wParam == (WPARAM) menu)) {
return 0;
}
otherwise let the original handler process it. 否则让原始处理程序处理它。
once done with 一旦完成
long myRetVal = ::TrackPopupMenu(g_hPubMenu,TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD,
ppt->x, ppt->y, NULL, hwnd, NULL);
revert back to the original proc handler.... 恢复为原始的proc处理程序。
Sample 样品
WNDPROC g_lpPrevWndProc = NULL;
HRESULT CWebEventHandler::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdTarget, IDispatch *pdispObject)
{
if (false)
return S_FALSE; // Show standard context menus.
else
{
IOleWindow* pWnd = NULL;
HRESULT hr = pcmdTarget->QueryInterface(IID_IOleWindow,
(void**) &pWnd);
if (SUCCEEDED(hr))
{
HWND hwnd;
if (SUCCEEDED(pWnd->GetWindow(&hwnd)))
{
g_lpPrevWndProc = (WNDPROC)SetWindowLong(hwnd, GWL_WNDPROC, (LONG)CtxMenuWndProc);
if (g_hPubMenu)
{
DestroyMenu(g_hPubMenu);
g_hPubMenu = NULL;
}
g_hPubMenu = ::CreatePopupMenu();
::AppendMenu(g_hPubMenu, MF_STRING|MF_ENABLED , ID_HELLO, L"&Hello" );
::AppendMenu(g_hPubMenu, MF_STRING|MF_ENABLED , ID_WORLD, L"&World" );
long myRetVal = ::TrackPopupMenu(g_hPubMenu,
TPM_RIGHTBUTTON | TPM_LEFTALIGN | TPM_RETURNCMD,
ppt->x, ppt->y, NULL, hwnd, NULL);
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)g_lpPrevWndProc);
// Send the command to the browser.
//
if (myRetVal == ID_HELLO)
{
box(_T("Hello"));
}else if(myRetVal == ID_WORLD)
{
box(_T("World"));
}else{
LRESULT myResult = ::SendMessage(hwnd, WM_COMMAND,myRetVal, NULL);
}
}
pWnd->Release();
}
}
return S_OK;
}
LRESULT CALLBACK CtxMenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ((uMsg == WM_INITMENUPOPUP) && (wParam == (WPARAM) g_hPubMenu)) {
return 0;
}
return CallWindowProc(g_lpPrevWndProc, hwnd, uMsg, wParam, lParam);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.