是否可以显示标题栏中没有图标的 wpf 窗口?

发布于 2024-08-07 16:15:22 字数 147 浏览 4 评论 0原文

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

有谁知道有什么方法可以彻底删除图标吗?

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

As we all know, if the icon for a wpf window is undefined then the default icon is displayed. I want to display a window without any icon in the title bar. I realise that I could use a blank image, however this would cause the text in the title bar to be offset to the right.

Does anyone know of a way to completely remove the icon?

(I tried searching for a similar question but couldn't find anything.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

醉梦枕江山 2024-08-14 16:15:22

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

[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);
}

Simple, add this code to your window:

[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);
}
小姐丶请自重 2024-08-14 16:15:22

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

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

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

While not exactly a proper solution, you could try one of the following things:

  1. Setting the WindowStyle-Property to ToolWindow will make the Icon disappear, but the title bar (obviously) will be smaller.

  2. Write a ControlTemplate for the whole Window. Depending on if the Window has to look like a "real" Window, there'd be much effort into trying to recreate the default Style in the Template.

遇见了你 2024-08-14 16:15:22

我知道这个问题已经得到解答,但是 Dan Rigsby 的博客< /a> 有一篇文章展示了如何在不隐藏最小化/最大化框的情况下执行此操作。

我发现这让我很沮丧,因为我正在使用这些文章(此处 和 此处 但它一直隐藏所有按钮系统菜单被隐藏,以帮助我创建这个帮助程序,如上所示,在 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));
    }

}

I know this is answered, however Dan Rigsby's blog has an article that shows how to do this without hiding the minimize/maximize boxes.

I found this was frustrating me as I was using the articles (here and here but it kept hiding all the buttons when the sysmenu was hidden, to help I created this helper which as shown above call in 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));
    }

}
转瞬即逝 2024-08-14 16:15:22

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

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

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

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

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

No, this doesn't seem to be possible. Quoting from the documentation of the Icon property (emphasis mine):

A WPF window always displays an icon. When one is not provided by setting Icon, WPF chooses an icon to display based on the following rules:

  1. Use the assembly icon, if specified.
  2. If the assembly icon is not specified, use the default Microsoft Windows icon.

If you use Icon to specify a custom window icon, you can restore the default application icon by setting Icon to null.

So, apparently a completely transparent icon seems to be your best bet here. Or perhaps hack around all this by using Windows API functions to set the appropriate style on the window. But this may interfere with WPF's window management.

最美不过初阳 2024-08-14 16:15:22

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

在此处输入图像描述

You can use an empty png image and convert it to icon and set it as icon for your window!!!

enter image description here

终弃我 2024-08-14 16:15:22

将以下代码添加到 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);
}

Add the following code to the main class of your Window to remove the maximize and minimize buttons, and hide the icon.

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);
}
ぺ禁宫浮华殁 2024-08-14 16:15:22

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

My first suggestion would be don't do it. In WinForms you can use types of formborderstyles to create a dialog box that has no icon, but only because that is a Windows standard. Only forms with those specific border types should have no icon; it's what users expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文