线程在UI更新之前启动

时间:2012-11-13 11:03:40

标签: c++ multithreading winapi

当我运行此代码时,文本会更新 AFTER 弹出线程中的消息框。

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
        );   
 }

3 个答案:

答案 0 :(得分:1)

我重现了这种行为,似乎EDIT控件和他的父窗口之间存在一种死锁,因为发布了WM_PAINT消息。

“Curioser”,如果用STATIC控件替换EDIT,它就有效。

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

SetWindowText发送消息以更新Windows文本,并在处理消息队列时在消息循环中处理消息。

但是,您在ClickHandler中阻止(通过调用WaitForSingleObject),这意味着在您从ClickHandler

返回之前不会处理消息队列