WPF: почему в окне сообщений нет значка на заголовке - PullRequest
4 голосов
/ 18 ноября 2010

Все, что я хочу, это чтобы в моем окне сообщений отображался значок моего приложения (или любой другой значок) в заголовке, но это не так, почему бы и нет?

Ответы [ 2 ]

7 голосов
/ 19 ноября 2010

MessageBox в WPF - это просто оболочка для стандартного MessageBox в user32.dll, который является точно такой же функцией, которую сама Windows вызывает для отображения диалогового окна. коробка. В ваших приложениях WPF он не будет выглядеть иначе, чем в любом другом приложении, использующем Win32 API (включая WinForms, MFC и т. Д.).

Используя Reflector, вы можете убедиться в этом, просмотрев соответствующую функцию, вызываемую MessageBox в WPF. Обратите особое внимание на последнюю строку кода, где он вызывает UnsafeNativeMethods.MessageBox:

[SecurityCritical]
private static MessageBoxResult ShowCore(IntPtr owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
    if (!IsValidMessageBoxButton(button))
    {
        throw new InvalidEnumArgumentException("button", (int) button, typeof(MessageBoxButton));
    }
    if (!IsValidMessageBoxImage(icon))
    {
        throw new InvalidEnumArgumentException("icon", (int) icon, typeof(MessageBoxImage));
    }
    if (!IsValidMessageBoxResult(defaultResult))
    {
        throw new InvalidEnumArgumentException("defaultResult", (int) defaultResult, typeof(MessageBoxResult));
    }
    if (!IsValidMessageBoxOptions(options))
    {
        throw new InvalidEnumArgumentException("options", (int) options, typeof(MessageBoxOptions));
    }
    if ((owner != IntPtr.Zero) && ((options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != MessageBoxOptions.None))
    {
        throw new ArgumentException(SR.Get(SRID.CantShowMBServiceWithOwner, new object[0]));
    }
    int type = (int) (((button | ((MessageBoxButton) ((int) icon))) | DefaultResultToButtonNumber(defaultResult, button)) | ((MessageBoxButton) ((int) options)));
    IntPtr zero = IntPtr.Zero;
    if ((options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) == MessageBoxOptions.None)
    {
        if (owner == IntPtr.Zero)
        {
            zero = UnsafeNativeMethods.GetActiveWindow();
        }
        else
        {
            zero = owner;
        }
    }
    return Win32ToMessageBoxResult(UnsafeNativeMethods.MessageBox(new HandleRef(null, zero), messageBoxText, caption, type));
}

Как вы заметили, в этом окне сообщения не отображается значок в строке заголовка. Это связано с тем, что его окно создается без указания стилей WS_CAPTION и WS_SYSMENU. И , хотя возможно , нет простого способа создать подкласс MessageBox и , предоставляемых user32.dll, изменить стили окна , чтобы отобразить значок в строке заголовка. Результирующий код выглядит беспорядочно и, честно говоря, не стоит хлопот.

Лучшее решение - просто создать свое собственное диалоговое окно и вместо этого вызвать его из своего кода. У этого есть множество других преимуществ, помимо возможности добавления значка, в том числе исправление любых проблем совместимости с WPF (вы будете использовать полностью управляемый код) и возможность настраивать темы диалогового окна по мере необходимости в соответствии с пользовательской темой, используемой в вашем приложении. , Попробуйте что-то вроде этого, чтобы помочь вам начать.


В качестве альтернативы, если вам не нужно ориентироваться на предыдущие версии Windows (те, что были до Vista), вы можете использовать TaskDialog, предоставленную в версии 6 COMCTRL32.DLL, которая заменяет и улучшает стандарт MessageBox. Однако это не входит в стандартный класс в .NET Framework, поэтому вам придется P / Invoke . Смотрите здесь для одного из многих доступных примеров.

Есть также несколько примеров проектов, которые стоит изучить, которые используют TaskDialog в версиях Windows, где она доступна, и эмулируют ее в предыдущих версиях, где ее нет. (Лично я использую что-то очень похожее во многих моих приложениях .NET.)

0 голосов
/ 18 ноября 2010

Вы можете создать свое собственное окно сообщения - просто создать пользовательский элемент управления (с вашими изображениями, анимацией, видео или чем-то еще ...) и вызвать ShowDialog, вы можете начать с этот пример .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...