2

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?

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
ApplePieIsGood
  • 3,731
  • 6
  • 35
  • 51

2 Answers2

3

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.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
0

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);
Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41