2014-02-17 83 views
3

我有一個無國界的閃屏形式顯示加載進度和含最小化關閉按鈕(類似濺在Office 2013的屏幕看到的東西)。我也想提供窗口的系統菜單,在窗體的任何地方右鍵單擊打開。如何打開右鍵單擊窗口系統菜單?

Classic system menu of a window

目前我實現通過發送鍵Alt +空格鍵打開菜單。

System.Windows.Forms.SendKeys.SendWait("% ") 'sending Alt+Space 

通過這種方法,窗口的系統菜單總是在窗口的左上角打開。

當用戶右擊窗口的標題欄時,是否有一種以與Windows自然相同的方式以編程方式打開系統菜單的方法?彈出菜單的API調用或消息是否打開?

我想保持在該應用程序提供的系統菜單,因爲我還增加了項目「關於」「設置」在那裏。 (這個應用程序作爲核心應用程序的獨立發射器和更新。)

該平臺是WPFWindows窗體庫在內,太(由於使用SendWait()該解決方法)。如果發佈一些代碼,請隨意選擇VB或C#。

+0

這可能會幫助您: [如何創建WPF中的一個按鈕右鍵單擊快捷菜單] [1] [1]:http://stackoverflow.com/questions/6776911 /如何創建 - 右鍵單擊​​ - 上下文菜單 - 按鈕在WPF – sam

+0

@sam當然,我知道用自定義項目創建右鍵單擊上下文菜單很容易。但是我需要上面顯示的6個項目的「系統菜單」,包括它們正確的語言相關標籤,啓用/禁用狀態和窗口控制操作。每個標準窗口都有這個菜單,問題是如何以編程方式彈出它,因爲當窗口邊框被隱藏時,你不能再通過鼠標右鍵單擊到達菜單。 – miroxlav

回答

3

沒有烘焙的winapi函數來顯示系統菜單。您可以使用pinvoke自行顯示它。 GetSystemMenu()函數返回系統菜單的句柄,通過使用TrackPopupMenu()顯示它,通過調用SendMessage來發送WM_SYSCOMMAND來執行選定的命令。

示例代碼,演示瞭如何做到這一點,包括必要的聲明:

using System.Runtime.InteropServices; 
... 
    private void Window_MouseDown(object sender, MouseButtonEventArgs e) { 
     if (e.ChangedButton == MouseButton.Right) { 
      IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; 
      RECT pos; 
      GetWindowRect(hWnd, out pos); 
      IntPtr hMenu = GetSystemMenu(hWnd, false); 
      int cmd = TrackPopupMenu(hMenu, 0x100, pos.left, pos.top, 0, hWnd, IntPtr.Zero); 
      if (cmd > 0) SendMessage(hWnd, 0x112, (IntPtr)cmd, IntPtr.Zero); 
     } 
    } 
    [DllImport("user32.dll")] 
    static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
    [DllImport("user32.dll")] 
    static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 
    [DllImport("user32.dll")] 
    static extern int TrackPopupMenu(IntPtr hMenu, uint uFlags, int x, int y, 
     int nReserved, IntPtr hWnd, IntPtr prcRect); 
    [DllImport("user32.dll")] 
    static extern bool GetWindowRect(IntPtr hWnd, out RECT rect); 
    struct RECT { public int left, top, right, bottom; } 

注意,您可以顯示菜單任何你想要的,我只是選擇了窗口的左上角。注意位置值以像素爲單位。

+0

創建VB版本,測試 - 效果很好。爲了定位,我將'e.GetPosition(this).X'和'e.GetPosition(this).Y'添加到代碼中使用的值中。 – miroxlav