2010-11-10 8 views
2

J'ai le code suivant, qui ajoute un élément 'Toujours visible' au menu contextuel du système tel qu'affiché sur la fenêtre chrome. Cela fonctionne correctement, mais je voudrais qu'il affiche une coche ou similaire pour indiquer si elle a été activée/désactivée.Rendre un élément de menu contextuel du système WPF basculable

Une idée de comment je peux faire cela?

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

Répondre

4

Vous devez appeler CheckMenuItem chaque fois que vous modifiez Topmost. Voir le CheckMenuItem documentaton pour plus de détails. Voici la signature P/Invoke et constantes, vous aurez besoin:

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

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

Maintenant, pour vérifier l'élément, il suffit:

CheckMenuItem(systemMenuHandle, SettingsSysMenuId, MfChecked); 

et de décocher:

CheckMenuItem(systemMenuHandle, SettingsSysMenuId, MfUnchecked); 
Questions connexes