【C#/WinForms】非クライアント領域を変更した場合のウィンドウサイズ変更時のチラつきについて

この記事は約17分で読めます。

自作エディタにもダークモードを適用したくて WM_NCCALCSIZE でクライアント領域を広げてタイトルバーを消しました。その後、色々検証しているとウィンドウを最大化した後にドラッグで元に戻すると標準のタイトルバーと異なり一瞬チラつきます。気になったので何故そうなるのか調べてみました。ただし、現時点で解決策は見つかっていません。

検証内容

以下の操作を標準のタイトルバーと WM_NCCALCSIZE で非クライアント領域を変更した場合で行いウィンドウメッセージの違いを確認しました。

  1. フォームを表示します。
  2. フォームを最大化します。
  3. タイトルバーをドラッグして元のサイズに戻します。
  4. マウスクリックをやめます。

結果

ウィンドウメッセージ内容は検証内容3.と4.を実施した後の抜粋(WM_NCLBUTTONDOWN から WM_EXITSIZEMOVE)です。また、メッセージ内に出てくる MainForm_Move は Move イベントです。MainForm_Resize は Resize イベントです。

標準タイトルバーの場合のウィンドウメッセージ

まずは標準タイトルバーの場合です。MainForm_Move が 4 回、MainForm_Resize が 1 回でした。

