Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何隐藏WPF窗口图标并使用ResizeMode=NoResize?_C#_Wpf - Fatal编程技术网

C# 如何隐藏WPF窗口图标并使用ResizeMode=NoResize?

C# 如何隐藏WPF窗口图标并使用ResizeMode=NoResize?,c#,wpf,C#,Wpf,我最近实现了从中隐藏WPF窗口图标的解决方案。我发现,当该解决方案与ResizeMode=NoResize结合使用时,应用程序的标题栏上下文菜单无法禁用最小/最大/调整大小选项 奇怪的是,上下文菜单没有错误地启用某些选项,它只是在图标隐藏之前保留上下文菜单的状态。我使用一个简单的测试应用程序发现了这一点,该应用程序可以进行必要的调用以隐藏图标,并可以动态更新窗口的ResizeMode 图标显示,ResizeMode=CanResize 标题栏按钮和关联菜单正确无误 图标隐藏,ResizeMod

我最近实现了从中隐藏WPF窗口图标的解决方案。我发现,当该解决方案与
ResizeMode=NoResize
结合使用时,应用程序的标题栏上下文菜单无法禁用最小/最大/调整大小选项

奇怪的是,上下文菜单没有错误地启用某些选项,它只是在图标隐藏之前保留上下文菜单的状态。我使用一个简单的测试应用程序发现了这一点,该应用程序可以进行必要的调用以隐藏图标,并可以动态更新窗口的
ResizeMode

图标显示,ResizeMode=CanResize

标题栏按钮和关联菜单正确无误

图标隐藏,ResizeMode=CanResize

仍然正确

图标隐藏,ResizeMode=NoResize

标题栏按钮已正确隐藏,但关联菜单保留其以前的状态。如果我切换到
CanMinimize
,然后切换到
NoResize
,关联菜单将只启用“Minimize”

当一个可调整大小的WPF窗口启动另一个设置为
NoResize
(并且您正在隐藏图标)的窗口时,这将成为一个问题

问题

是否有其他Windows API函数可以强制上下文菜单重新评估其状态?那么,
NoResize
选项可能会导致这种奇怪的行为呢?由于这只会影响
NoResize
选项,是否可以在WPF级别找到解决方法


编辑-我的目标是避免使用
WindowStyle=ToolWindow
WS_EX_ToolWindow
扩展窗口样式。在过去,我发现这种窗口样式有一些问题,其中一个是被描述的。我的整个方法的目标之一是模拟
工具窗口的外观,而不必实际使用它。

使用.NET 4.0和Windows 8.1 Enterprise(我不知道它是否适用于其他.NET版本或不同的操作系统),您只需要使用
WS_EX_工具窗口
扩展样式,而不是
WS_EX_DLGMODALFRAME
样式

因此,代码将是:

public partial class MainWindow : Window
{
    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hwnd, int index);

    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags);

    [DllImport("user32.dll")]
    static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam);

    private const int GWL_EXSTYLE = -20;
    private const int WS_EX_DLGMODALFRAME = 0x0001;
    private const int SWP_NOSIZE = 0x0001;
    private const int SWP_NOMOVE = 0x0002;
    private const int SWP_NOZORDER = 0x0004;
    private const int SWP_FRAMECHANGED = 0x0020;
    private const int WM_SETICON = 0x0080;
    private const int WS_EX_TOOLWINDOW = 0x00000080;

    public MainWindow()
    {
        InitializeComponent();
        ResizeMode = System.Windows.ResizeMode.NoResize;
    }

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);

        IntPtr hwnd = new WindowInteropHelper(this).Handle;

        int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TOOLWINDOW);

        SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
        SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);

        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | 
            SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }
}

希望它能对您有所帮助。

您采用了哪种解决方案?o-toole-kit的还是Sheridan的?组合。我做
SetWindowLong…SendMessage…SendMessage…SetWindowPos
。仅使用其中一个似乎不起作用。我认为这是一个有效的答案,但我试图避免使用
toolswindow
。如前所述,
ToolWindow
具有一些不良副作用。我将相应地更新我的问题。如果您想使用
SetWindowLong
,恐怕没有其他方法@Michael。你是否考虑创建一个空图标并将它用于你的窗口?这可能是我们暂时的方式。当一个窗口被设置为使用
NoResize
时,只需显示一个存根透明图标,而不是隐藏它。不太理想,但你可能是目前最好的。