从子线程绘制到 window
Drawing to window from child thread
我的应用程序从工作线程绘制图形已有 10 多年了,我从未遇到过任何问题。工作线程像这样绘制到我的 HWND
(由主线程创建):
hdc = GetDC(hwnd);
SetDIBitsToDevice() ... or StretchDIBits()
ReleaseDC(hwnd, hdc);
将我的应用程序移植到其他平台后,我开始意识到,在许多平台(例如 macOS)上,从主线程以外的任何其他线程绘制通常是行不通的。我的研究表明这可能也适用于 Win32,但我仍然缺乏明确的答案。
因此,我的问题:
是否允许从 未 创建要绘制到的 window 的工作线程绘制到我的 window,如上所示?请注意,工作线程实际上是唯一绘制到 window 的线程。主线程不做任何绘图。甚至 WM_PAINT
也没有。在我的例子中,在 WM_PAINT
中绘制是不必要的,因为工作线程以 50fps 的速度绘制。
如果不允许,将绘图从工作线程委托给主线程的最佳方法是什么?
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to?
它可能不是您问题的最佳解决方案,但它是安全的,只要您遵守 GetDC
:
的记录规则
- Note that the handle to the DC can only be used by a single thread at any one time.
ReleaseDC
必须从调用 GetDC
. 的同一个线程调用
如果您确实从多个线程渲染到同一设备上下文,则您有责任同步对它的访问。*
如评论中所述,更好的解决方案是从工作线程生成 DIB,并让该线程通过调用 RedrawWindow
更新 window。然后主线程可以在其 WM_PAINT
处理程序中 StretchBlt
。跨线程调用 RedrawWindow
实现同步屏障。当调用 returns 时,目标线程上的渲染已 运行 完成,并且 re-use DIB 是安全的。
* 参见 Thread affinity of user interface objects, part 2: Device contexts。
我的应用程序从工作线程绘制图形已有 10 多年了,我从未遇到过任何问题。工作线程像这样绘制到我的 HWND
(由主线程创建):
hdc = GetDC(hwnd);
SetDIBitsToDevice() ... or StretchDIBits()
ReleaseDC(hwnd, hdc);
将我的应用程序移植到其他平台后,我开始意识到,在许多平台(例如 macOS)上,从主线程以外的任何其他线程绘制通常是行不通的。我的研究表明这可能也适用于 Win32,但我仍然缺乏明确的答案。
因此,我的问题:
是否允许从 未 创建要绘制到的 window 的工作线程绘制到我的 window,如上所示?请注意,工作线程实际上是唯一绘制到 window 的线程。主线程不做任何绘图。甚至 WM_PAINT
也没有。在我的例子中,在 WM_PAINT
中绘制是不必要的,因为工作线程以 50fps 的速度绘制。
如果不允许,将绘图从工作线程委托给主线程的最佳方法是什么?
Is it allowed to draw to my window like shown above from a worker thread that did not create the window it is drawing to?
它可能不是您问题的最佳解决方案,但它是安全的,只要您遵守 GetDC
:
- Note that the handle to the DC can only be used by a single thread at any one time.
ReleaseDC
必须从调用GetDC
. 的同一个线程调用
如果您确实从多个线程渲染到同一设备上下文,则您有责任同步对它的访问。*
如评论中所述,更好的解决方案是从工作线程生成 DIB,并让该线程通过调用 RedrawWindow
更新 window。然后主线程可以在其 WM_PAINT
处理程序中 StretchBlt
。跨线程调用 RedrawWindow
实现同步屏障。当调用 returns 时,目标线程上的渲染已 运行 完成,并且 re-use DIB 是安全的。
* 参见 Thread affinity of user interface objects, part 2: Device contexts。