Right button popup menu
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).
WM_RBUTTONDOWN WM_LBUTTONDOWN WM_CONTEXTMENU =TVN_KEYDOWNThere 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
protected:
//{{AFX_MSG(CMyTreeView)
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
protected:
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;
treeCtrl.ScreenToClient(&ptTree);
HTREEITEM htItem = treeCtrl.HitTest(ptTree, &uFlags);
if ((htItem != NULL) && (uFlags & TVHT_ONITEM)) {
ShowPopupMenu( point );
treeCtrl.SetItemState(htItem, 0, TVIS_DROPHILITED);
}
else
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;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
CMenu menu;
VERIFY(menu.LoadMenu(IDR_POPUP_MY_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,
pWndPopupOwner);
}
/* 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)
{
TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
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

Comments
Nike Air Max 1 FB publicity, have on the agenda c trick a strong color character, the brand-new shoes
Posted by Geozyoceada on 04/22/2013 04:10pmIn the summer in a pane backing bowels the chilling sprite seems to be a godlike creme de la creme, but if the sprite "feet"? Resolution also disclose you a set off, bring a sustenance! This summer, Nike and Sprite [url=http://fossilsdirect.co.uk/glossarey.cfm]nike huarache free[/url] and his sneakers to a fuse of classic snow spread of callow, unsullied and downcast color schematic in the undying Nike Air Max 1 shoes romp a like a breath of fresh air cool scent.[url=http://markwarren.org.uk/property-waet.cfm]air max 90[/url] Summer is the duration to choice a clean shoe, shoes should be a acceptable choice. Qualifying series Nike Air Max HomeTurf megalopolis recently at the end of the day comes up, this series in the first-rate Melody Max shoes to London, Paris and Milan the three paid glorification to the iconic metropolis of Europe, combined with the characteristics of the three cities, Sense Max 1 HYP,Allied Max 90 HYP,Air Max 1 and shoes such as Make public Max 95, combined [url=http://northernroofing.co.uk/roofins.cfm]nike free run uk[/url] with the Hyperfuse, as kindly as a collection of materials, such as suede, Whether you crave going or retro-everything.
ReplyWM_CONTEXTMENU
Posted by RaymondCai on 03/10/2007 01:26pmI very appreciate that you shared your idea and code. it helps me a lot. But there is a very funny thing that I can not make right click working for popup menu, I need to double click right botton to popup menu. It seems the only one click did not send message WM_CONTEXTMENU to my program. I know there is some problem of my code, but where? Thanks.
ReplySomething Wrong
Posted by Legacy on 01/23/2003 12:00amOriginally posted by: Cagatay Tunali
This code works only;
user must left click the menu item before right clicking the menu item. this combination will make the code work.
but if you select an item in the list, and after that if you right click another item this code does not work correctly. the selected item and the right clicked item is different.
i discover this when i try to disable the menu item when root is clicked and eanble when a chld is clicked. is there a method to solve this problem. thank you fro your comments and codes.......
ReplyShift-F10 even easier...
Posted by Legacy on 01/06/2003 12:00amOriginally posted by: Greg Williams
I found that I didn't need to explicitly handle the keypress for Shift-F10 (or the context menu key), the WM_CONTEXTMENU message was automatically generated with (-1, -1) as the point passed.
Btw, CTreeCtrl::SelectDropTarget(item) is equivalent to CTreeCtrl::Select(item, TVG_DROPHILITE).
ReplyYou don't need ShowPopupMenu(...)
Posted by Legacy on 09/27/2002 12:00amOriginally posted by: Simon
ReplyThe fight against MFC
Posted by Legacy on 09/09/2002 12:00amOriginally posted by: Anders Borch
Reply
How to implement CTreeCtrl right click Pop up Menu on Dialog?
Posted by Legacy on 07/18/2002 12:00amOriginally posted by: eko sulistyo a
Within CTreeView derived class your method is applicable, but when i'm using CTreeCtrl on My dialog the method is unapplicable. Could you help me with this ?
ReplyTreeCtrl - Right button popup menu:How to enable/disable menu item?
Posted by Legacy on 05/14/2002 12:00amOriginally posted by: Mon
Hi,
In this sample how will I enable or disable any menu item(Right button popup menu).I tried the function EnableMenuItem() function but its not working.Do i need to do some thing extra??
Regards,
ReplyMon
And another way to do it
Posted by Legacy on 11/18/2001 12:00amOriginally posted by: Cla Tischhauser
ReplyAnother easy wait to do this
Posted by Legacy on 10/01/2001 12:00amOriginally posted by: SCAGNI S�bastien
ReplyLoading, Please Wait ...