1
votes

I have VC++ MFC app and I need to display a context menu over CMainFrame menubar. I added a handler for WM_CONTEXTMENU in CMainFrame and I am able to display my context menu over the toolbar (also the window title) but the handle does not get invoked when I right click in the menubar

2

2 Answers

3
votes

Using the Spy++ utility and right clicking on the client, toolbar or caption regions of a typical application results in the following message trace information:

<02620> 005503AE P WM_RBUTTONDOWN fwKeys:MK_RBUTTON xPos:1048 yPos:7
<02621> 005503AE P WM_RBUTTONUP fwKeys:0000 xPos:1048 yPos:7
<02622> 005503AE S WM_CONTEXTMENU hwnd:005503AE xPos:1174 yPos:63

But right clicking on the menu produces no corresponding trace information in the Spy++ message window. So it looks to me like this is standard Windows behaviour.

I suspect Windows is generating the WM_CONTEXTMENU message in response to the WM_RBUTTONDOWN and WM_RBUTTONUP messages and since these are not generated when you right click on the menu, no popup context menu is displayed.

But if you really want this behaviour, what you could do is trap the WM_NCRBUTTONDOWN client mouse message and inside this message handler post your own WM_CONTEXTMENU message to the frame window.

1
votes

Thanks for pointing me in the right direction. I was able to do it by handling WM_NCRBUTTONUP message and inside the handler check whether the point is on the menu bar.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CONTEXTMENU()
ON_WM_NCRBUTTONUP()
END_MESSAGE_MAP()

void CMainFrame::OnContextMenu(CWnd* pWnd, CPoint point) {

    // do not display our popup menu for title bar, etc
    CRect rcClient;
    GetClientRect(rcClient);
    ClientToScreen(rcClient);

    if (rcClient.PtInRect(point))
        PopupMenu(point);
    else
        __super::OnContextMenu(pWnd, point);
}

void CMainFrame::OnNcRButtonUp(UINT nHitTest, CPoint point) {

    if (nHitTest == HTMENU)
        PopupMenu(point);

    CFrameWnd::OnNcRButtonUp(nHitTest, point);
}

int CMainFrame::PopupMenu(CPoint &point) {
  // display popup menu
  ....
}