|
-
April 6th, 1999, 07:16 AM
#1
ListView's ContextMenu
Hi,
I use VC5.0 on NT4.
I need to know how to detect when a user has right-clicked on an item in a listview, and not just anywhere in the client area. I only want to display the
context menu when there has been right clicked on an item in the view.
I think I'll have to handle the OnRButtonClick message, but do not know what
to do then.
Any help you can give me will be much appreciated.
Thanks in advance.
-
April 6th, 1999, 09:41 AM
#2
Re: ListView's ContextMenu
If you handle the NM_CLICK notification, you will receive an NMLISTVIEW structure as the lParam argument. This has all the information you need:
typedef struct tagNMLISTVIEW
{
NMHDR hdr;
int iItem;
int iSubItem;
UINT uNewState;
UINT uOldState;
UINT uChanged;
POINT ptAction;
LPARAM lParam;
} NMLISTVIEW, FAR *LPNMLISTVIEW;
Have a look at "List View Control Notification Messages" in the online docs.
Also check out the List Control area on this site, there are probably suitable examples there.
Dave
-
February 28th, 2001, 12:24 PM
#3
Re: ListView's ContextMenu
1. Map CListView's OnContextMenu
2. Get the Window Rect of List Control,
3. Compare it with mouse coordinates to determine whether it is over list control
4. if not , return, else continue with right click popup menu
-
February 28th, 2001, 12:35 PM
#4
Re: ListView's ContextMenu
Here's some sample code for a right-click handler that does what you want.
If the user right-clicks over a list control item or subitem, the context menu shows "Add," "Edit" and "Delete." If the user right-clicks off of any row (i.e., on a row of white space), then the context menu contains just "Add."
Ignore the SetCurrentAdvisor() call, it has nothing to do with your problem.
void CAdvisorsPage::OnRclickListReps(NMHDR* pNMHDR, LRESULT* pResult)
{
SetCurrentAdvisor();
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
CPoint pt(pNMListView->ptAction);
CMenu menu;
menu.LoadMenu(IDM_LISTCTRL); // our context menu
CMenu* pContextMenu = menu.GetSubMenu(0);
// Only the Fee Schedules page uses Clone
menu.RemoveMenu(ID_LISTCTRL_CLONE, MF_BYCOMMAND);
// Make sure something is there before we show the menu.
// If nothing is there, shorten the menu to just "Add..."
int nCol = 0;
CHeaderCtrl* pHdr = m_listctrlReps.GetHeaderCtrl();
ASSERT(pHdr);
int nIndex = m_StdRt.HitTestEx( pt,&nCol, m_listctrlReps, pHdr->GetItemCount());
if(m_CurrentAdvisor.m_FirmID < 0 || nIndex == -1)
{
menu.RemoveMenu(ID_LISTCTRL_EDIT, MF_BYCOMMAND); // remove "Edit..."
menu.RemoveMenu(ID_LISTCTRL_DELETE, MF_BYCOMMAND); // remove "Delete..."
}
POINT p;
p.x = pt.x;
p.y = pt.y;
::ClientToScreen(pNMHDR->hwndFrom, &p);
int nID = pContextMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RETURNCMD,
p.x, p.y, this);
// if() used instead of case to avoid overhead of instantiating
// possibly unused resources outside the switch statement
if(nID == ID_LISTCTRL_ADD)
AdvisorInsert();
else if(nID == ID_LISTCTRL_EDIT)
AdvisorEdit();
else if(nID == ID_LISTCTRL_DELETE)
AdvisorDelete();
// The menu is a temporary MFC object, no need to delete it.
*pResult = 0;
}
///////////////////////////////////////
// HitTestEx() code:
/*
Name: HitTestEx()
Description: Determines row and column of a mouse click in the list control
*/
int CStdRoutines::HitTestEx( CPoint point, int *nCol, CListCtrl& list, int nColumnCount)
{
int colnum = 0;
int row = list.HitTest( point, NULL );
if( nCol ) *nCol = 0;
// Make sure that the ListView is in LVS_REPORT mode
if( (GetWindowLong(list.m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
return row;
// Get the top and bottom row visible
row = list.GetTopIndex();
int bottom = row + list.GetCountPerPage();
if( bottom > list.GetItemCount() )
bottom = list.GetItemCount();
// Loop through the visible rows
for( ;row <= bottom;row++)
{
// Get bounding rect of item and check whether point falls in it.
CRect rect;
list.GetItemRect( row, &rect, LVIR_BOUNDS );
if( rect.PtInRect(point) )
{
// Now find the column
for( colnum = 0; colnum < nColumnCount; colnum++ )
{
int colwidth = list.GetColumnWidth(colnum);
if( point.x >= rect.left && point.x <= (rect.left + colwidth ) )
{
if( nCol ) *nCol = colnum;
return row;
}
rect.left += colwidth;
}
}
}
return -1;
}
///////////////////////////////////////
// The resource info for the context menu:
IDM_LISTCTRL MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "&Add...", ID_LISTCTRL_ADD
MENUITEM "&Edit...", ID_LISTCTRL_EDIT
MENUITEM "&Delete...", ID_LISTCTRL_DELETE
MENUITEM "&Clone...", ID_LISTCTRL_CLONE
END
END
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|