29

众所周知,如果 wpf 窗口的图标未定义,则显示默认图标。我想在标题栏中显示一个没有任何图标的窗口。我意识到我可以使用空白图像,但这会导致标题栏中的文本向右偏移。

有谁知道完全删除图标的方法?

(我尝试搜索类似的问题,但找不到任何东西。)

4

7 回答 7

31

很简单,将此代码添加到您的窗口中:

[DllImport("user32.dll")]
static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

private const int GWL_STYLE = -16;

private const uint WS_SYSMENU = 0x80000;

protected override void OnSourceInitialized(EventArgs e)
{
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    SetWindowLong(hwnd, GWL_STYLE,
        GetWindowLong(hwnd, GWL_STYLE) & (0xFFFFFFFF ^ WS_SYSMENU));

    base.OnSourceInitialized(e);
}
于 2009-10-13T10:58:38.607 回答
17

虽然不完全是正确的解决方案,但您可以尝试以下方法之一:

  1. 将 WindowStyle-Property 设置为 ToolWindow 将使图标消失,但标题栏(显然)会更小。

  2. 为整个窗口编写一个 ControlTemplate。根据窗口是否必须看起来像“真实”窗口,尝试在模板中重新创建默认样式会付出很多努力。

于 2009-10-12T10:15:19.747 回答
11

我知道这是有答案的,但是Dan Rigsby 的博客有一篇文章展示了如何在不隐藏最小化/最大化框的情况下做到这一点。

我发现这让我感到沮丧,因为我正在使用这些文章(herehere,但是当系统菜单被隐藏时它一直隐藏所有按钮,以帮助我创建这个助手,如上所示调用OnSourceInitialized

public static class WpfWindowHelper {

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

    public const int GWL_EXSTYLE = -20;
    public const int WS_EX_DLGMODALFRAME = 0x0001;
    public const int SWP_NOSIZE = 0x0001;
    public const int SWP_NOMOVE = 0x0002;
    public const int SWP_NOZORDER = 0x0004;
    public const int SWP_FRAMECHANGED = 0x0020;
    public const int GWL_STYLE = -16;
    public const int WS_MAXIMIZEBOX = 0x00010000;
    public const int WS_MINIMIZEBOX = 0x00020000;
    public const int WS_SYSMENU = 0x00080000;

    public static void HideSysMenu(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
        SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
        SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    }

    public static void HideMinimizeBox(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MINIMIZEBOX));
    }

    public static void HideMaximizeBox(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MAXIMIZEBOX));
    }

    public static void HideMinimizeAndMaximizeBoxes(this Window w) {
        IntPtr hwnd = new WindowInteropHelper(w).Handle;
        SetWindowLong(hwnd, GWL_STYLE,
            GetWindowLong(hwnd, GWL_STYLE) & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
    }

}
于 2011-05-16T22:37:43.360 回答
10

不,这似乎是不可能的。引用Icon 属性的文档(强调我的):

WPF 窗口始终显示一个图标。当未通过设置 Icon 提供时,WPF 根据以下规则选择要显示的图标:

  1. 如果指定,请使用程序集图标。
  2. 如果未指定程序集图标,请使用默认的 Microsoft Windows 图标。

如果使用 Icon 指定自定义窗口图标,则可以通过将 Icon 设置为 来恢复默认应用程序图标null

所以,显然一个完全透明的图标似乎是你最好的选择。或者也许通过使用 Windows API 函数在窗口上设置适当的样式来解决所有这些问题。但这可能会干扰 WPF 的窗口管理。

于 2009-10-12T10:09:20.823 回答
6

您可以使用空的 png 图像并将其转换为图标并将其设置为窗口的图标!!!

在此处输入图像描述

于 2015-02-09T08:32:51.320 回答
0

将以下代码添加到您的主类中,Window以删除最大化和最小化按钮,并隐藏图标。

private const uint WS_MINIMIZEBOX = 0x00020000;
private const uint WS_MAXIMIZEBOX = 0x00010000;
private const int GWL_STYLE = -16;
private const int GWL_EXSTYLE = -20;
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_SYSCOMMAND = 0x0112;
private const int WM_SETICON = 0x0080;
private const int WS_EX_DLGMODALFRAME = 0x0001;

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll")]
private static extern uint GetWindowLong(IntPtr hwnd, int index);

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

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

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    
    IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    uint styles = GetWindowLong(hwnd, GWL_STYLE);

    // Remove the maximize and minimize buttons
    styles &= 0xFFFFFFFF ^ (WS_MINIMIZEBOX | WS_MAXIMIZEBOX);
    SetWindowLong(hwnd, GWL_STYLE, styles);
    
    // Change to dialog modal - necessary for the final step to work!
    styles = GetWindowLong(hwnd, GWL_EXSTYLE);
    styles |= WS_EX_DLGMODALFRAME;
    SetWindowLong(hwnd, GWL_EXSTYLE, styles);

    SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    ((HwndSource)PresentationSource.FromVisual(this)).AddHook(HelpButtonHook);

    // Remove the icon
    SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
    SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);
}
于 2021-05-07T20:15:57.783 回答
-2

我的第一个建议是不要这样做。在 WinForms 中,您可以使用 formborderstyles 类型来创建一个没有图标的对话框,但这仅仅是因为这是 Windows 标准。只有具有这些特定边框类型的表单才应该没有图标;这是用户所期望的。

于 2009-10-12T10:10:29.623 回答