WPF - 从模态窗口中删除系统菜单图标,但不是主应用程序窗口

时间:2010-06-22 19:15:00

标签: wpf menu system icons

我正在尝试(在WPF中):

  1. 有一个.exe文件,显示系统菜单图标(窗口左上角的图标),就像正常一样
  2. 此应用程序调用的模态窗口中没有显示此图标
  3. 我在这里尝试了解决方案: 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

    但是,如果我将.ico文件添加到.exe的项目属性(属性 - >应用程序 - >图标和清单),它将停止工作。您可以使用可下载的示例尝试此操作。

    似乎.exe中的图标也用在模式窗口中(我们在.dll文件中也有),即使该.dll的属性显示为“默认图标”。它必须从.exe传递下来。那么,有没有办法在主窗口上显示图标,而不是在子窗口上显示?

    可能更简单的方法是:即使项目属性中指定了.ico文件,是否可以删除图标?

    我发现的唯一工作就是将模态窗口的WindowStye设置为“ToolWindow”。这给了我几乎我想要的东西:没有图标和“关闭”按钮(右上角的“x”)仍然存在。然而,x是超小的。这是最好的吗?

    感谢您的帮助。

1 个答案:

答案 0 :(得分:6)

我有同样的问题。当WPF窗口的本机Win32窗口没有与之关联的图标时,WS_EX_DLGMODALFRAME似乎仅删除图标。 WPF(方便地)使用应用程序的图标作为所有窗口的默认图标,没有明确设置的图标。通常情况下,这不会导致任何问题,并且可以省去在每个窗口上手动设置应用程序图标的麻烦。但是,当我们尝试删除图标时,它会给我们带来问题。

由于问题是WPF会自动为我们设置窗口的图标,因此我们可以在应用WS_EX_DLGMODALFRAME时将WM_SETICON发送到Win32窗口以重置其图标。

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外部运行时才有效。