【问题标题】:Win32 C++ ListView WM_CONTEXTMENU IssueWin32 C++ ListView WM_CONTEXTMENU 问题
【发布时间】:2021-02-06 14:57:00
【问题描述】:

我有一个 ListView,我想使用一个根据选择而变化的上下文菜单。我确保在释放鼠标右键时首先能够显示菜单(按照正常的上下文菜单行为)。

在我的 ListView WNDPROC 中,我使用 WM_CONTEXTMENU 来显示上下文菜单。然而,菜单显示在光标开始选择的位置,而不是结束处。

来自MS documentation

DefWindowProc 在处理 WM_RBUTTONUP 或 WM_NCRBUTTONUP 消息或当用户键入 SHIFT+F10 时生成 WM_CONTEXTMENU 消息。当用户按下并释放 VK_APPS 键时,也会生成 WM_CONTEXTMENU 消息。

当我检查调用堆栈时,在WM_CONTEXTMENU 中有一个断点,我看到在WM_CONTEXTMENU 之前发送的消息是0x0204WM_RBUTTONDOWN,此时包含光标的坐标。这可能解释了菜单位置问题,但为什么会发生这种情况?

当我在 ListView 外面按住 RMB 并在里面释放它时,上下文菜单仍然出现,我可以从调用堆栈中看到最后一条消息是 0x0205WM_RBUTTONUP

不确定我的代码是否有问题,或者我不理解某些内容。非常感谢您对此问题的任何帮助,谢谢。

【问题讨论】:

  • 0x0205WM_RBUTTONUPWM_RBUTTONDOWN0x0204
  • 啊,是的,抱歉,我现在就解决这个问题。
  • 在处理WM_CONTEXTMENU 时,GetMessagePos() 是否会为您提供您正在寻找的正确坐标?
  • 确实如此。我想知道在WM_CONTEXTMENU 之后是否有WM_RBUTTONUP 进入导致GetMessagePos() 从中获取鼠标坐标?
  • WM_CONTEXTMENU自己报告的坐标呢?

标签: c listview winapi win32gui


【解决方案1】:

而不是依靠WM_RBUTTON(DOWN|UP) 消息来确定鼠标坐标,WM_CONTEXTMENU 自己的lParam 为您提供生成WM_CONTEXTMENU 的消息的鼠标屏幕坐标。如果这些坐标不是您所期望的,您可以改用GetMessagePos(),它将报告生成WM_CONTEXTMENU 时的屏幕坐标。无论哪种方式,您都可以使用ScreenToClient()MapWindowPoints() 将屏幕坐标转换为ListView 客户端坐标。

请确保您还处理了用户通过键盘输入而不是鼠标单击来调用弹出菜单的情况。在这种情况下,WM_CONTEXTMENUlParam 将携带屏幕坐标[x=-1,y=-1],您可以根据需要使用LVM_GETITEMPOSITIONLVM_GETITEMRECT 查询ListView 的所选项目的位置,然后转换使用ClientToScreen()MapWindowPoints() 将该位置设置为屏幕坐标,然后在该屏幕位置显示弹出菜单。

【讨论】:

  • 谢谢。有趣的是,MMC 中的 ListViews 似乎遇到了与我相同的问题,而如果您在 Windows 资源管理器中使用 RMB 框选择元素并在控件之外释放 RMB,它将不会显示上下文菜单,而只会选择项目。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 2021-01-24
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
相关资源
最近更新 更多