如何从未创建该窗口的线程更新该窗口
How to update a Window from a thread that did not create that Window?
我想创建一个能够在主线程(创建 GUI)运行一些长计算时更新 GUI 元素的线程,我不知道该怎么做。我正在使用MSVC++中的win32 API。
由于这些计算很长且占用大量 RAM,因此我想避免弄乱它们并将它们放在线程中。这意味着我希望能够直接从线程处理此 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++中执行此操作的正确过程的资源,但我正在寻找与此 MSDN 资源(在 C# 中)类似的内容。
如果这有用,我当然可以上传我尝试的整个代码,但我认为我可能走错了路,所以我只是包含了这个片段。
不能让 UI 线程执行工作,并从工作线程更新 UI。系统根本不以这种方式工作。主线程需要保持响应并及时处理其消息队列。与窗口的交互需要从 UI 线程执行。
您只需反转工作分配即可。让 UI 线程在 UI 上工作,并让工作线程执行密集型工作。
您似乎担心密集的工作会花费时间并使用内存,并且线程不适合该任务。但事实并非如此。线程可用于执行长时间运行的计算。线程能够使用内存。
似乎你已经为任何事情而感到头晕目眩。在 UI 线程上处理 UI,并在工作线程上执行工作。仅此而已。
传递一个指向HWND display
的指针。
CreateThread()
使用
HANDLE myThreadHandle = CreateThread(0, 0, myThread, (LPVOID)&display, 0, &myThreadID);
在您的线程使用中:
HWND hwnd = (HWND)(*threadParameter);
我想创建一个能够更新 GUI 元素的线程 而主线程(创建 GUI)运行时间较长 计算
如注释中所述,工作应该在工作线程中完成,让主线程处理绘图、鼠标、键盘等。
就个人而言,我更喜欢为此使用用户消息,并将它们发布到父窗口(而不是直接发布WM_SETTEXT
子窗口),并让父窗口处理其余部分。
- 自 Windows 10 20H1 以来,具有单独线程的多个窗口停止工作
- 如何从单独的线程控制 SFML 窗口?
- DirectX 窗口通过多窗口和多线程快速闪烁
- 如何将C++ dll 在 C# 窗口窗体应用程序下的工作线程中运行
- 在工作线程中使用 QT 主窗口
- 是否可以从其他线程隐藏qt小部件窗口
- 是否可以使用标准的C 线程而不是FLTK超时来更新窗口
- C++从异步线程更新窗口
- 将工作线程信号与主窗口插槽 (Qt5) 连接时出错
- 使用第二个线程快速更新 GUI 窗口会通过调整窗口大小或移动窗口而崩溃
- 将程序(.EXE)作为线程 - 窗口C 执行
- SDL2在不同线程中的两个窗口
- 2个线程 - 一个带有OpenGL窗口的线程,第二个带有WXWIDGETS的窗口
- SIGSEGV 信号处理程序不是从辅助线程 c++ 窗口调用的
- Qt 窗口包含提升线程标头失败
- 两个窗口-一个由线程随机输出修改
- 如果最初发出 IO 的线程在窗口 8 下的 ReadFile 中阻塞,则 GetQueuedCompletionStatus 无法将 IO 从 IOCP 中取消排队
- 关闭其他线程的对话框后无法从主窗口聚焦
- C++ 中窗口线程的异常输出
- 如何让窗口线程同时使用两个函数