2016-08-10 36 views
2

Windowsフォームからデフォルトボーダーを削除し、デフォルトのウィンドウと同じ機能を提供する独自のヘッダーを作成しました。それらのボーダーレスWindowsフォームにシステムのデフォルトコンテキストメニューを追加

一つのマウスを右クリックで表示されるコンテキストメニューです:

Default Context Menu

私costumヘッダにこれを割り当てる可能性がありますか?

コードを投稿したいのであれば、私はVBを好むでしょうが、C#も大丈夫です。

+0

他のオプションのコードは、あなたが何かを試しましたか? – BugFinder

+0

@BugFinderコンテキストメニューを再作成したくない場合は、何とかシステムデフォルトを呼び出したい – Error404

+0

@VisualVincent私の質問はWindowsフォームとWPFについてのもう1つの理由から間違って重複してマークされました – Error404

答えて

3

ボーダーレスフォームには、デフォルトでシステムメニューがありません。まず、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は文書化されていませんが、完全に機能しています。 。

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 

をしてメニューをこのように示しています:あなたはGetSystemMenuを使用してシステムメニューを取得し、それがTrackPopupMenuを使用して、返されたコマンドを実行SendMessageを使用して表示することができ、文書化の方法を使用する場合は、宣言することができます

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

がほぼ完全に動作していることを思い出しました。 - メニューの移動オプションとポジショニングは機能しません。 – Error404

+1

それは動作する方法です。移動にはタイトルバーが必要です。あるいは、ボーダレスフォームを移動するためのソリューションを使用することもできます。 –

+0

ポジショニングパートで何を変更しなければならないのですか?Moce Optionを動作させるにはどうすればいいですか(私は移動のためのコードを持っていますが、それを実装する方法) – Error404

関連する問題