首页 > 解决方案 > 打开表单的上下文菜单

问题描述

我想在表单上的最小化按钮旁边添加一个带有一些选项(快捷方式)的下拉菜单。为此,我在代码项目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 消息来调用上下文菜单,因为它应该自动处理,但我没有在网上找到任何关于它的信息。

标签: vb.netwinforms

解决方案


作为一个选项,您可以处理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);

推荐阅读