600:msg=0xa1 (WM_NCLBUTTONDOWN) hwnd=0x400ff4 wparam=0x2 lparam=0xb014b result=0x0
601:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
602:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
603:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
604:msg=0x112 (WM_SYSCOMMAND) hwnd=0x400ff4 wparam=0xf012 lparam=0xb014b result=0x0
605:msg=0x215 (WM_CAPTURECHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
606:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
607:msg=0x231 (WM_ENTERSIZEMOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
608:msg=0x2a2 hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
609:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
610:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcbc70 result=0x0
611:msg=0x83 (WM_NCCALCSIZE) hwnd=0x400ff4 wparam=0x1 lparam=0xfa2edcca60 result=0x0
612:msg=0x85 (WM_NCPAINT) hwnd=0x400ff4 wparam=0x4f041f0c lparam=0x0 result=0x0
613:msg=0x14 (WM_ERASEBKGND) hwnd=0x400ff4 wparam=0xffffffffa501246a lparam=0x0 result=0x0
614:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
615:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
616:msg=0xae hwnd=0x400ff4 wparam=0x1001 lparam=0x0 result=0x0
617:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
618:msg=0x3 (WM_MOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x1c0020 result=0x0
619:MainForm_Move
620:MainForm_Resize
621:msg=0x5 (WM_SIZE) hwnd=0x400ff4 wparam=0x0 lparam=0x1a20265 result=0x0
622:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
623:msg=0xd (WM_GETTEXT) hwnd=0x400ff4 wparam=0x36 lparam=0xfa2edcb450 result=0x0
624:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
625:msg=0xd (WM_GETTEXT) hwnd=0x400ff4 wparam=0x36 lparam=0xfa2edcb450 result=0x0
626:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcbe80 result=0x0
627:msg=0x85 (WM_NCPAINT) hwnd=0x400ff4 wparam=0x2d041271 lparam=0x0 result=0x0
628:msg=0x14 (WM_ERASEBKGND) hwnd=0x400ff4 wparam=0xffffffffef011465 lparam=0x0 result=0x0
629:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcbe80 result=0x0
630:msg=0x3 (WM_MOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x19003f2 result=0x0
631:MainForm_Move
632:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
633:msg=0xd (WM_GETTEXT) hwnd=0x400ff4 wparam=0x36 lparam=0xfa2edca840 result=0x0
634:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
635:msg=0xd (WM_GETTEXT) hwnd=0x400ff4 wparam=0x36 lparam=0xfa2edca840 result=0x0
636:msg=0x214 (WM_SIZING) hwnd=0x400ff4 wparam=0x9 lparam=0xfa2edccaa0 result=0x0
637:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
638:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcbc70 result=0x0
639:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
640:msg=0x3 (WM_MOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x1c0020 result=0x0
641:MainForm_Move
642:msg=0x215 (WM_CAPTURECHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0
643:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
644:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcbc70 result=0x0
645:msg=0x85 (WM_NCPAINT) hwnd=0x400ff4 wparam=0x71041eb5 lparam=0x0 result=0x0
646:msg=0x14 (WM_ERASEBKGND) hwnd=0x400ff4 wparam=0xffffffffc6010b04 lparam=0x0 result=0x0
647:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x400ff4 wparam=0x0 lparam=0xfa2edcca90 result=0x0
648:msg=0x3 (WM_MOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x1f0020 result=0x0
649:MainForm_Move
650:msg=0x232 (WM_EXITSIZEMOVE) hwnd=0x400ff4 wparam=0x0 lparam=0x0 result=0x0

WM_NCCALCSIZEを処理した場合のウィンドウメッセージ

次に WM_NCCALCSIZE を処理した場合です。MainForm_Move は 4 回と標準タイトルバーと同じですが、MainForm_Resize が 3 回実行されていました。おそらくサイズ変更が 3 回実行されるためチラつくんだと思います。各リサイズ時の画面の位置を確認すると下記でした。

  • 1回目はドラッグした位置に最大化前のサイズで表示
  • 2回目は最大化前の位置に最大化前のサイズで表示
  • 3回目はドラッグした位置に最大化前のサイズで表示
164:msg=0xa1 (WM_NCLBUTTONDOWN) hwnd=0x10f0d14 wparam=0x2 lparam=0x0 result=0x0
165:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
166:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
167:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
168:msg=0x112 (WM_SYSCOMMAND) hwnd=0x10f0d14 wparam=0xf012 lparam=0x0 result=0x0
169:msg=0x215 (WM_CAPTURECHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
170:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
171:msg=0x231 (WM_ENTERSIZEMOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
172:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
173:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496a7a0 result=0x0
174:msg=0x83 (WM_NCCALCSIZE) hwnd=0x10f0d14 wparam=0x1 lparam=0x1b5496b7f0 result=0x0
175:msg=0x85 (WM_NCPAINT) hwnd=0x10f0d14 wparam=0x60042018 lparam=0x0 result=0x0
176:msg=0x14 (WM_ERASEBKGND) hwnd=0x10f0d14 wparam=0xffffffffe20117ee lparam=0x0 result=0x0
177:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
178:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
179:msg=0xae hwnd=0x10f0d14 wparam=0x1001 lparam=0x0 result=0x0
180:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
181:msg=0x3 (WM_MOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0xfff70029 result=0x0
182:MainForm_Move
183:MainForm_Resize
184:msg=0x5 (WM_SIZE) hwnd=0x10f0d14 wparam=0x0 lparam=0x1c10265 result=0x0
185:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
186:msg=0xd (WM_GETTEXT) hwnd=0x10f0d14 wparam=0x36 lparam=0x1b54969f80 result=0x0
187:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
188:msg=0xd (WM_GETTEXT) hwnd=0x10f0d14 wparam=0x36 lparam=0x1b54969f80 result=0x0
189:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496a9b0 result=0x0
190:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b54969930 result=0x0
191:msg=0x83 (WM_NCCALCSIZE) hwnd=0x10f0d14 wparam=0x1 lparam=0x1b5496a980 result=0x0
192:msg=0x85 (WM_NCPAINT) hwnd=0x10f0d14 wparam=0x54042088 lparam=0x0 result=0x0
193:msg=0x14 (WM_ERASEBKGND) hwnd=0x10f0d14 wparam=0xffffffffe20117ee lparam=0x0 result=0x0
194:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496a9b0 result=0x0
195:msg=0x3 (WM_MOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0x1e2048c result=0x0
196:MainForm_Move
197:msg=0x14 (WM_ERASEBKGND) hwnd=0x10f0d14 wparam=0xffffffffa501246a lparam=0x0 result=0x0
198:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
199:msg=0xd (WM_GETTEXT) hwnd=0x10f0d14 wparam=0x36 lparam=0x1b54966880 result=0x0
200:MainForm_Resize
201:msg=0x5 (WM_SIZE) hwnd=0x10f0d14 wparam=0x0 lparam=0x1e00265 result=0x0
202:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
203:msg=0xd (WM_GETTEXT) hwnd=0x10f0d14 wparam=0x36 lparam=0x1b54969110 result=0x0
204:msg=0xe (WM_GETTEXTLENGTH) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
205:msg=0xd (WM_GETTEXT) hwnd=0x10f0d14 wparam=0x36 lparam=0x1b54969110 result=0x0
206:msg=0x214 (WM_SIZING) hwnd=0x10f0d14 wparam=0x9 lparam=0x1b5496b830 result=0x0
207:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
208:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496a7a0 result=0x0
209:msg=0x83 (WM_NCCALCSIZE) hwnd=0x10f0d14 wparam=0x1 lparam=0x1b5496b7f0 result=0x0
210:msg=0x85 (WM_NCPAINT) hwnd=0x10f0d14 wparam=0xfffffffffd040db2 lparam=0x0 result=0x0
211:msg=0x14 (WM_ERASEBKGND) hwnd=0x10f0d14 wparam=0xffffffffa501246a lparam=0x0 result=0x0
212:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
213:msg=0x3 (WM_MOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0xfff70029 result=0x0
214:MainForm_Move
215:MainForm_Resize
216:msg=0x5 (WM_SIZE) hwnd=0x10f0d14 wparam=0x0 lparam=0x1c10265 result=0x0
217:msg=0xf (WM_PAINT) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
218:msg=0x216 (WM_MOVING) hwnd=0x10f0d14 wparam=0x9 lparam=0x1b5496b830 result=0x0
219:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
220:msg=0x24 (WM_GETMINMAXINFO) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496a7a0 result=0x0
221:msg=0x85 (WM_NCPAINT) hwnd=0x10f0d14 wparam=0xffffffffb6040aa0 lparam=0x0 result=0x0
222:msg=0x14 (WM_ERASEBKGND) hwnd=0x10f0d14 wparam=0x1010d93 lparam=0x0 result=0x0
223:msg=0x47 (WM_WINDOWPOSCHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
224:msg=0x3 (WM_MOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0x2003c result=0x0
225:MainForm_Move
226:msg=0x215 (WM_CAPTURECHANGED) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0
227:msg=0x46 (WM_WINDOWPOSCHANGING) hwnd=0x10f0d14 wparam=0x0 lparam=0x1b5496b820 result=0x0
228:msg=0x232 (WM_EXITSIZEMOVE) hwnd=0x10f0d14 wparam=0x0 lparam=0x0 result=0x0

おわりに

ウィンドウをドラッグして元に戻すことは私自身はほとんどしない操作なのですが、やっぱり気になります。多分 1 回だけリサイズするようにすればいいと思うのですが、現時点で良い方法が見つかりません。

コメント

タイトルとURLをコピーしました