C#で画面の外に出せないフォームを作ってみた

マルチディスプレイは面倒だったので対応してません

//タスクバー情報取得関数
[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);

//hWnd取得関数
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName);

//座標情報格納構造体
[StructLayout(LayoutKind.Sequential)]
private struct RECT {
public int Left;
public int Top;
public int Right;
public int Bottom;
}

//タスクバー情報格納構造体
[StructLayout(LayoutKind.Sequential)]
struct APPBARDATA {
public int cbSize;
public IntPtr hWnd;
public int uCallbackMessage;
public int uEdge;
public RECT rc;
public IntPtr lParam;
}

//Window移動
private const int WM_MOVING = 0x0216;
//タスクバー情報
private const int ABM_GETTASKBARPOS = 5;

protected override void WndProc(ref Message m) {
try {
if (m.Msg == WM_MOVING) {
//移動のメッセージだったら
//移動先予定の座標を取得する
var r = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));

//タスクバー情報の取得
APPBARDATA abd = new APPBARDATA();
abd.cbSize = Marshal.SizeOf(abd);
abd.hWnd = FindWindow("Shell_TrayWnd", null);
uint ret = SHAppBarMessage((int)5, ref abd);

//タスクバー抜きの画面サイズを設定しておく
RECT windowArea;
windowArea.Left = 0;
windowArea.Top = 0;
windowArea.Right = ((Rectangle)Screen.PrimaryScreen.Bounds).Width;
windowArea.Bottom = ((Rectangle)Screen.PrimaryScreen.Bounds).Height;

if (abd.rc.Top < 0) {
//クラシック表示
//2ピクセルはみ出ているので、調整する
abd.rc.Top += 2;
}
if (abd.rc.Bottom < 0) {
//クラシック表示
//2ピクセルはみ出ているので、調整する
abd.rc.Bottom += 2;
}

if (abd.rc.Left < 0 || abd.rc.Right < 0) {
//クラシック表示
//2ピクセルはみ出ているので、調整する
abd.rc.Left += 2;
abd.rc.Right -= 2;
}

//タスクバーの位置から、有効画面座標を算出する
if (abd.rc.Right - abd.rc.Left == ((Rectangle)Screen.PrimaryScreen.Bounds).Width) {
//上下にある
if (abd.rc.Top <= 0) {
//上にある
windowArea.Top = abd.rc.Bottom;
} else {
//下にある
windowArea.Bottom = abd.rc.Top;
}
} else {
if (abd.rc.Left <= 0) {
//左にある
windowArea.Left = abd.rc.Right;
} else {
//右にある
windowArea.Right = abd.rc.Left;
}
}

//画面外に出ようとしたら、ぎりぎりで止める
if (r.Left < windowArea.Left) {
r.Left = windowArea.Left;
r.Right = windowArea.Left + this.Width;
}
if (r.Right > windowArea.Right) {
r.Left = windowArea.Right - this.Width;
r.Right = windowArea.Right;
}
if (r.Top < windowArea.Top) {
r.Top = windowArea.Top;
r.Bottom = windowArea.Top + this.Height;
}
if (r.Bottom > windowArea.Bottom) {
r.Top = windowArea.Bottom - this.Height;
r.Bottom = windowArea.Bottom;
}

//すり替えた座標をLParamに戻す
Marshal.StructureToPtr(r, m.LParam, false);

}
base.WndProc(ref m);

} catch (Exception ex) {

}
}