表題の通りです。
親ウィンドウの中央にダイアログなどを表示しようとすると、親ウィンドウそのものが画面から外れている場合に表示領域外に表示されてしまったりして困ったことになります。
マルチディスプレイ環境だったりすると、座標域に負数が含まれる場合などもあって、なかなかややこしい。
WEB上を検索しても、GetSystemMetrics(SM_CXSCREEN)とかGetSystemMetrics(SM_CXSFULLCREEN) などを使ったサンプルしか公開されていなくて、ちょっと不満だったので書いてみました。
ま、実際にはもっとややこしい環境もあると思うので完全ではないかもしれないけど、うちの環境では表示されるのでよしとしようw
ヘッダファイルの記述
extern BOOL SetWindowCenterParent(HWND handle, HWND parent, int width, int height, int min_width = -1, int min_heigh = -1);
ソースファイル
#include// // ウィンドウを親ウィンドウの中心に表示する // // 【パラメータ】 // HWND handle 対象となるウィンドウハンドル // HWND parent 親ウィンドウハンドル(HWND_DESKTOP も可) // int width ウィンドウの幅 // int height ウィンドウの高さ // int min_width 最小ウィンドウ幅(不要な場合は負数を指定) // int min_heigh 最小ウィンドウ高さ(不要な場合は負数を指定) BOOL SetWindowCenterParent(HWND handle, HWND parent, int width, int height, int min_width, int min_heigh) { // 親ウィンドウの中心を取得 RECT parent_rect; GetWindowRect(parent, &parent_rect); POINT center; center.x = (parent_rect.right + parent_rect.left) / 2; center.y = (parent_rect.bottom + parent_rect.top) / 2; // ディスプレイ情報 SIZE display; display.cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); display.cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); // タスクバーの大きさを調整 SIZE screen; screen.cx = GetSystemMetrics(SM_CXSCREEN); screen.cy = GetSystemMetrics(SM_CYSCREEN); RECT work_area; SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0); SIZE task_bar; task_bar.cx = screen.cx - (work_area.right - work_area.left); task_bar.cy = screen.cy - (work_area.bottom - work_area.top); display.cx -= task_bar.cx; display.cy -= task_bar.cy; POINT origin; origin.x = GetSystemMetrics(SM_XVIRTUALSCREEN); origin.y = GetSystemMetrics(SM_YVIRTUALSCREEN); // 最小サイズ、最大サイズの検査 if ((0 < min_width) && (width < min_width)) { width = min_width; } if ((0 < min_heigh) && (height < min_heigh)) { height = min_heigh; } if (display.cx < width) { width = display.cx; } if (display.cy < height) { height = display.cy; } // 表示位置 POINT place; place.x = center.x - (width / 2); place.y = center.y - (height / 2); // ディスプレイの座標範囲(マルチディスプレイ含む)からのはみだし検査 if ((origin.x + display.cx) < (place.x + width)) { place.x = origin.x + display.cx - width; } if (place.x < origin.x) { place.x = origin.x; } if ((origin.y + display.cy) < (place.y + height)) { place.y = origin.y + display.cy - height; } if (place.y < origin.y) { place.y = origin.y; } return SetWindowPos(handle, HWND_TOP, place.x, place.y, width, height, 0); }