WPF:为什么没有消息框在标题栏上有图标

Nit*_*ari 4 wpf icons messagebox

我想要的只是我的消息框应该在其标题栏中显示我的应用程序的图标(或任何其他图标),但它没有,为什么不呢?

Cod*_*ray 7

MessageBox在WPF简直就是标准的包装MessageBoxuser32.dll,这正是Windows本身调用显示一个对话框相同的功能.在WPF应用程序中,它看起来不会与依赖Win32 API(包括WinForms,MFC等)的任何其他应用程序有任何不同.

使用Reflector,您可以通过查看MessageBoxWPF中调用的相关函数来验证这一点.特别注意最后一行代码,它调用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));
}
Run Code Online (Sandbox Code Playgroud)

正如您所注意到的,此消息框在其标题栏上不显示图标.这是因为它的窗口是在没有指定WS_CAPTIONWS_SYSMENU样式的情况下创建的.而且虽然是可能的,有子类user32.dll中提供的没有简单的方法MessageBox,并改变它的窗口样式,以显示其标题栏上的图标.由此产生的代码很难看,坦白说不值得.

最好的解决方案是简单地创建自己的对话框,并从代码中调用它.除了添加图标的能力之外,这还有许多其他优点,包括修复WPF的任何互操作性问题(您将使用完全托管的代码),并允许您根据需要设置对话框主题以匹配应用程序中使用的自定义主题.尝试这样的事情来帮助你入门.


或者,如果您不需要定位以前版本的Windows(Vista之前版本),则可以使用TaskDialogCOMCTRL32.DLL第6版中提供的版本,该版本替换并增强了标准MessageBox.但是,这不包含在.NET Framework中作为标准类,因此您必须进行P/Invoke.请参阅此处了解许多可用示例之一.

还有一些值得研究的示例项目利用TaskDialog可用的Windows版本,并在之前的版本中模拟它.(我个人在我的许多.NET应用程序中使用了非常相似的东西.)