以前の投稿でMDI子フォームはMDI親フォームの最大化時にサイズグリップが非表示になるWinFormsの仕様を紹介しました。この記事ではウィンドウメッセージとToolStripRenderer
を利用したサイズグリップの強制表示を紹介します。動作確認環境は.NET 8.0ですが、他のバージョンでも変わらないと思います。
使用する仕組みは次の3つです。
StatusStrip
派生コントロールの作成。WndProc
のオーバーロードによるWM_NCHITTEST
処理の上書き。OnPaint
のオーバーロードとToolStripRenderer
によるサイズグリップの描画。
暗黙的なglobal usingを使った具体的なコードは以下の通りです。とりあえず機能することを目的としています。プロジェクトで使用するには次のコードを適用なCSファイルに貼り付け、目的とするフォームの「*.Designer.cs」でStatusStrip
をStatusStripWithSizeGrip
に置き換えてください。
namespace Utility.Windows.Forms; // TODO:適当な名前空間に変更 internal sealed class StatusStripWithSizeGrip : StatusStrip { protected override void OnCreateControl() { base.OnCreateControl(); // SizeGripBoundsを使いたいのでサイズグリップを強制表示します。 // この後の変更は対応しません。 SizingGrip = true; } protected override void WndProc(ref Message m) { const int WM_NCHITTEST = 0x0084; const int HTBOTTOMRIGHT = 17; if (m.Msg == WM_NCHITTEST) { var pt = PointToClient(Cursor.Position); if (SizeGripBounds.Contains(pt)) { m.Result = HTBOTTOMRIGHT; return; } } base.WndProc(ref m); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // 直接の親がフォームかつ最小・最大化されていなければサイズグリップを描画 if (Parent is not Form { WindowState: FormWindowState.Normal }) return; // サイズグリップを描画する。描画済みでも上書き。 Renderer.DrawStatusStripSizingGrip(new(e.Graphics, this)); } }