2016-08-10 5 views
2

Я удалил по умолчанию Border из своей Windows Form и создал свой собственный заголовок, который я хочу предоставить тем же функциям, что и окна по умолчанию.Добавить системное контекстное меню по умолчанию в безграничную форму Windows

Одним из них является контекстное меню, которое отображается на правую кнопку мыши:

Default Context Menu

Есть возможность назначить это мой заголовок Costum?

Если вы хотите опубликовать код, я бы предпочел vb, но C# тоже в порядке.

+0

Что вы пробовали, кроме как переместить, код для других вариантов смехотворно прост, так что вы пробовали? – BugFinder

+0

@BugFinder Я не хочу воссоздавать контекстное меню, я хочу как-то вызвать Систему по умолчанию – Error404

+0

@VisualVincent Это было ложно отмечено как дубликат, потому что мой вопрос касался Windows Form, а другой - WPF – Error404

ответ

3

Форма без границ по умолчанию не имеет системного меню. Сначала вы должны включить системное меню для формы, добавив WS_SYSMENU стиль в CreateParams. Затем вы можете отправить WM_POPUPSYSTEMMENU в окно OnMouseDown.

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 
+0

почти отлично работает - Move Option и позиционирование меню не работают – Error404

+1

Так оно и работает. Перемещение требует заголовка.Или вы можете альтернативно использовать решения, доступные для перемещения форм без полей. –

+0

Что мне нужно изменить для позиции позиционирования и как я могу сделать работу с Moce Option (я получил код для перемещения, но как его реализовать) – Error404

Смежные вопросы