2

このコードを実行すると、スレッドのメッセージ ボックスがポップされた後にテキストが更新されます

void PnlOptions::ClickHandler() {
    SetWindowText(txt_progress_, "CLASS MEMBER FUNCTION");

    HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &ThreadProcess, 0, CREATE_SUSPENDED, 0);

    ResumeThread(hThread);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
}

unsigned int __stdcall ThreadProcess(void * data0) {
    MessageBox(NULL, "THREAD FREE FUNCTION", "Alert", MB_OK);
}

だったからだと思いました

スレッドが実行可能な状態で作成された場合 (つまり、CREATE_SUSPENDED フラグが使用されていない場合)、スレッドは CreateThread が戻る前、特に呼び出し元が作成されたスレッドのハンドルと識別子を受け取る前に実行を開始できます。

ただし、中断されていないスレッドを使用すると、同じ結果になります。

また試しました:

  • 使用するCreateThread

  • スレッドの優先度の変更

  • SendMessageの代わりに使用SetWindowText

  • PeekMessage

UI が更新される前にスレッドが開始されるのはなぜですか?


宣言:

pnl_options.h:

unsigned int __stdcall ThreadProcess(void *);

public PnlOptions:
     void Init(HWND);
     void ClickHandler();

private:
     HWND txt_progress_;

pnl_options.cpp (上記のコード以外):

 void PnlOptions::Init(HWND hwnd0) {
    txt_progress_ = CreateWindowEx (0,
        TEXT("EDIT"), "Press \"GO\" to process all selected files.",
        SS_LEFT | SS_CENTERIMAGE | WS_VISIBLE | WS_CHILD,
        0, 0, 0, 0,
        hwnd0, (HMENU) IDT_PROGRESSTEXT, NULL, NULL
        );   
 }
4

3 に答える 3

1

この動作を再現したところ、投稿された WM_PAINT メッセージが原因で、EDIT コントロールとその親ウィンドウの間に一種のデッドロックが発生しているようです。

「キュリオザー」、EDITをSTATICコントロールに置き換えると機能します。

これについての本当の説明/解決策はないので、答えというよりは手がかりです...

PS: SS_LEFT と SS_CENTERIMAGE は EDIT コントロールには有効ではないことに注意してください。代わりに ES_* 定義を使用してください。

于 2012-11-13T13:14:51.833 に答える
0

他のスレッドを待つ前に、イベント ループをロールさせる必要があります。.NET では、 になりますApplicaiton.DoEvents()。それで検索すると、関連する質問がたくさんあるようです...

于 2012-11-13T11:14:00.660 に答える
0

SetWindowTextWindows テキストを更新するためにメッセージを送信します。メッセージは、メッセージ キューを処理するときにメッセージ ループで処理されます。

ClickHandlerただし、 (への呼び出しを介して)ブロックしてWaitForSingleObjectいるため、から戻るまでメッセージキューは処理されません。ClickHandler

于 2012-11-13T11:17:12.097 に答える