2010-11-18 96 views

回答

5

MessageBox in WPF只是標準MessageBox in user32.dll的包裝,它與Windows本身調用的顯示對話框的功能完全相同。在任何其他依賴於Win32 API的應用程序(包括WinForms,MFC等)中,WPF應用程序不會有任何不同。

使用反射器,您可以通過查看WPF中的MessageBox調用的相關函數來驗證此情況。注意具體的代碼的最後一行,它調用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_CAPTIONWS_SYSMENU樣式。並且while possible,有沒有簡單的方法來繼承user32.dll提供的MessageBoxchange its window styles以在其標題欄上顯示圖標。由此產生的代碼非常繁瑣,坦白地說不值得麻煩。

最好的解決方案是簡單地創建自己的對話框,然後從代碼中調用這個對話框。除了添加圖標之外,這還有其他許多優點,包括修復WPF的任何互操作性問題(您將使用完全託管的代碼),並允許您根據需要設置主題對話框,以匹配應用程序中使用的自定義主題。嘗試這樣的事情來幫助你開始。


或者,如果您不需要針對以前版本的Windows(那些Vista之前的),你可以使用COMCTRL32.DLL第6版所提供的TaskDialog,它取代並增強了標準MessageBox。但是,這並不包含在.NET Framework中作爲標準類,因此您必須使用P/Invoke。有關許多可用示例之一,請參閱here

還有一些示例項目值得研究,它利用了Windows版本中的TaskDialog,並且在以前的版本中對其進行了仿真。 (我個人使用我的很多.NET應用程序非常類似的東西。)

0

您可以創建自己的自定義消息框 - 只需創建用戶控件(包括圖像,動畫,視頻或其他...)並調用ShowDialog,即可從this example開始。

+2

是的,我可以創造一個,但我問題是要找出原因,爲什麼它在BCL中默認不可用 – 2010-11-18 12:10:24