I have a custom slider in a toolbar. In order to show the slider in the toolbar it is wrapped in a CMFCToolBarButton
derived class.
The slider uses OnCustomDraw
to perform its rendering:
BEGIN_MESSAGE_MAP(CCustomSlider, CSliderCtrl)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()
void CCustomSlider::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
const auto lpcd = (LPNMCUSTOMDRAW)pNMHDR;
std::cout << "Draw stage: " << lpcd->dwDrawStage << '\n'; // for debugging purposes
switch (lpcd->dwDrawStage) {
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT: // custom drawing done here
switch (lpcd->dwItemSpec) {
// ...
}
break;
}
}
(For those interested in customizing a slider, I followed this tutorial).
At some point of my application I have to force redrawing the slider because the user changes its visual style.
I've tried the following (including combinations) without succeed:
slider.Invalidate();
slider.GetOwner()->SendMessage(WM_COMMAND, m_nID);
(m_nID
is the command ID the slider sends)slider.SendNotifyMessageA(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
The same with the wrapper. I've also tried forcing the toolbar to be redrawn:
toolbar.AdjustLayout();
toolbar.Invalidate();
toolbar.RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
The rest of the application is refreshing correctly when the visual style changes (including the toolbar), but not the slider.
The slider updates correctly if I resize the window.
As far as I've been able to find, it seems that I'm not sending the correct message to the OnCustomDraw
. When redrawn by myself it shows the draw stage is CDDS_PREPAINT
, while on the resize it's called several times, some of them including the CDDS_ITEMPREPAINT
, so it seems I'm only calling for a general update without indicating the specific items, but I don't know how to do it.
In overall question is then: How can I force a redraw of this control?