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 控件和他的父窗口之间似乎存在一种死锁。

“Curioser”,如果您将 EDIT 替换为 STATIC 控件,它就可以工作。

我对此没有真正的解释/解决方案,所以它更像是一个线索而不是一个答案......

PS:请注意 SS_LEFT 和 SS_CENTERIMAGE 对 EDIT 控件无效,请改用 ES_* 定义。

于 2012-11-13T13:14:51.833 回答
0

在等待另一个线程之前,您需要让事件循环滚动。在 .NET 中它会是Applicaiton.DoEvents(). 用那个搜索,SO似乎有一堆相关的问题......

于 2012-11-13T11:14:00.660 回答
0

SetWindowText发送一条消息以更新 Windows 文本,并且在处理消息队列时,该消息将在您的消息循环中处理。

但是,您正在阻塞ClickHandler(通过对 的调用WaitForSingleObject),这意味着在您返回之前不会处理消息队列ClickHandler

于 2012-11-13T11:17:12.097 回答