Error404 Error404 - 3 months ago 22
Vb.net Question

Add System Default Context Menu to Borderless Windows Form

I removed the default Border from my Windows Form and created my own header which i want to give the same features as the default windows one.

One of them is the context Menu that is displayed on Right Mouse Click:

Default Context Menu

Is there a possibility to assign this to my costum header?

If you want to post code I would prefer vb, but c# is also okay.

Answer

A border-less form doesn't have system menu by default. You should first enable system menu for the form by adding WS_SYSMENU style in CreateParams. Then you can send WM_POPUPSYSTEMMENU to the window in OnMouseDown.

VB.NET

Set Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None then:

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

C#

Set this.FormBorderStyle = Windows.Forms.FormBorderStyle.None; then:

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);
    }
}