WPF - 如何从模态窗口中移除系统菜单图标,但不影响主应用程序窗口

3
我正在尝试在WPF中实现以下功能:
1. 有一个.exe文件,像正常情况下一样显示系统菜单图标(窗口左上角的图标)。 2. 不要让这个图标出现在由此应用程序调用的模态窗口中。
我尝试了这里的解决方案:Removing Icon from a WPF window,并且它有效。同样的东西也可以在这里下载:http://blogs.msdn.com/b/wpfsdk/archive/2007/08/02/a-wpf-window-without-an-window-icon-the-thing-you-click-to-get-the-system-menu.aspx。但是,如果我向.exe的项目属性(属性->应用程序->图标和清单)添加.ico文件,则不起作用。您可以使用可下载示例尝试此操作。即使该.dll的属性为“默认图标”,似乎也会在模态窗口中使用来自.exe的图标。它必须从.exe传递下来。因此,是否有一种方法可以在主窗口上显示图标,但在子窗口上不显示?
可能更简单的问题是:即使在项目的属性中指定了.ico文件,是否仍然可以删除图标?
我找到的唯一有效方法是将模态窗口的WindowStye设置为“ToolWindow”。这几乎可以实现我的要求:没有图标,但“关闭”按钮(右上角的“x”)仍然存在。不过,x非常小。这是最好的方法吗?
感谢任何帮助。
1个回答

6
我遇到了同样的问题。看起来,只有在WPF窗口的本地Win32窗口没有关联图标时,WS_EX_DLGMODALFRAME才会删除图标。WPF(方便地)使用应用程序的图标作为所有未明确设置图标的窗口的默认图标。通常,这不会引起任何问题,并节省了我们手动在每个窗口上设置应用程序图标的麻烦;然而,在我们尝试删除图标时,它会给我们带来问题。
由于问题在于WPF自动为我们设置窗口图标,因此当我们应用WS_EX_DLGMODALFRAME时,我们可以向Win32窗口发送WM_SETICON来重置其图标。
const int WM_SETICON = 0x0080;
const int ICON_SMALL = 0;
const int ICON_BIG = 1;

[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SendMessage(
    IntPtr hWnd, 
    int msg,
    IntPtr wParam, 
    IntPtr lParam);

移除图标的代码:

IntPtr hWnd = new WindowInteropHelper(window).Handle;
int currentStyle = NativeMethods.GetWindowLongPtr(hWnd, GWL_EXSTYLE);

SetWindowLongPtr(
    hWnd,
    GWL_EXSTYLE,
    currentStyle | WS_EX_DLGMODALFRAME);

// reset the icon, both calls important
SendMessage(hWnd, WM_SETICON, (IntPtr)ICON_SMALL, IntPtr.Zero);
SendMessage(hWnd, WM_SETICON, (IntPtr)ICON_BIG, IntPtr.Zero);

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

编辑:哦,看起来只有在Visual Studio之外运行应用程序时才有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接