Win32 C++ ListView WM_CONTEXTMENU 问题
Win32 C++ ListView WM_CONTEXTMENU Issue
我有一个 ListView,我想在其中使用根据选择而变化的上下文菜单。我正在确保在释放鼠标右键时首先能够显示菜单(按照正常的上下文菜单行为)。
在我的 ListView WNDPROC
中,我使用 WM_CONTEXTMENU
来显示上下文菜单。然而,菜单显示在光标开始选择的位置,而不是结束处。
DefWindowProc generates the WM_CONTEXTMENU message when it processes the WM_RBUTTONUP or WM_NCRBUTTONUP message or when the user types SHIFT+F10. The WM_CONTEXTMENU message is also generated when the user presses and releases the VK_APPS key.
当我检查调用堆栈时,在 WM_CONTEXTMENU
中设置了一个断点,我看到在 WM_CONTEXTMENU
之前发送的消息是 0x0204
或 WM_RBUTTONDOWN
包含坐标此时的光标。这可能解释了菜单位置问题,但为什么会发生这种情况?
当我在 ListView 外部按住人民币并在内部释放它时,上下文菜单仍然出现,我可以从调用堆栈中看到最后一条消息是 0x0205
或 WM_RBUTTONUP
。
不确定我的代码是否有问题,或者我不理解某些东西。非常感谢对此问题的任何帮助,谢谢。
不是依靠 WM_RBUTTON(DOWN|UP)
消息来确定鼠标坐标,WM_CONTEXTMENU
自己的 lParam
为您提供生成 [= 的消息的鼠标屏幕坐标11=]。如果这些坐标不是您所期望的,您可以改用 GetMessagePos()
,它将报告生成 WM_CONTEXTMENU
时的屏幕坐标。无论哪种方式,您都可以使用 ScreenToClient()
或 MapWindowPoints()
.
将屏幕坐标转换为 ListView 客户端坐标
请确保您还处理了用户通过键盘输入而不是鼠标单击来调用弹出菜单的情况。在这种情况下,WM_CONTEXTMENU
的 lParam
将携带屏幕坐标 [x=-1,y=-1]
,您可以使用 LVM_GETITEMPOSITION
或查询 ListView 以获取其所选项目的位置LVM_GETITEMRECT
根据需要,然后使用 ClientToScreen()
或 MapWindowPoints()
将该位置转换为屏幕坐标,然后在该屏幕位置显示弹出菜单。
我有一个 ListView,我想在其中使用根据选择而变化的上下文菜单。我正在确保在释放鼠标右键时首先能够显示菜单(按照正常的上下文菜单行为)。
在我的 ListView WNDPROC
中,我使用 WM_CONTEXTMENU
来显示上下文菜单。然而,菜单显示在光标开始选择的位置,而不是结束处。
DefWindowProc generates the WM_CONTEXTMENU message when it processes the WM_RBUTTONUP or WM_NCRBUTTONUP message or when the user types SHIFT+F10. The WM_CONTEXTMENU message is also generated when the user presses and releases the VK_APPS key.
当我检查调用堆栈时,在 WM_CONTEXTMENU
中设置了一个断点,我看到在 WM_CONTEXTMENU
之前发送的消息是 0x0204
或 WM_RBUTTONDOWN
包含坐标此时的光标。这可能解释了菜单位置问题,但为什么会发生这种情况?
当我在 ListView 外部按住人民币并在内部释放它时,上下文菜单仍然出现,我可以从调用堆栈中看到最后一条消息是 0x0205
或 WM_RBUTTONUP
。
不确定我的代码是否有问题,或者我不理解某些东西。非常感谢对此问题的任何帮助,谢谢。
不是依靠 WM_RBUTTON(DOWN|UP)
消息来确定鼠标坐标,WM_CONTEXTMENU
自己的 lParam
为您提供生成 [= 的消息的鼠标屏幕坐标11=]。如果这些坐标不是您所期望的,您可以改用 GetMessagePos()
,它将报告生成 WM_CONTEXTMENU
时的屏幕坐标。无论哪种方式,您都可以使用 ScreenToClient()
或 MapWindowPoints()
.
请确保您还处理了用户通过键盘输入而不是鼠标单击来调用弹出菜单的情况。在这种情况下,WM_CONTEXTMENU
的 lParam
将携带屏幕坐标 [x=-1,y=-1]
,您可以使用 LVM_GETITEMPOSITION
或查询 ListView 以获取其所选项目的位置LVM_GETITEMRECT
根据需要,然后使用 ClientToScreen()
或 MapWindowPoints()
将该位置转换为屏幕坐标,然后在该屏幕位置显示弹出菜单。