2016-02-24 74 views
3

的中心我一直在关注这个问题How to get MessageBox.Show() to pop up in the middle of my WPF application?消息框出现在窗口WPF

我试图将代码从Framnk与此代码:

using System; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Interop; 
using System.Drawing; 

namespace dsmgmt 
{ 
    public class MessageBoxEx 
    { 
     private static IntPtr _owner; 
     private static HookProc _hookProc; 
     private static IntPtr _hHook; 

     public static MessageBoxResult Show(string text) 
     { 
      Initialize(); 
      return MessageBox.Show(text); 
     } 

     public static MessageBoxResult Show(string text, string caption) 
     { 
      Initialize(); 
      return MessageBox.Show(text, caption); 
     } 

     public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons) 
     { 
      Initialize(); 
      return MessageBox.Show(text, caption, buttons); 
     } 

     public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon) 
     { 
      Initialize(); 
      return MessageBox.Show(text, caption, buttons, icon); 
     } 

     public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult) 
     { 
      Initialize(); 
      return MessageBox.Show(text, caption, buttons, icon, defResult); 
     } 

     public static MessageBoxResult Show(string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult, MessageBoxOptions options) 
     { 
      Initialize(); 
      return MessageBox.Show(text, caption, buttons, icon, defResult, options); 
     } 

     public static MessageBoxResult Show(Window owner, string text) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text); 
     } 

     public static MessageBoxResult Show(Window owner, string text, string caption) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text, caption); 
     } 

     public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text, caption, buttons); 
     } 

     public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text, caption, buttons, icon); 
     } 

     public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text, caption, buttons, icon, defResult); 
     } 

     public static MessageBoxResult Show(Window owner, string text, string caption, MessageBoxButton buttons, MessageBoxImage icon, MessageBoxResult defResult, MessageBoxOptions options) 
     { 
      _owner = new WindowInteropHelper(owner).Handle; 
      Initialize(); 
      return MessageBox.Show(owner, text, caption, buttons, icon, 
            defResult, options); 
     } 

     public delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam); 

     public delegate void TimerProc(IntPtr hWnd, uint uMsg, UIntPtr nIDEvent, uint dwTime); 

     public const int WH_CALLWNDPROCRET = 12; 

     public enum CbtHookAction : int 
     { 
      HCBT_MOVESIZE = 0, 
      HCBT_MINMAX = 1, 
      HCBT_QS = 2, 
      HCBT_CREATEWND = 3, 
      HCBT_DESTROYWND = 4, 
      HCBT_ACTIVATE = 5, 
      HCBT_CLICKSKIPPED = 6, 
      HCBT_KEYSKIPPED = 7, 
      HCBT_SYSCOMMAND = 8, 
      HCBT_SETFOCUS = 9 
     } 

     [DllImport("user32.dll")] 
     private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect); 

     [DllImport("user32.dll")] 
     private static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); 

     [DllImport("User32.dll")] 
     public static extern UIntPtr SetTimer(IntPtr hWnd, UIntPtr nIDEvent, uint uElapse, TimerProc lpTimerFunc); 

     [DllImport("User32.dll")] 
     public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 

     [DllImport("user32.dll")] 
     public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); 

     [DllImport("user32.dll")] 
     public static extern int UnhookWindowsHookEx(IntPtr idHook); 

     [DllImport("user32.dll")] 
     public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam); 

     [DllImport("user32.dll")] 
     public static extern int GetWindowTextLength(IntPtr hWnd); 

     [DllImport("user32.dll")] 
     public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int maxLength); 

     [DllImport("user32.dll")] 
     public static extern int EndDialog(IntPtr hDlg, IntPtr nResult); 

     [StructLayout(LayoutKind.Sequential)] 
     public struct CWPRETSTRUCT 
     { 
      public IntPtr lResult; 
      public IntPtr lParam; 
      public IntPtr wParam; 
      public uint message; 
      public IntPtr hwnd; 
     }; 

     static MessageBoxEx() 
     { 
      _hookProc = new HookProc(MessageBoxHookProc); 
      _hHook = IntPtr.Zero; 
     } 

     private static void Initialize() 
     { 
      if (_hHook != IntPtr.Zero) 
      { 
       throw new NotSupportedException("multiple calls are not supported"); 
      } 

      if (_owner != null) 
      { 
       _hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, _hookProc, IntPtr.Zero, AppDomain.GetCurrentThreadId()); 
      } 
     } 

     private static IntPtr MessageBoxHookProc(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode < 0) 
      { 
       return CallNextHookEx(_hHook, nCode, wParam, lParam); 
      } 

      CWPRETSTRUCT msg = (CWPRETSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPRETSTRUCT)); 
      IntPtr hook = _hHook; 

      if (msg.message == (int)CbtHookAction.HCBT_ACTIVATE) 
      { 
       try 
       { 
        CenterWindow(msg.hwnd); 
       } 
       finally 
       { 
        UnhookWindowsHookEx(_hHook); 
        _hHook = IntPtr.Zero; 
       } 
      } 

      return CallNextHookEx(hook, nCode, wParam, lParam); 
     } 

     private static void CenterWindow(IntPtr hChildWnd) 
     { 
      Rectangle recChild = new Rectangle(0, 0, 0, 0); 
      bool success = GetWindowRect(hChildWnd, ref recChild); 

      int width = recChild.Width - recChild.X; 
      int height = recChild.Height - recChild.Y; 

      Rectangle recParent = new Rectangle(0, 0, 0, 0); 
      success = GetWindowRect(_owner, ref recParent); 

      System.Drawing.Point ptCenter = new System.Drawing.Point(0, 0); 
      ptCenter.X = recParent.X + ((recParent.Width - recParent.X)/2); 
      ptCenter.Y = recParent.Y + ((recParent.Height - recParent.Y)/2); 


      System.Drawing.Point ptStart = new System.Drawing.Point(0, 0); 
      ptStart.X = (ptCenter.X - (width/2)); 
      ptStart.Y = (ptCenter.Y - (height/2)); 

      ptStart.X = (ptStart.X < 0) ? 0 : ptStart.X; 
      ptStart.Y = (ptStart.Y < 0) ? 0 : ptStart.Y; 

      int result = MoveWindow(hChildWnd, ptStart.X, ptStart.Y, width, 
            height, false); 
     } 
    } 
} 

,然后我用MessageBoxEx.Show('something', 'sometihng'),结果把它太奇怪了。

消息框显示在屏幕的左上角(不是窗口),无论我移动窗口并尝试调用消息箱,它总是会出现在屏幕的左上角。我怎样才能解决这个问题?

回答

2

假设你从主窗口类致电:

dsmgmt.MessageBoxEx.Show(this, "A", "B"); 

如果不是,你的窗口传递给函数;

Window w; // your window 
dsmgmt.MessageBoxEx.Show(w, "A", "B"); 
+1

omg它就像那样。谢谢 :) – Mirza