vb.net - 打开表单的上下文菜单
问题描述
我想在表单上的最小化按钮旁边添加一个带有一些选项(快捷方式)的下拉菜单。为此,我在代码项目https://www.codeproject.com/Articles/55180/Extending-the-Non-Client-Area-in-Aero上遵循了以下示例。这非常适合我想要的(我考虑隐藏边框样式,但后来我无法将表单停靠在屏幕边缘)但由于某种原因禁用了调用标题栏上的上下文菜单的能力。
我在示例中注意到 WM_NCHITTEST 事件的覆盖没有使用 HTSYSMENU 结果,并且只为标题栏的整个区域返回 HTCAPTION。然后,如果鼠标在标题栏的左侧,我更改了代码以返回正确的值,并且我设法通过左键单击该角来调用上下文菜单。
Dim p As New Point(LoWord(CInt(lparam)), HiWord(CInt(lparam)))
Dim cap As Rectangle = RectangleToScreen(New Rectangle(0, dwmMargins.cxLeftWidth, Width, dwmMargins.cyTopHeight - dwmMargins.cxLeftWidth))
If cap.Contains(p) Then
Dim mp As Point = MousePosition
mp = PointToClient(mp)
If mp.X < 30 Then
Return New IntPtr(HTSYSMENU)
Else
Return New IntPtr(HTCAPTION)
End If
End If
但是,当右键单击标题栏上的任意位置时,我找不到如何激活对上下文菜单的调用。我尝试覆盖 WndProc 上的消息 WM_NCRBUTTONUP 并发送一条消息以显示上下文菜单,但似乎没有任何反应。
Dim WM_CONTEXTMENU As Integer = &H7B
If m.Msg = WM_NCRBUTTONUP Then
Dim mp As Point = MousePosition
mp = PointToClient(mp)
Dwm.SendMessage(Me.Handle, WM_CONTEXTMENU, Me.Handle, Dwm.MAKEWPARAM(mp.Y, mp.X))
<DllImport("user32.dll")>
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function
我相信我正在尝试重新发明轮子,并且我不需要处理 WM_NCRBUTTONUP 消息来调用上下文菜单,因为它应该自动处理,但我没有在网上找到任何关于它的信息。
解决方案
作为一个选项,您可以处理WM_NCRBUTTONUP
和发送WM_POPUPSYSTEMMENU
:
case WM_NCRBUTTONUP:
{
SendMessage(this.Handle, 0x313/*WM_POPUPSYSTEMMENU*/, (IntPtr)0, m.LParam);
break;
}
我使用的这个签名SendMessage
:
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
推荐阅读
- php - 如何在 HTML/PHP(WordPress 和 Woocommerce)中引用自定义产品类型值
- python - 使用应用脚本将 MS Word 文件(保存在云端硬盘中)转换为 Google Docs
- python - 对 lmfit.minimize 中的参数设置条件
- c - 如何在编译时正确确定支持 _Float16?
- reactjs - 每个下拉选项的工具提示
- python - pymol 没有从终端启动
- javascript - React 的浏览器分析器开发工具实际测量了哪些操作?
- javascript - 当我在javascript中有一个对象时如何创建二维数组?
- sql - 删除满足一个条件的所有记录
- r - 传递给函数时没有适用的 tibble 方法