%や^で気持ち悪いVC++2005ですが、Win32APIを使うには手続きの煩雑なVC#2005よりは向いていそうです。
手軽に画面の有効部分までウィンドウを拡張する「最大化」。しかしメッセンジャーやデスクトップ上のいくつかのアイコン、Samuraizeなどタスクバー以外にも常に表示させたい部分もあります。
サイドバー系のソフトや「常に最前面に表示」を使ってもいいのですが、あらゆるソフトに対応するには最大化の領域を制限するのが理に適っています。
以下、製作メモ。
WM_GETMINMAXINFOについて
void virtual WndProc(Message % m) override { switch(m.Msg) { case WM_GETMINMAXINFO: LPMINMAXINFO lpmmi; lpmmi = (LPMINMAXINFO)m.LParam.ToPointer(); lpmmi->ptMaxPosition.x = 200; lpmmi->ptMaxPosition.y = 200; break; default: __super::WndProc(m); break; } return; }
上のようにした場合、ウィンドウを最大化すると200, 200を左上に表示され、位置も大きさも固定されます。(サイズは画面と同じ?)
そこで、
lpmmi->ptMaxSize.x = 1024; lpmmi->ptMaxSize.y = 700;
を追加してサイズを指定することはできましたが、位置が可変になってしまいます。
位置を固定する方法は色々あるようですが、
case WM_NCHITTEST: m.Result = IntPtr(HTCLIENT); break;
はシステムメニュー(ALT+Spaceで出る)から移動を選ぶと移動できますし、何より最大化ボタンなども無効になるため却下。
smdn .NET Tipsを参考に、
case WM_SYSCOMMAND: WINDOWPLACEMENT placement; placement.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(static_cast<HWND>(this->Handle.ToPointer()), &placement); if ( placement.showCmd == SW_SHOWMAXIMIZED && (m.WParam.ToInt32() & 0xFFF0) == SC_MOVE) { m.Result = IntPtr.Zero; } else { __super::WndProc(m); } break;
としてみると、最大化時の移動のみ無効にできました。(this->WindowState等を使わないのは後々他のアプリケーションのウィンドウにも適用するため)
.NETでEnumWindows+コールバックするあたりで詰まったのでまた今度。

No Comments yet »
コメント RSS TrackBack URI
コメントをどうぞ