WPF:为什么没有消息框在标题栏上有图标 [英] WPF : why doesnt messagebox have icon on titlebar

查看:599
本文介绍了WPF:为什么没有消息框在标题栏上有图标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

All I want is that my messagebox should show my application's icon (or any other icon) in its titlebar, but it doesnt, why not?

推荐答案

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

The MessageBox in WPF is simply a wrapper for the standard MessageBox in user32.dll, which is exactly the same function that Windows itself calls to display a dialog box. It's not going to look any different in your WPF applications than it does in any other app that relies on the Win32 API (including WinForms, MFC, etc.).

使用Reflector,您可以通过查看WPF中 MessageBox 调用的相关函数来验证这一点。请特别注意最后一行代码,它调用 UnsafeNativeMethods.MessageBox

Using Reflector, you can verify this by looking at the relevant function called by MessageBox in WPF. Note specifically the last line of code, where it calls 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 样式的情况下创建的。并尽可能 ,没有简单的方法来继承user32.dll-提供 MessageBox 将其窗口样式更改为在标题栏上显示一个图标。由此产生的代码很难看,坦白说不值得。

As you've noticed, this message box does not display an icon on its title bar. This is because its window is created without specifying the WS_CAPTION and WS_SYSMENU styles. And while possible, there's no easy way to subclass the user32.dll-provided MessageBox and change its window styles to display an icon on its title bar. The resulting code is fugly and frankly not worth the trouble.

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

The best solution is to simply create your own dialog box and call this one from your code instead. This has plenty of other advantages beyond the ability to add an icon, including fixing any interoperability problems with WPF (you'll be using entirely managed code) and allowing you to theme the dialog box as necessary to match a custom theme used in your application. Try something like this to help get you started.

  • http://blogsprajeesh.blogspot.com/2009/12/wpf-messagebox-custom-control.html



或者,如果您不需要定位以前版本的Windows(Vista之前版本),您可以使用< a href =http://msdn.microsoft.com/en-us/library/bb787471(VS.85).aspx\"rel =noreferrer> TaskDialog 在COMCTRL32.DLL的第6版中提供,它取代并增强了标准 MessageBox 。但是,这不包含在.NET Framework中作为标准类,因此您必须的P / Invoke 。有关众多可用示例之一,请参见此处


Alternatively, if you don't need to target previous versions of Windows (those prior to Vista), you can use the TaskDialog provided in version 6 of COMCTRL32.DLL, which replaces and enhances the standard MessageBox. However, this is not included as a standard class in the .NET Framework, so you'll have to P/Invoke. See here for one of many available examples.

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

There are also a couple of sample projects worth looking into that utilize the TaskDialog on versions of Windows where it is available and emulate it in previous versions where it is not. (I personally use something very similar in many of my .NET applications.)

http://www.codeproject.com/KB/ WPF / WPFTaskDialogVistaAndXP.aspx

http://www.codeproject.com/KB/vista/TaskDialogWinForms.aspx

这篇关于WPF:为什么没有消息框在标题栏上有图标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