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

时间:2009-10-12 10:02:45

标签: wpf xaml dialog titlebar application-icon

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

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

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

7 个答案:

答案 0 :(得分:26)

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

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

答案 1 :(得分:17)

虽然不是一个恰当的解决方案,但您可以尝试以下方法之一:

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

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

答案 2 :(得分:10)

不,这似乎不可能。引自Icon property(强调我的)的文档:

  

WPF窗口始终显示图标。如果未通过设置图标提供图标,WPF会根据以下规则选择要显示的图标:

     
      
  1. 使用装配图标(如果已指定)。
  2.   
  3. 如果未指定程序集图标,请使用默认的Microsoft Windows图标。
  4.         

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

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

答案 3 :(得分:10)

我知道这已得到解答,但Dan Rigsby's blog有一篇文章说明如何在不隐藏最小化/最大化框的情况下执行此操作。

我发现这令我感到沮丧,因为我正在使用文章(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));
    }

}

答案 4 :(得分:7)

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

enter image description here

答案 5 :(得分: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);
}

答案 6 :(得分:-1)

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