简体   繁体   中英

How to get rect of the item in Listbox using winapi

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.

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.

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM