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);
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)
(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).