当在Visual Studio之外运行时,如何从WPF窗口中移除图标?

8
我使用了 在WPF窗口中移除图标的方法 来移除应用程序窗口的图标(使用附加属性答案),这在通过Visual Studio 2010运行时效果很好。但是,在正常运行应用程序时,图标仍然会显示。
该窗口没有分配给其“Icon”属性的图标,但是应用程序在其属性(Application > Resources > Icon)中定义了一个图标,这个图标被显示为窗口图标。
我该如何解决这种行为上的差异,以便在Visual Studio 2010之外运行应用程序时不显示图标?

我在一个小的WPF应用程序的MainWindow中使用了参考答案中的代码来移除图标。它在Visual Studio中工作,并且从我的项目的Bin\Debug文件夹运行时也能正常工作。是否还有其他一些细节可能会影响它的工作? - Ritch Melton
2个回答

3
我进行了一些调查; 有一个StackOverflow问题解决了您的问题。具有讽刺意味的是,这个修复只在Visual Studio之外起作用。
答案的相关部分(由Zach Johnson提供):
似乎WS_EX_DLGMODALFRAME只有在WPF窗口的本机Win32窗口没有与其关联的图标时才会删除该图标。 WPF(方便地)使用应用程序的图标作为所有未明确设置图标的窗口的默认图标。 通常,这不会造成任何问题,并节省我们手动在每个窗口上设置应用程序的图标的麻烦; 然而,当我们尝试删除图标时,它会给我们带来问题。
由于问题在于WPF自动为我们设置窗口的图标,因此我们可以发送WM_SETICON到Win32窗口,以在应用WS_EX_DLGMODALFRAME时重置其图标。
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之外运行时才起作用。


假设您将GetWindowLongPtr和SetWIndowLongPtr替换为GetWindowLongSetWindowLong(像使用currentStyle | WS_EX_DLGMODALFRAME一样对IntPtr和int进行OR运算不起作用)。不幸的是,这段代码对我不起作用。在回答之前,您测试过它吗?(此外,它不能编译,因为在此引用的答案中没有任何代码可以使用NativeMethods.GetWindowLongPtr - Rob

0

也许 Shell 集成库是您的选择?它包含这个 WindowChrome 类来自定义非客户区域,使您可以忽略图标。


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