【发布时间】:2016-01-15 18:34:26
【问题描述】:
我想创建一个能够更新 GUI 元素的线程,而主线程(创建 GUI)运行一些长时间的计算,但我不知道该怎么做。我在 MSVC++ 中使用 win32 API。
因为这些计算时间长且占用大量内存,我想避免弄乱它们并将它们放在一个线程中。这意味着我希望能够直接从线程处理此 GUI 更新,而无需主窗口处理任何 WndProc 消息。
在最简单的情况下,我只想能够从线程内部更新单个静态控件,但最终我希望能够在主窗口上绘图或在数据滚动时更新其中的位图图像从外部设备。我并不是说线程要完全接管窗口过程。
我尝试过非常简单的方法,例如:
// Global
HWND display;
DWORD WINAPI myThread(LPVOID threadParameter);
int APIENTRY WinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow){
// Blah Blah Create main Window and display object, which is a "STATIC" Blah Blah
HANDLE myThreadHandle = CreateThread(0, 0, myThread, (LPVOID)display, 0, &myThreadID);
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT7));
MSG msg;
// Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CloseHandle(myThreadHandle);
return (int) msg.wParam;
}
// other function outside WinMain(){
DWORD WINAPI myThread(LPVOID threadParameter) {
// I've passed in my static handle here.
HWND hwnd = (HWND)threadParameter;
// My hope was that this would update the text of the static window, but...
PostMessage(hwnd, WM_SETTEXT, 0, (LPARAM)"10");
// After this message the static window still hasn't updated with the text "10".
return 0;
};
但这不起作用(静态控件只是不更新)而且这只是一个猜测,所以我可能在做一些愚蠢的事情。我找不到任何有关在 C++ 中执行此操作的正确过程的资源,但我正在寻找与 this MSDN resource (在 C# 中)类似的东西。
如果有用的话,我当然可以上传我尝试的全部代码,但我认为我可能走错了路,所以我只包含了这个 sn-p。
【问题讨论】:
-
交换你的线程,后台线程长计算,forground/windows线程更新UI。计算完成后,从后台线程向前台窗口发布消息,
-
@RichardCritten 所说的。仅当您调用 GetMessage/DispatchMessage 时才会发送窗口消息。如果您的主线程忙于计算,则无法处理已发布的窗口消息。
-
我已经考虑过了。那么这可能是一个单独的问题,但是长计算非常占用 RAM,因为我需要能够处理几个非常大的数组(在极端情况下高达 ~1 GB)并将它们传递给我正在编程的外部设备,所以我决定不想把它放在一个线程中。你是说我想做的事情(从内部线程更新 GUI)是不可能的?
-
@aquirdturtle 将数组放在堆上,只是传递指针。您不能从另一个线程更新 Window,它必须从创建它的线程更新。您必须在创建 Window 的线程上发送消息才能发生更新/更改。
-
工作线程被称为是有原因的,它们确实可以工作。不要在你的 UI 线程上工作。
标签: c++ multithreading user-interface winapi