Можно ли отобразить окно 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);
}

Хотя это не совсем правильное решение, вы можете попробовать одну из следующих вещей:

  1. Если установить WindowStyle-Property в ToolWindow, значок исчезнет, ​​но заголовок (очевидно) будет меньше.

  2. Напишите 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 выбирает значок для отображения на основе следующих правил:

  1. Используйте значок сборки, если указан.
  2. Если значок сборки не указан, используйте значок 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. Только формы с этими конкретными типами границ не должны иметь значок; это то, что ожидают пользователи.

Другие вопросы по тегам