如何使用winapi获取Listbox中的项目的rect

我正在使用VC6.0。 我正在尝试编程来显示contextmenu,当我右键单击列表框的项目。 但现在popmenu可以显示在ListBox的任何地方,因为我只能得到列表框的矩形,而我不知道如何获得该项目的矩形。 我知道有一个macrosListView_GetSubItemRect似乎得到了ListView项的矩形。 有没有类似的方式为ListBox,或者有一种方法来获取ListBox的项目的宽度和高度,所以我可以计算矩形? 我没有find一些有用的信息在MSDN和谷歌? 任何人都可以给我一些想法吗? 谢谢。

我目前的代码:

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

编辑

当前:

在这里输入图像说明

首先,我点击一个项目来select一个项目。 第二我右键单击所选项目以显示popmenu。 它显示正常。 但在第二步,如果我点击ListBox的空白区域,它也显示菜单。 这不是我所期望的。

我所期望的是:

在这里输入图像说明

菜单只显示当我点击一个项目,只有在项目的位置。 当我右击其他地区,它不会被显示。

您正在寻找ListBox_GetItemRect宏。

但是,我确实觉得用户会觉得很奇怪,要点击一个地方,看到菜单出现在别的地方。

这个问题的正确解决方案是在鼠标位置弹出上下文菜单。 点击一个地方,然后在别的地方弹出来会很糟糕。

获取鼠标位置使用GetCursorPos()http://msdn.microsoft.com/en-us/library/windows/desktop/ms648390%28v=vs.85%29.aspx


清楚的是,首先使用ListBox_GetItemRect来确定哪个项目被点击,如果没有则忽略它。 然后使用GetCursorPos,使菜单恰好出现在鼠标所在的位置 – 列表项内 – 而不是几个像素之外。 Windows UI标准是上下文菜单出现在光标位置。

我不知道为什么你自己写了OnContextMenu – 你应该使用类向导来映射WM_CONTEXTMENU与标准的处理程序,其中现有的函数结束在你的代码是这样的:

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