c# - 将系统默认上下文菜单添加到无边框 Windows 窗体

标签 c# .net vb.net winforms contextmenu

我从我的 Windows 窗体中删除了默认边框并创建了我自己的标题,我想提供与默认 Windows 相同的功能。

其中之一是右键单击时显示的上下文菜单:

Default Context Menu

是否可以将其分配给我的服装 header ?

如果您想发布代码,我更喜欢 vb,但 c# 也可以。

最佳答案

默认情况下,无边框表单没有系统菜单。您应该首先通过添加 WS_SYSMENU 为表单启用系统菜单款式 CreateParams .然后你可以发送WM_POPUPSYSTEMMENUOnMouseDown中的窗口.

C#

设置 this.FormBorderStyle = Windows.Forms.FormBorderStyle.None; 然后:

private const int WS_SYSMENU = 0x80000;
private const int WS_MINIMIZEBOX = 0x20000;
private const int WS_MAXIMIZEBOX = 0x10000;
protected override CreateParams CreateParams
{
    get
    {
        CreateParams p = base.CreateParams;
        p.Style = WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
        return p;
    }
}

[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg,
    IntPtr wParam, IntPtr lParam);
private const int WM_POPUPSYSTEMMENU = 0x313;
protected override void OnMouseDown(MouseEventArgs e)
{
    base.OnMouseDown(e);
    if (e.Button == System.Windows.Forms.MouseButtons.Right)
    {
        var p = MousePosition.X + (MousePosition.Y * 0x10000);
        SendMessage(this.Handle, WM_POPUPSYSTEMMENU, (IntPtr)0, (IntPtr)p);
    }
}

VB.NET

设置 Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None 然后:

Private Const WS_SYSMENU As Integer = &H80000
Private Const WS_MINIMIZEBOX As Integer = &H20000
Private Const WS_MAXIMIZEBOX As Integer = &H10000
Protected Overrides ReadOnly Property CreateParams As System.Windows.Forms.CreateParams
    Get
        Dim p = MyBase.CreateParams
        p.Style = WS_SYSMENU + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
        Return p
    End Get
End Property

<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, _
    ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Private Const WM_POPUPSYSTEMMENU As Integer = &H313
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
    MyBase.OnMouseDown(e)
    If e.Button = MouseButtons.Right Then
        Dim p = MousePosition.X + (MousePosition.Y * &H10000)
        SendMessage(Me.Handle, WM_POPUPSYSTEMMENU, 0, p)
    End If
End Sub

注意

WM_POPUPSYSTEMMENU 没有记录但可以正常工作。如果您想使用记录的方式,您可以使用 GetSystemMenu 获取系统菜单然后使用 TrackPopupMenu 显示它并使用 SendMessage执行返回的命令。,你可以声明:

Private Const TPM_LEFTBUTTON As Integer = &H0
Private Const TPM_RIGHTBUTTON As Integer = &H2
Private Const TPM_RETURNCMD As Integer = &H100
Private Const WM_SYSCOMMAND As Integer = &H112
<DllImport("user32.dll")> _
Private Shared Function GetSystemMenu(ByVal hWnd As IntPtr, _
    ByVal bRevert As Boolean) As IntPtr
End Function
<DllImport("user32.dll")>
Private Shared Function TrackPopupMenu(ByVal hMenu As IntPtr, ByVal uFlags As Integer, _
    ByVal x As Integer, ByVal y As Integer, ByVal nReserved As Integer, _
    ByVal hWnd As IntPtr, ByVal prcRect As IntPtr) As Integer
End Function
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, _
    ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function

并以这种方式显示菜单:

Dim menu = GetSystemMenu(Me.Handle, False)
Dim command = TrackPopupMenu(menu, TPM_RETURNCMD + TPM_LEFTBUTTON + TPM_RIGHTBUTTON, _
                    MousePosition.X, MousePosition.Y, IntPtr.Zero, _
                    Me.Handle, IntPtr.Zero)
If (command > 0) Then
    SendMessage(Me.Handle, WM_SYSCOMMAND, command, IntPtr.Zero)
End If

关于c# - 将系统默认上下文菜单添加到无边框 Windows 窗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38867093/

相关文章:

c# - WCF 跟踪代码

.net - 如何找出.NET Windows窗体中关注焦点的控件?

c# - Linux 下 AutoResetEvent 的 C++ 等价物是什么?

mysql - 更新mysql数据库中的日期

VB.Net Office 互操作 - Excel 进程未关闭

c# - 如何将异步方法放入列表中并迭代调用它们?

C# Protobuf 禁用空检查

c# - 为什么我没有收到 "Cross-thread operation not valid"错误

vb.net - 将 XML 文件加载到 VB.Net 结构中

c# - 在 C# 程序中从 Firefox 获取网页内容