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