禁用WPF窗口的Windows任务栏菜单

mum43rcc  于 2023-05-19  发布在  Windows
关注(0)|答案(1)|浏览(202)

我需要禁用Windows任务栏上下文菜单(当鼠标悬停在任务栏上的窗口上时):

我希望它要么是不可见或所有项目变灰或点击任何项目(最重要的-最小化和恢复)被中和
重要提示-解决方案不能依赖于“正常”WPF布线,例如OnStateChanged处理和使用WindowStateSystemCommands将窗口状态恢复到所需状态。欢迎使用低级/非托管/pinvoke/win32代码。

  • 因为我已经大量使用这些,这适用于所有用例,除了用户使用此Windows任务栏命令时。我想不出一个更简单、更稳定的解决方案来完全排除这种情况。
vlju58qv

vlju58qv1#

该菜单被称为“窗口系统菜单”。它可以通过GetSystemMenu检索。它将返回一个 Menu 对象的句柄。
获取菜单句柄后,可以将其传递给ModifyMenu函数以修改其中的菜单项。它需要修改哪些菜单项。您可以使用uPosition参数来给予它。你可以给予一个相对位置,它是从零开始的索引或标识符。系统菜单包含具有预定义标识符的菜单项。它们是SC_MINIMIZESC_MAXIMIZESC_CLOSE等。您可以使用这些标识符来引用要修改的菜单项。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private IntPtr _hwnd = IntPtr.Zero; 
    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        _hwnd = new WindowInteropHelper(this).EnsureHandle();
        IntPtr hSystemMenu = GetSystemMenu(_hwnd, false);
        StringBuilder buffer = new StringBuilder(64);
        int[] itemIDs = new int[2] { SC_MAXIMIZE, SC_MINIMIZE };
        foreach (var itemID in itemIDs)
        {
            buffer.Clear();
            GetMenuString(hSystemMenu, itemID, buffer, 64, MF_BYCOMMAND);
            ModifyMenu(hSystemMenu, itemID, MF_BYCOMMAND | MF_GRAYED, 0, buffer.ToString());
        }
    }
    
    private const int SC_MAXIMIZE = 0xF030;
    private const int SC_MINIMIZE = 0xF020;
    private const int MF_DISABLED = 0x00000002;
    private const int MF_ENABLED = 0x00000000;
    private const int MF_BYCOMMAND = 0x00000000;
    private const int MF_GRAYED = 0x00000001;

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern bool ModifyMenu(IntPtr hMenu, int uPosition, int uFlags, int uIDNewItem, string lpNewItem);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern int GetMenuString(IntPtr hMenu, int uIDItem, [Out] StringBuilder lpString, int cchMax, int flags);
}

相关问题