CSharp0003 のバックアップ(No.1) - PukiWiki

CSharp?

C#.NET で MessageBox をオーナーウィンドウの中央に配置する方法

抜粋:Win32 APIを利用する必要があります。

public partial class Form1 : Form {
   public Form1() {
       InitializeComponent();
   }

   private void cmdCenterMsgBox_Click(object sender, EventArgs e) {
       MsgBox.Show(this, "オーナーウィンドウの中央に表示されるはず", "オーナーウィンドウの中央表示サンプル", MessageBoxButtons.OK, MessageBoxIcon.Information);
   }
}

/// <summary>
/// Win API
/// </summary>
public class WinAPI {
   [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);

   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;

   public struct RECT {
       public RECT(int left, int top, int right, int bottom) {
           Left = left;
           Top = top;
           Right = right;
           Bottom = bottom;
       }

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

/// <summary>
/// オーナーウィンドウの真中に表示される MessageBox
/// </summary>
public class MsgBox {
 
   /// <summary>
   /// 親ウィンドウ
   /// </summary>
   private IWin32Window m_ownerWindow = null;

   /// <summary>
   /// フックハンドル
   /// </summary>
   private IntPtr m_hHook = (IntPtr) 0;

   /// <summary>
   /// メッセージボックスを表示する
   /// </summary>
   /// <param name="owner"></param>
   /// <param name="messageBoxText"></param>
   /// <param name="caption"></param>
   /// <param name="button"></param>
   /// <param name="icon"></param>
   /// <returns></returns>
   public static DialogResult Show(
       IWin32Window owner,
       string messageBoxText,
       string caption,
       MessageBoxButtons button,
       MessageBoxIcon icon) {
       MsgBox mbox = new MsgBox(owner);
       return mbox.Show(messageBoxText, caption, button, icon);
   }

   /// <summary>
   /// コンストラクタ
   /// </summary>
   /// <param name="window">親ウィンドウ</param>
   private MsgBox(IWin32Window window) {
       m_ownerWindow = window;
   }

   /// <summary>
   /// メッセージボックスを表示する
   /// </summary>
   /// <param name="messageBoxText"></param>
   /// <param name="caption"></param>
   /// <param name="button"></param>
   /// <param name="icon"></param>
   /// <returns></returns>
   private DialogResult Show(
       string messageBoxText,
       string caption,
       MessageBoxButtons button,
       MessageBoxIcon icon) {
       // フックを設定する。
       IntPtr hInstance = WinAPI.GetWindowLong(m_ownerWindow.Handle, WinAPI.GWL_HINSTANCE);
       IntPtr threadId = WinAPI.GetCurrentThreadId();
       m_hHook = WinAPI.SetWindowsHookEx(WinAPI.WH_CBT, new WinAPI.HOOKPROC(HookProc), hInstance, threadId);

       return MessageBox.Show(m_ownerWindow, messageBoxText, caption, button, icon);
   }

   /// <summary>
   /// フックプロシージャ
   /// </summary>
   /// <param name="nCode"></param>
   /// <param name="wParam"></param>
   /// <param name="lParam"></param>
   /// <returns></returns>
   private IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam) {

       if (nCode == WinAPI.HCBT_ACTIVATE) {
           WinAPI.RECT rcForm = new WinAPI.RECT(0, 0, 0, 0);
           WinAPI.RECT rcMsgBox = new WinAPI.RECT(0, 0, 0, 0);

           WinAPI.GetWindowRect(m_ownerWindow.Handle, out rcForm);
           WinAPI.GetWindowRect(wParam, out rcMsgBox);

           // センター位置を計算する。
           int x = (rcForm.Left + (rcForm.Right - rcForm.Left) / 2) - ((rcMsgBox.Right - rcMsgBox.Left) / 2);
           int y = (rcForm.Top + (rcForm.Bottom - rcForm.Top) / 2) - ((rcMsgBox.Bottom - rcMsgBox.Top) / 2);

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

           IntPtr result = WinAPI.CallNextHookEx(m_hHook, nCode, wParam, lParam);

           // フックを解除する。
           WinAPI.UnhookWindowsHookEx(m_hHook);
           m_hHook = (IntPtr) 0;

           return result;

       } else {
           return WinAPI.CallNextHookEx(m_hHook, nCode, wParam, lParam);
       }
   }
}

http://www.koutou-software.co.jp/junk/mynote-cs-dotnet-messagebox-position-on-center.html


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

yVoC[UNLIMITȂ1~] ECirŃ|C Yahoo yV LINEf[^[Ōz500~`I


z[y[W ̃NWbgJ[h COiq 萔O~ył񂫁z COsیI COze