I have a basic app written with ATL, using the wizard with VS2008. I have a treeview in the left side of the app. I see how to (painfully) add tree items. Question is how do I show a menu when the mouse is right clicked? How do I trap any click events on each item that could be selected?
2 Answers
You should detect the WM_CONTEXTMENU
windows message by specifying a handler in your message map. In the handler you can then show the context menu. You then need to make sure you also handle the menu commands in your message map for when a command is selected from the context menu. Use the COMMAND_HANDLER
macro in your message map for this part.

- 61,417
- 20
- 137
- 189
Jeff Yates answer gave me the direction. Since I am using C, the solution is a bit different (and, as usual, a bit more complex):
The idea is to calculate the point in the tree view where the right click was performed, then get the item. Now you can check the type of the item and display the appropriate context menu. To prevent user confusion, the following also selects the right-clicked node in the tree view.
The example assumes there is one tree view in your dialog. You may need to cycle over the tree views in your dialog.
case WM_CONTEXTMENU:
{
RECT rcTree;
HWND hwndTV;
HTREEITEM htvItem;
TVHITTESTINFO htInfo = {0};
long xPos = GET_X_LPARAM(lParam); // x position from message, in screen coordinates
long yPos = GET_Y_LPARAM(lParam); // y position from message, in screen coordinates
hwndTV=GetDlgItem(hDlg, IDC_TREE1); // get the tree view
GetWindowRect(hwndTV,&rcTree); // get its window coordinates
htInfo.pt.x= xPos-rcTree.left; // convert to client coordinates
htInfo.pt.y= yPos-rcTree.top;
if (htvItem=TreeView_HitTest(hwndTV, &htInfo)) { // hit test
TreeView_SelectItem(hwndTV, htvItem); // success; select the item
/* display your context menu */
}
break;
}
The following displays a context menu:
RECT winPos, itemPos;
HMENU hCtxtMenuBar= LoadMenu(ghInst,MAKEINTRESOURCE(ID_CTXTMENUS_RESOURCE));
HMENU hCtxtMenu= GetSubMenu(hCtxtMenuBar, MY_CTXMENU);
TreeView_GetItemRect(hwndTV, htvItem, &itemPos, TRUE);
GetWindowRect(hwndTV, &winPos);
SendMessage (hDlg, WM_COMMAND,
TrackPopupMenuEx(hCtxtMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_NONOTIFY|TPM_RETURNCMD,
winPos.left+itemPos.left, winPos.top+itemPos.bottom, hDlg,0),
(LPARAM)hwndTV);

- 25,048
- 4
- 23
- 41
-
Why? Why do all this? Why not just do this: `NOTIFY_CODE_HANDLER_EX(NM_RCLICK, OnRClick)` – trieck Jul 22 '21 at 21:49
-
@trieck, I think that in your `OnRClick` function you still have to do all the work. – Paul Ogilvie Jul 23 '21 at 07:16