using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;
namespace GetADoc
{
//親(メイン)ウインドウの中心にメッセージを表示するためのクラス
class CustomMsgBox
{///
/// 親ウィンドウ
///
private Window ownerWindow = null;
///
/// フックハンドル
///
private IntPtr hHook = IntPtr.Zero;
///
/// メッセージボックスを表示する
///
///
///
///
///
///
///
public static MessageBoxResult Show(
Window owner,
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon)
{
if (owner.WindowState == WindowState.Minimized)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon);
}
else
{
CustomMsgBox mbox = new CustomMsgBox(owner);
return mbox.Show(messageBoxText, caption, button, icon);
}
}
///
/// コンストラクタ
///
/// Owner Window
private CustomMsgBox(Window window)
{
ownerWindow = window;
}
///
/// メッセージボックスを表示する
///
///
///
///
///
///
private MessageBoxResult Show(
string messageBoxText,
string caption,
MessageBoxButton button,
MessageBoxImage icon)
{
// フックを設定する。
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(ownerWindow);
IntPtr hInstance = WinAPI.GetWindowLong(hwndSource.Handle, WinAPI.GWL_HINSTANCE);
IntPtr threadId = WinAPI.GetCurrentThreadId();
hHook = WinAPI.SetWindowsHookEx(WinAPI.WH_CBT, new WinAPI.HOOKPROC(HookProc), hInstance, threadId);
return MessageBox.Show(ownerWindow, messageBoxText, caption, button, icon);
}
///
/// フックプロシージャ
///
///
///
///
///
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);
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(ownerWindow);
WinAPI.GetWindowRect(hwndSource.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(hHook, nCode, wParam, lParam);
// フックを解除する。
WinAPI.UnhookWindowsHookEx(hHook);
hHook = IntPtr.Zero;
return result;
}
else
{
return WinAPI.CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
}
internal 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 inLeft, int inTop, int inRight, int inBottom)
{
Left = inLeft;
Top = inTop;
Right = inRight;
Bottom = inBottom;
}
public int Left;
public int Top;
public int Right;
public int Bottom;
}
}
}