2010-11-10 80 views
2

我有以下代碼,它將在窗口鑲邊上顯示的系統上下文菜單中的'Always on Top'項添加到'Always on Top'項中。它工作正常,但我希望它顯示一個複選標記或類似的指示是否已打開/關閉。製作一個WPF系統上下文菜單項可切換

任何想法我可以做到這一點?

public RibbonShell() 
{ 
    InitializeComponent(); 

    Loaded += (s,e) => 
       { 
        // Get the Handle for the Forms System Menu 
        var systemMenuHandle = GetSystemMenu(Handle, false); 

        // Create our new System Menu items just before the Close menu item 
        InsertMenu(systemMenuHandle, 5, MfByposition | MfSeparator, 0, string.Empty); // <-- Add a menu seperator 
        InsertMenu(systemMenuHandle, 6, MfByposition, SettingsSysMenuId, "Always on Top"); 

        // Attach our WindowCommandHandler handler to this Window 
        var source = HwndSource.FromHwnd(Handle); 
        source.AddHook(WindowCommandHandler); 
       }; 
} 

#region Win32 API Stuff 

// Define the Win32 API methods we are going to use 
[DllImport("user32.dll")] 
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); 

[DllImport("user32.dll")] 
private static extern bool InsertMenu(IntPtr hMenu, Int32 wPosition, Int32 wFlags, Int32 wIDNewItem, string lpNewItem); 

/// Define our Constants we will use 
private const int WmSyscommand = 0x112; 
private const int MfSeparator = 0x800; 
private const int MfByposition = 0x400; 

#endregion 

// The constants we'll use to identify our custom system menu items 
private const int SettingsSysMenuId = 1000; 

/// <summary> 
/// This is the Win32 Interop Handle for this Window 
/// </summary> 
public IntPtr Handle 
{ 
    get { return new WindowInteropHelper(this).Handle; } 
} 

private IntPtr WindowCommandHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    // Check if a System Command has been executed 
    if (msg == WmSyscommand && wParam.ToInt32() == SettingsSysMenuId) 
    { 
     Topmost = !Topmost; 
     handled = true; 
    } 

    return IntPtr.Zero; 
} 

回答

4

無論何時更改「最上層」,您都需要調用CheckMenuItem。有關詳細信息,請參見CheckMenuItem documentaton。這裏的的P/Invoke簽名和常量你需要:

[DllImport("user32.dll")] 
private static extern bool CheckMenuItem(IntPtr hMenu, Int32 uIDCheckItem, Int32 uCheck); 

private const int MfChecked = 8; 
private const int MfUnchecked = 0; 

我們檢查的項目,只是:

CheckMenuItem(systemMenuHandle, SettingsSysMenuId, MfChecked); 

,並取消:

CheckMenuItem(systemMenuHandle, SettingsSysMenuId, MfUnchecked);