Можно ли отобразить окно wpf без иконки в строке заголовка?
Как мы все знаем, если значок для окна wpf не определен, то отображается значок по умолчанию. Я хочу отобразить окно без значка в строке заголовка. Я понимаю, что могу использовать пустое изображение, однако это приведет к смещению текста в строке заголовка вправо.
Кто-нибудь знает способ полностью убрать иконку?
(Я пытался найти похожий вопрос, но ничего не смог найти.)
7 ответов
Просто добавьте этот код в ваше окно:
[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 для всего окна. В зависимости от того, должно ли окно выглядеть как "настоящее" окно, потребуется много усилий, чтобы воссоздать стиль по умолчанию в шаблоне.
Я знаю, что на это есть ответ, однако в блоге Дэна Ригсби есть статья, в которой показано, как это сделать, не скрывая поля минимизации / максимизации.
Я обнаружил, что это расстраивало меня, когда я использовал статьи ( здесь и здесь, но он скрывал все кнопки, когда системное меню было скрыто, чтобы помочь мне создать этого помощника, который, как показано выше, вызывает в 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));
}
}
Нет, это не представляется возможным. Цитирование из документации свойства Icon (выделено мной):
Окно 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 вы можете использовать типы форм формования для создания диалогового окна, которое не имеет иконки, но только потому, что это стандарт Windows. Только формы с этими конкретными типами границ не должны иметь значок; это то, что ожидают пользователи.