【发布时间】:2010-12-05 22:32:34
【问题描述】:
众所周知,如果 wpf 窗口的图标未定义,则显示默认图标。我想在标题栏中显示一个没有任何图标的窗口。我意识到我可以使用空白图像,但这会导致标题栏中的文本向右偏移。
有谁知道完全删除图标的方法吗?
(我尝试搜索类似的问题,但找不到任何内容。)
【问题讨论】:
标签: wpf xaml dialog titlebar application-icon
众所周知,如果 wpf 窗口的图标未定义,则显示默认图标。我想在标题栏中显示一个没有任何图标的窗口。我意识到我可以使用空白图像,但这会导致标题栏中的文本向右偏移。
有谁知道完全删除图标的方法吗?
(我尝试搜索类似的问题,但找不到任何内容。)
【问题讨论】:
标签: wpf xaml dialog titlebar application-icon
简单,将此代码添加到您的窗口中:
[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);
}
【讨论】:
虽然不是完全正确的解决方案,但您可以尝试以下方法之一:
将 WindowStyle-Property 设置为 ToolWindow 会使图标消失,但标题栏(显然)会变小。
为整个窗口编写一个 ControlTemplate。根据窗口是否必须看起来像“真实”窗口,尝试在模板中重新创建默认样式会付出很多努力。
【讨论】:
我知道这已得到解答,但是 Dan Rigsby's blog 有一篇文章展示了如何在不隐藏最小化/最大化框的情况下做到这一点。
我发现这让我很沮丧,因为我正在使用文章(here 和 here,但是当隐藏 sysmenu 时它一直隐藏所有按钮,以帮助我创建了这个助手,如上所示,在 @987654324 中调用@。
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));
}
}
【讨论】:
不,这似乎是不可能的。引用Icon property 的文档(强调我的):
一个WPF窗口总是显示一个图标。当没有通过设置Icon提供时,WPF根据以下规则选择一个图标显示:
- 如果指定,请使用程序集图标。
- 如果未指定程序集图标,请使用默认的 Microsoft Windows 图标。
如果使用 Icon 指定自定义窗口图标,可以通过将 Icon 设置为
null来恢复默认应用程序图标。
因此,显然完全透明的图标似乎是您最好的选择。或者也许通过使用 Windows API 函数在窗口上设置适当的样式来解决所有这些问题。但这可能会干扰 WPF 的窗口管理。
【讨论】:
您可以使用一个空的 png 图片并将其转换为图标并将其设置为您的窗口的图标!!!
【讨论】:
将以下代码添加到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);
}
【讨论】:
我的第一个建议是不要这样做。在 WinForms 中,您可以使用 formborderstyles 类型来创建一个没有图标的对话框,但这仅仅是因为这是 Windows 标准。只有具有这些特定边框类型的表单才应该没有图标;这是用户的期望。
【讨论】:
ShowIcon 属性。