タスクバーを考慮した、Windowの位置情報の保存

Windows のプログラムで、窓の位置情報を取得する関数が、いくつかるのですが、GetWindowRect を使うと、最小化、最大化したときの位置情報が保存されてしまうため、次回この値で復元するととんでもないことになってしまいます。

GetWindowPlacement では、取得できる 構造体に rcNormalPosition なん便利なものがあるので使っていたのですが、タスクバーの位置を考慮しないワークエリアの位置情報が帰ってくるので、左や上にタスクバーがあると、起動するたびに、どんどん右や下に移動してしまうということになります。

GetWindowPlacement関数の落とし穴

そこで、最大化された窓の X/Y座標をとってきて、負の値だった方をまず、最大化したときの、オフセット(最大化すると少し Window が外にはみ出して、-4 とかになります)として取得し、正の方に オフセットを加算した分をタスクバーの高さや幅として計算して、Window 位置に加算して 取得するという方法をとっていました。

しかし、マルチモニタ環境では、最大化時の原点が (0,0)ではなくなるので、この座標を加算すると、とんでもないことになるのでした。

v0.8.8e/0.8.7g より前の もふったーが デュアルディスプレイ環境で最大化後、終了させると画面外に行ってしまうのはそのためでした。

しかし、マルチモニタ関数眺めてて気づいたのですが

HMONITOR SECMON;
MONITORINFO MonitorInfo;
pt.x=rt.left+32;
pt.y=rt.top+32;
MonitorInfo.cbSize = sizeof(MonitorInfo);
SECMON=MonitorFromPoint
    (pt,MONITOR_DEFAULTTONEAREST);
::GetMonitorInfo(SECMON, &MonitorInfo);
rt.top=MonitorInfo.rcWork.top-MonitorInfo.rcMonitor.top;
rt.left=MonitorInfo.rcWork.left-MonitorInfo.rcMonitor.left;

よく見たら、これでタスクバーの情報取得できるのでした Σ(・ω・;) ががーん

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です