扩展C#中对话框

问题

在WinForm中,使用MessageBox时,总是显示在桌面中心,如何显示在winform的中心呢?

这个需要扩展MessageBox了,使用window hook。

实现


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

    namespace UIEx {

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

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

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

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

        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)  
        {  
            Initialize();  
            return MessageBox.Show(text, caption, buttons, icon);  
        }  

        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton)  
        {  
            Initialize();  
            return MessageBox.Show(text, caption, buttons, icon, defButton);  
        }  

        public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton, MessageBoxOptions options)  
        {  
            Initialize();  
            return MessageBox.Show(text, caption, buttons, icon, defButton, options);  
        }  

        public static DialogResult Show(IWin32Window owner, string text)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text);  
        }  

        public static DialogResult Show(IWin32Window owner, string text, string caption)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text, caption);  
        }  

        public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text, caption, buttons);  
        }  

        public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text, caption, buttons, icon);  
        }  

        public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text, caption, buttons, icon, defButton);  
        }  

        public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defButton, MessageBoxOptions options)  
        {  
            _owner = owner;  
            Initialize();  
            return MessageBox.Show(owner, text, caption, buttons, icon,  
                                   defButton, 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.Handle, ref recParent);  

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

            Point ptStart = new 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);  
        }  
    }
}      

使用

使用时和MessageBox一样的用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值