TrackPopupMenu弹出菜单后父窗口的消息响应有关问题
TrackPopupMenu弹出菜单后父窗口的消息响应问题
我在程序中制作了一个菜单项,但是不是直接用来放到对话框上的
我在对话框上输出了几个词组,当鼠标点击文字时,将在对应文字下方弹出菜单
弹出菜单的代码如下
弹出正常,问题就在于,当弹出菜单后,窗口的消息就由当前菜单来处理了,鼠标移动等消息捕获不到了
我想做成一般菜单的那种,鼠标滑过哪个菜单项就在其下弹出其对应菜单。
而现在弹出菜单后,除非点击窗口,不然鼠标消息捕获不到··代码中
SetForegroundWindow(hWnd);
试过了,没有效果··
请问该如何解决呢?
------解决方案--------------------
如果一个菜单点击之后,没有点击过其他地方,那么当鼠标滑出菜单区域时,菜单会自动消失,鼠标再进入菜单时,菜单会自动弹出。
点击过其他地方之后,鼠标再次滑过菜单,菜单不弹出。
------解决方案--------------------
菜单是模式窗口,你需要HOOK它,在HOOK里面要使已经弹出的菜单自动消失,给它发送WM_CANCELMODE消息。
// 在弹出菜单之前先HOOK菜单。
HOOK hHook = SetWindowsHookEx(WH_MSGFILTER, HookProc, NULL, GetCurrentThreadId);
TrackPopupMenu(...);
UnhookWindowsHookEx(hHook);
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code == MSGF_MENU)
{
MSG* pMsg = (MSG*)lParam;
if (pMsg->msg == WM_MOUSEMOVE)
{
// 计算坐标,当鼠标到了某个位置需要销毁菜单时,给拥有菜单的窗口发送WM_CANCELMODE消息。
}
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}
我在程序中制作了一个菜单项,但是不是直接用来放到对话框上的
我在对话框上输出了几个词组,当鼠标点击文字时,将在对应文字下方弹出菜单
弹出菜单的代码如下
- C/C++ code
m_nMenuSel = MenuItemChecked(hWnd, point); // 判断是否点击文字。返回文字在数组中的索引 if(-1 != m_nMenuSel) { CMenu menu; menu.LoadMenu(IDR_MENU2); CMenu *pPopup = menu.GetSubMenu(m_nMenuSel); CPoint ptMenu; ptMenu.x = m_rcMenu[m_nMenuSel].left; ptMenu.y = m_rcMenu[m_nMenuSel].bottom; ClientToScreen(hWnd, &ptMenu); //SetForegroundWindow(hWnd); pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,ptMenu.x,ptMenu.y,NULL); //SetFocus(hWnd); return TRUE; }
弹出正常,问题就在于,当弹出菜单后,窗口的消息就由当前菜单来处理了,鼠标移动等消息捕获不到了
我想做成一般菜单的那种,鼠标滑过哪个菜单项就在其下弹出其对应菜单。
而现在弹出菜单后,除非点击窗口,不然鼠标消息捕获不到··代码中
SetForegroundWindow(hWnd);
试过了,没有效果··
请问该如何解决呢?
------解决方案--------------------
如果一个菜单点击之后,没有点击过其他地方,那么当鼠标滑出菜单区域时,菜单会自动消失,鼠标再进入菜单时,菜单会自动弹出。
点击过其他地方之后,鼠标再次滑过菜单,菜单不弹出。
------解决方案--------------------
菜单是模式窗口,你需要HOOK它,在HOOK里面要使已经弹出的菜单自动消失,给它发送WM_CANCELMODE消息。
// 在弹出菜单之前先HOOK菜单。
HOOK hHook = SetWindowsHookEx(WH_MSGFILTER, HookProc, NULL, GetCurrentThreadId);
TrackPopupMenu(...);
UnhookWindowsHookEx(hHook);
LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
{
if (code == MSGF_MENU)
{
MSG* pMsg = (MSG*)lParam;
if (pMsg->msg == WM_MOUSEMOVE)
{
// 计算坐标,当鼠标到了某个位置需要销毁菜单时,给拥有菜单的窗口发送WM_CANCELMODE消息。
}
}
}
return CallNextHookEx(NULL, code, wParam, lParam);
}