Reputation: 3736
I am using VC6.0. I am trying programming to show contextmenu when I right click on the item of the ListBox. But now the popmenu can show anywhere in the rect of ListBox, since I only can get the rect of the ListBox, and I dont know how to get the rect of the item. I know that there is a macro ListView_GetSubItemRect
which seems to get the rect of item of ListView. Is there similar way for ListBox, or is there a way to get the width and the height of item of ListBox, so I can caculate the rect? I didnt find some useful information on msdn and google? Can anyone give me some ideas? Thanks.
My current Code:
void My_OnContextMenu(HWND hwnd, HWND hwndContext, UINT xPos, UINT yPos)
{
HWND hList = GetDlgItem(hwnd,IDC_LIST_RESTYPE);
if (hList == hwndContext)
{
if(-1!=indexLB)
{
RECT rect;
POINT pt;
GetClientRect(hwndContext, &rect);
ScreenToClient(hwndContext, &pt);
if(PtInRect(&rect, pt))
{
HMENU hroot = LoadMenu((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), MAKEINTRESOURCE(IDR_MENU_DELTYPE));
if(hroot)
{
HMENU hpop = GetSubMenu(hroot,0);
ClientToScreen(hwndContext, &pt);
TrackPopupMenu(hpop, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwndContext, NULL);
DestroyMenu(hroot);
}
}
}
}
}
Edit
Current:
First, I left click an item to selected、 an item. And Second I right click the selected item to show popmenu. It shows normally. But in the second step if I click the blank area of ListBox, it shows menu either. That is not what I expected.
What I expected is:
The menu only shows when I click an item and the position only over the item. When I right click other area, it wont be showed.
Upvotes: 1
Views: 1056
Reputation: 328
I'm not sure Why you wrote your own OnContextMenu - you should use the class wizard to map WM_CONTEXTMENU with the standard handler where the existing function ends up in your code like this:
//Wizard Added this the message map block
ON_WM_CONTEXTMENU()
//Declares the function with the proper parameters
void MyDlg::OnContextMenu(CWnd* pWnd, CPoint point);
//in the body of OnContextMenu use the system supplied parameters and the
//menu will appear next to the mouse position wherever it is clicked in the control
CMenu popupmenu;
popupmenu.LoadMenu(IDR_RMOUSEPOPUP);
int Command = (int)popupmenu.GetSubMenu(0)->TrackPopupMenu(
TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY,
point.x, point.y, pWnd);
Upvotes: 0
Reputation: 10868
The proper solution to this problem is to popup the context menu at the mouse position. Clicking in one place and popping it up somewhere else would be very bad.
To get the mouse position use GetCursorPos()
.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648390%28v=vs.85%29.aspx
To be clear, first use ListBox_GetItemRect to work out which item is clicked on, and ignore it if none. Then use GetCursorPos so the menu appears exactly where the mouse is -- inside the list item -- and not somewhere a few pixels away. The Windows UI standards are that the context menu appears at the cursor position.
Upvotes: 0
Reputation: 612954
You are looking for the ListBox_GetItemRect
macro.
However, I do feel that the user will find it odd to click in one place and see the menu appear somewhere else.
Upvotes: 2