Right button popup menu


Submitted by Christopher A. Snyder.

The CTreeView class does not handle the right mouse button click in a manner like the Explorer window. Actions like highlighting, setting the active item, and where the right mouse menu pops up require some additional code to obtain the appropriate functionality. This article is intented to illustrate what functions need to be added to your view class for the tree to "act" properly.

(this page was revised to correct several typos and to address the SHIFT-F10 keypress. Revision date 2-20-98)

How this works

What need to happen when a user presses the right mouse button is the selected item needs to change, but not the item in focus. In addition the pop-up context sensitive menu should be display at the corner where the mouse clicked. By default, this does not happen. These code additions shift the focus of a tree item based on the where the mouse click occurs. However, when the right mouse button click is completed, (or after the context menu goes away) the selection needs to shift back to the original selected tree item. This is done in the end of the OnContextMenu function through the use of an added member variable.

To handle the SHIFT-F10 key press, this is the keyboard equivalent of a right mouse button click for those who didn't know that (I never use it so I tend to forget it is there), we need to handle the key press command mirrored from the Tree control. The code I have here for this is more a quick fix than a good solution (if someone has a better method send it to me and I will have it updated here). I first look for a shift key press and then set a flag. Then only when the next key pressed is the F10 do I then call the on-context menu function. This is not a real good solution because the use does not have to hold the shift key down to get the menu to pop up. Though it is close and not too big of a deal since few probably even use the SHIFT-F10 sequence anyways.

To add a Right mouse button context sensitive popup menu to a CTreeView which behaves like the Explorer. To do this you need to add command handler functions for the following messages in your CTreeView derived class (CMyTreeView).

There is one more function that I created here to actually create and display you menu from a menu resource and is called

ShowPopupMenu( CPoint& point );

You will need to add one member variable to CMyTreeView called m_pOldSel. Enjoy!

class CMyTreeView : public CTreeView
        // Generated message map functions
        afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);

        afx_msg void OnContextMenu(CWnd*, CPoint point);
        void CMyTreeView::ShowPopupMenu( CPoint& point );
// member variables
        HTREEITEM m_pOldSel;
Place this code in the created functions.
void CMyTreeView::OnLButtonDown(UINT nFlags, CPoint point)
        UINT uFlags;
        HTREEITEM htItem = GetTreeCtrl().HitTest(point, &uFlags);
        if ((htItem != NULL) && (uFlags & TVHT_ONITEM))
                GetTreeCtrl().Select(htItem, TVGN_DROPHILITE);
        CTreeView::OnLButtonDown(nFlags, point);

void CMyTreeView::OnRButtonDown(UINT nFlags, CPoint point)
        UINT uFlags;
        HTREEITEM htItem = GetTreeCtrl().HitTest(point, &uFlags);
        if ((htItem != NULL) && (uFlags & TVHT_ONITEM)) {
                m_pOldSel = GetTreeCtrl().GetSelectedItem();
                GetTreeCtrl().Select(htItem, TVGN_DROPHILITE);

void CMyTreeView::OnContextMenu(CWnd* pWnd, CPoint point)
        UINT uFlags;
        CTreeCtrl&      treeCtrl = GetTreeCtrl();
        CPoint ptTree = point;
        HTREEITEM htItem = treeCtrl.HitTest(ptTree, &uFlags);

        if ((htItem != NULL) && (uFlags & TVHT_ONITEM)) {
                ShowPopupMenu( point );
                treeCtrl.SetItemState(htItem, 0, TVIS_DROPHILITED);
                CTreeView::OnContextMenu(pWnd, point);

        if (m_pOldSel != NULL) {
                treeCtrl.Select(m_pOldSel, TVGN_DROPHILITE);
                m_pOldSel = NULL;

void CMyTreeView::ShowPopupMenu( CPoint& point )
        if (point.x == -1 && point.y == -1){
                //keystroke invocation
                CRect rect;

                point = rect.TopLeft();
                point.Offset(5, 5);

        CMenu menu;

        CMenu* pPopup = menu.GetSubMenu(0);
        ASSERT(pPopup != NULL);
        CWnd* pWndPopupOwner = this;

        while (pWndPopupOwner->GetStyle() & WS_CHILD)
                pWndPopupOwner = pWndPopupOwner->GetParent();

        pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,

/*       121 vbKeyF10  16 = shift */
// there is probably a more elegant way to handle this, but this method works.
void CMyTreeView::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) 
        static BOOL bShift = FALSE;
        if ( bShift && pTVKeyDown->wVKey == 121 ) {
                HTREEITEM hItem = GetTreeCtrl().GetSelectedItem( );
                CRect rect;
                GetTreeCtrl().GetItemRect( hItem, &rect, TRUE);
                ClientToScreen( rect );
                OnContextMenu( this, CPoint( rect.right, rect.top ) );
        bShift = pTVKeyDown->wVKey == 16;

        *pResult = 0;
Chris is a reseach engineer for the Ohio University Avionics Engineering Center.
Feel Free to e-mail him with questions or comments.

Revised on : 3/15/98


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • A leading provider of tools and services to the health care industry was looking to implement automated chargeback reports with aggregation of tiered storage usage across multiple business units and applications. When the company's storage administrators attempted to create this system in-house, their productivity took a huge hit and they discovered the task was too challenging, as well. Read this case study to learn how this company was able to increase storage utilization, reduce storage consumption, and …

  • The software-defined WAN (SD-WAN) has emerged as the solution for enterprises embracing cloud computing as a means to realizing digital transformation. In this IDC brief, learn why the need for SD-WAN will be even greater than the need for SDN in the data center, especially when an organization's application profile is migrating toward public cloud services and where customer engagement is most valued.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date