none
右键菜单问题 RRS feed

  • 问题

  • 在MFC中我在一个button上用TrackPopupMenu创建了弹出菜单,可是这个菜单必须在鼠标选择了一项或者在其他地方点击一下才能关闭消失,如果我没有做出任何选择,而鼠标离开button的时候想要关闭这个弹出菜单的话应该怎么实现呢?恳请知道的朋友指点,谢谢。
    2012年10月12日 10:23

答案

  • 重写CButton类,添加处理WM_ENTERIDLE消息
    BEGIN_MESSAGE_MAP(CXXXButton, CButton)
    	ON_WM_CONTEXTMENU()
    	ON_WM_ENTERIDLE()
    END_MESSAGE_MAP()
    
    void CXXXButton::OnEnterIdle(UINT nWhy, CWnd* pWho)
    {
    	CButton::OnEnterIdle(nWhy, pWho);
    
    	// TODO: Add your message handler code here
    	CPoint pt;
    	GetCursorPos(&pt);
    	HWND hWnd = ::WindowFromPoint(pt);
    	if(GetSafeHwnd() != hWnd)
    	{
    		TCHAR szText[MAX_PATH] = {0};
    		GetClassName(hWnd, szText, _countof(szText));
    		if((0 != _tcscmp(szText, _T("#32768"))) && (NULL != pWho) && (NULL != pWho->GetSafeHwnd()))
     		{
     			pWho->ShowWindow(SW_HIDE);
     		}
    	}
    }
    
    void CXXXButton::OnContextMenu(CWnd* pWnd, CPoint point)
    {
    	// TODO: Add your message handler code here
    	CMenu menu;
    	menu.LoadMenu(IDR_MENU1);
    	ASSERT(menu.GetSafeHmenu());
    	CMenu* pSubMenu = menu.GetSubMenu(0);
    	ASSERT(NULL != pSubMenu);
    	pSubMenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, pWnd);
    	menu.DestroyMenu();
    }


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 jamsBang 2012年10月15日 1:43
    2012年10月12日 14:12
    版主

全部回复

  • 重写CButton类,添加处理WM_ENTERIDLE消息
    BEGIN_MESSAGE_MAP(CXXXButton, CButton)
    	ON_WM_CONTEXTMENU()
    	ON_WM_ENTERIDLE()
    END_MESSAGE_MAP()
    
    void CXXXButton::OnEnterIdle(UINT nWhy, CWnd* pWho)
    {
    	CButton::OnEnterIdle(nWhy, pWho);
    
    	// TODO: Add your message handler code here
    	CPoint pt;
    	GetCursorPos(&pt);
    	HWND hWnd = ::WindowFromPoint(pt);
    	if(GetSafeHwnd() != hWnd)
    	{
    		TCHAR szText[MAX_PATH] = {0};
    		GetClassName(hWnd, szText, _countof(szText));
    		if((0 != _tcscmp(szText, _T("#32768"))) && (NULL != pWho) && (NULL != pWho->GetSafeHwnd()))
     		{
     			pWho->ShowWindow(SW_HIDE);
     		}
    	}
    }
    
    void CXXXButton::OnContextMenu(CWnd* pWnd, CPoint point)
    {
    	// TODO: Add your message handler code here
    	CMenu menu;
    	menu.LoadMenu(IDR_MENU1);
    	ASSERT(menu.GetSafeHmenu());
    	CMenu* pSubMenu = menu.GetSubMenu(0);
    	ASSERT(NULL != pSubMenu);
    	pSubMenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x, point.y, pWnd);
    	menu.DestroyMenu();
    }


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 jamsBang 2012年10月15日 1:43
    2012年10月12日 14:12
    版主
  • 非常感谢您的帮助,你的方法确实管用,但是我对于:

    	if(GetSafeHwnd() != hWnd)
    	{
    		TCHAR szText[MAX_PATH] = {0};
    		GetClassName(hWnd, szText, _countof(szText));
    		if((0 != _tcscmp(szText, _T("#32768"))) && (NULL != pWho) && (NULL != pWho->GetSafeHwnd()))
     		{
     			pWho->ShowWindow(SW_HIDE);
     		}
    	}

    这段代码不是很明白,您能否给我简单解释一下呢?非常感谢

    2012年10月13日 2:11
  • 因为菜单的窗口类名是“#32768”,所以根据这个可以来隐藏右键弹出的菜单窗口

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年10月15日 1:16
    版主