Application::DoEvents
画面を更新するだけではありません。実際には、アプリケーションの UI スレッドのメッセージ キューをポンプします。アセンブラーでこれを行う場合は、メッセージ キューを自分でポンピングする必要があります。ただし、これはお勧めしません。UI フレームワークで使用DoEvents
することは、そのような機能を提供するかどうかにかかわらず、明確なアンチパターンです。詳細については、こちらとこちらをご覧ください。
リストボックス コントロールが再描画されることを確認するだけの場合は、それを無効にして強制的に再描画する必要があります。WinForms では、次のようになります。
myListBox.Invalidate();
myListBox.Update();
アセンブラーでは、適切な Win32 API 関数を自分で呼び出す必要があります。特に、InvalidateRect
リストボックス コントロールのクライアント領域を無効にしてから、UpdateWindow
すぐに再描画されるようにするために使用できます。
MASM の構文はわかりませんが、アンマネージ C++ では次のようになります。
InvalidateRect(hListBox, /* handle to your listbox control */
NULL, /* invalidate the entire client area */
TRUE); /* erase the background */
UpdateWindow(hListBox);
ほとんどの場合、ウィンドウを無効にするだけで十分です。次回アプリケーションが (通常のメッセージ ループで) メッセージを処理するときに、WM_PAINT
メッセージを処理してコントロールを再描画するため、すぐに再描画を強制する必要はありません。これが機能しない唯一の理由は、なんらかのタイプの長時間実行操作を実行して UI スレッドをブロックしていた場合です。これは、そもそも実行すべきではありません。バックグラウンド スレッドをスピンオフして計算を実行します。
WM_SETREDRAW
ここでメッセージの送信が機能しない理由は、基本的に、コントロールがそれ自体を再描画できるかどうかを示すフラグを設定するためです。リンクされたドキュメントで説明されているように、変更を確認するにはウィンドウを再描画する必要があります。RedrawWindow
たとえば、呼び出すか、上記と同じことを行うことで、これを強制できると書かれています。