在BHO中实现右键菜单网上相关文章很多,可以通过实现IDocHostUIHandler接口的ShowContextMenu、截获HTMLDocumentEvents2的OnContextMenu消息等。
但这两种方式都必须在浏览器线程中实现才能正常弹出右键菜单,当你需要在另外的线程中实现右键菜单,这就不行了,TrackPopupMenuEx的时候会直接略过。
我采取的方式是建一个看不见的窗口,TrackPopupMenuEx所需的窗口句柄设置为该窗口。
构建一个轻量级的窗体类:
#include <atlbase.h> #include <atlwin.h> class CMenuWindow : public ATL::CWindowImpl < CMenuWindow > { public: BEGIN_MSG_MAP(CMenuWindow) END_MSG_MAP(); };
右键菜单例子:
HMENU hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING, 1001, L"aaa"); AppendMenu(hMenu, MF_STRING, 1002, L"bbb"); AppendMenu(hMenu, MF_STRING, 1003, L"ccc"); POINT pt; GetCursorPos(&pt); RECT wndRect; wndRect.left = pt.x; wndRect.top = pt.y; wndRect.right = wndRect.left + 1; wndRect.bottom = wndRect.top + 1; CMenuWindow wnd; wnd.Create(NULL, wndRect, _T(""), WS_OVERLAPPED | WS_CAPTION);
SetForegroundWindow(wnd.m_hWnd); // 必须设置到最前面,否则取消会成问题 int cmd = TrackPopupMenuEx(hMenu, TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON, pt.x, pt.y, wnd.m_hWnd, NULL); DestroyMenu(hMenu); wnd.DestroyWindow(); ATL::CString msg; msg.Format(L"id = %d", cmd); MessageBox(NULL, msg, L"", MB_OK);