0

プログラムが c++、c#、vb.net で計算を行っているときは、 を使用しapplication::doevents()て画面を更新し、画面がフリーズしないようにすることができます。アセンブリの特定のマスでこれを行うにはどうすればよいですか

入れてみた

invoke SendMessage, hWin, WM_SETREDRAW, 0, 0 
invoke SendMessage, hWin, WM_SETREDRAW, 1, 0 

私のプログラムのループ部分にありますが、動作しません。

私も試しました

invoke SendMessage, hWin, WM_SETREDRAW, 1, 0

しかし、それも機能しません

4

1 に答える 1

1

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たとえば、呼び出すか、上記と同じことを行うことで、これを強制できると書かれています。

于 2013-04-02T23:44:26.380 に答える