代码之家  ›  专栏  ›  技术社区  ›  LJW

使WPF系统上下文菜单项可切换

  •  2
  • LJW  · 技术社区  · 14 年前

    知道我怎么做吗?

    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;
    }
    
    1 回复  |  直到 14 年前
        1
  •  4
  •   Ray Burns    14 年前

    每当你换到最上面时,你需要调用CheckMenuItem。见 CheckMenuItem documentaton

    [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);