Sorry to be a wise-ass here , but there’s a simpler solution for this particular use-case. If the goal is only to refresh a display that already has the correct image handle set, it would be sufficient to call
SendMessage(m_cvDisp.GethWnd(), WM_PAINT, 0, 0);
or
PostMessage(m_cvDisp.GethWnd(), WM_PAINT, 0, 0);
in your non-UI thread to update the display control’s content.
However, @parsd provided the perfect entry point for a case where a simple m_cvDisp.Refresh()
is not sufficient because e.g. you need to call m_cvDisp.SetImage()
because your processing generates a new image rather than updating the content of an existing image.
In that case, use the code from @parsd and send the new image handle through the LPARAM
of your custom window message and modify the OnAsyncRefresh
as follows:
LRESULT CYourClass:OnAsyncRefresh(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam);
m_cvDisp.SetImage(reinterpret_cast<intptr_t>(lParam));
}
(well, maybe we should rename it to something like OnAsyncSetImage
in that case, but I guess you get what I am up to…)
The code from @parsd can also be easily extended to other use cases that are forbidden from within a non-UI thread like adding labels or overlay plugins to a display etc.
Generally speaking, doing anything that alters the state of the user interface from withing a non-UI thread is a no-go (some things might work most of the time, but effectively as soon as you touch your UI from a non-UI thread you enter the territory of undefined behavior).