メッセージボックスを owner の中央に表示、ついでにディスプレイ内に収める

C# 2.0 で実装。
ご利用はご自由に。
参考:

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

public class CenterMessageBox
{

    #region defines

    private static class NativeMethods
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetCurrentThreadId();

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

        [DllImport("user32.dll")]
        public static extern bool UnhookWindowsHookEx(IntPtr hHook);

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

        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

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

        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct RECT
        {
            #region fields

            public int Left;
            public int Top;
            public int Right;
            public int Bottom;

            #endregion

            #region properties

            public int Width
            {
                get { return this.Right - this.Left; }
            }

            public int Height
            {
                get { return this.Bottom - this.Top; }
            }

            #endregion

            #region methods

            public Rectangle ToRectangle()
            {
                return new Rectangle(this.Left, this.Top, this.Width, this.Height);
            }

            #endregion
        }

        public const int GWL_HINSTANCE  = (-6);
        public const int WH_CBT         = 5;
        public const int HCBT_ACTIVATE  = 5;
        public const int SWP_NOSIZE     = 0x0001;
        public const int SWP_NOZORDER   = 0x0004;
        public const int SWP_NOACTIVATE = 0x0010;
    }

    #endregion

    #region static methods

    public static DialogResult Show(IWin32Window owner, string text)
    {
        return Show(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
    }

    public static DialogResult Show(IWin32Window owner, string text, string caption)
    {
        return Show(owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
    }

    public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons)
    {
        return Show(owner, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
    }

    public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
    {
        return Show(owner, text, caption, buttons, icon, MessageBoxDefaultButton.Button1);
    }

    public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
    {
        if (null == owner)
        {
            throw new ArgumentNullException("owner");
        }
        CenterMessageBox messageBox = new CenterMessageBox(owner);
        return messageBox.Show(text, caption, buttons, icon, defaultButton);
    }

    #endregion

    #region fields

    private readonly IWin32Window Owner;
    private IntPtr HookHandle = IntPtr.Zero;

    #endregion

    #region constructors

    private CenterMessageBox(IWin32Window owner)
    {
        this.Owner = owner;
    }

    #endregion

    #region methods

    private DialogResult Show(
        string text,
        string caption,
        MessageBoxButtons buttons,
        MessageBoxIcon icon,
        MessageBoxDefaultButton defaultButton)
    {
        IntPtr hInstance = NativeMethods.GetWindowLong(this.Owner.Handle, NativeMethods.GWL_HINSTANCE);
        IntPtr threadId = NativeMethods.GetCurrentThreadId();
        this.HookHandle = NativeMethods.SetWindowsHookEx(NativeMethods.WH_CBT, this.HookProc, hInstance, threadId);

        return MessageBox.Show(this.Owner, text, caption, buttons, icon, defaultButton);
    }

    private IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode == NativeMethods.HCBT_ACTIVATE)
        {
            NativeMethods.RECT ownerRect;
            NativeMethods.RECT msgBoxRect;

            NativeMethods.GetWindowRect(this.Owner.Handle, out ownerRect);
            NativeMethods.GetWindowRect(wParam, out msgBoxRect);
            int x = ownerRect.Left + (ownerRect.Width - msgBoxRect.Width) / 2;
            int y = ownerRect.Top + (ownerRect.Height - msgBoxRect.Height) / 2;

            Rectangle workingArea = Screen.GetWorkingArea(ownerRect.ToRectangle());
            if (workingArea.Bottom < y + msgBoxRect.Height)
            {
                y = workingArea.Bottom - msgBoxRect.Height;
            }
            if (workingArea.Right < x + msgBoxRect.Width)
            {
                x = workingArea.Right - msgBoxRect.Width;
            }
            if (y < workingArea.Top)
            {
                y = workingArea.Top;
            }
            if (x < workingArea.Left)
            {
                x = workingArea.Left;
            }

            NativeMethods.SetWindowPos(wParam, 0, x, y, 0, 0,
                NativeMethods.SWP_NOSIZE | NativeMethods.SWP_NOZORDER | NativeMethods.SWP_NOACTIVATE);

            try
            {
                return NativeMethods.CallNextHookEx(this.HookHandle, nCode, wParam, lParam);
            }
            finally
            {
                NativeMethods.UnhookWindowsHookEx(this.HookHandle);
                this.HookHandle = IntPtr.Zero;
            }
        }

        return NativeMethods.CallNextHookEx(this.HookHandle, nCode, wParam, lParam);
    }

    #endregion

}