Custom drawing of a Group Box in CDialog
I think that this is related to the answer here.
I have derived from CFindReplaceDialog
in an effort to render it in dark mode:
All is well (event the check boxes / radio controls 🤣). But the group box needs attantion. In my own dialogs I was switching off the theme and owner drawing:
void CMyStatic::OnPaint() {
CPaintDC dc(this); // Device context for painting
// Get the text to display
CString text;
GetWindowText(text);
// Get the client area
CRect rect;
GetClientRect(&rect);
// Use the same font as the parent window (dialog)
CFont* pOldFont = dc.SelectObject(GetParent()->GetFont());
// Calculate the text height
CSize textSize = dc.GetTextExtent(text);
int textHeight = textSize.cy;
// Adjust the frame position so the top border intersects the middle of the text
rect.top += textHeight / 2;
// Draw the group box border
// dc.DrawEdge(&rect, EDGE_ETCHED, BF_RECT);
// Draw a 1-pixel-thick frame
CPen pen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); // Use a 1-pixel pen
CPen* pOldPen = dc.SelectObject(&pen);
// Draw the top border
dc.MoveTo(rect.left, rect.top);
dc.LineTo(rect.left + 8, rect.top); // Leave space for the text
dc.MoveTo(rect.left + 8 + textSize.cx, rect.top); // Resume after the text
dc.LineTo(rect.right, rect.top);
// Draw the bottom border
dc.MoveTo(rect.left, rect.bottom - 1);
dc.LineTo(rect.right, rect.bottom - 1);
// Draw the left border
dc.MoveTo(rect.left, rect.top);
dc.LineTo(rect.left, rect.bottom - 1);
// Draw the right border
dc.MoveTo(rect.right - 1, rect.top);
dc.LineTo(rect.right - 1, rect.bottom - 1);
// Restore the old pen
dc.SelectObject(pOldPen);
// Set the text color and background mode
dc.SetTextColor(m_textColor);
dc.SetBkMode(OPAQUE); // Use OPAQUE mode to draw the text with a background
// Get the system background color for dialogs (typically COLOR_3DFACE or COLOR_BTNFACE)
// COLORREF bgColor = GetSysColor(COLOR_3DFACE);
COLORREF bgColor = RGB(32, 32, 32);
// Set the background color for the text
dc.SetBkColor(bgColor);
// Calculate the text position
rect.left += 8; // Indent the text slightly
rect.top -= textHeight / 2; // Move the text back up to its original position
// Draw the text with a background to mask out the border
dc.DrawText(text, &rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
// Restore the old font
dc.SelectObject(pOldFont);
}
But I can't use this approach with common dialogs. Now I am wondering if I can go down the same route as for checkboxes and radio controls, by using NM_CUSTOMDRAW
(since groupbox is also derived from button).
I know that we can detect if we are on a groupbox easily enough:
TCHAR className[256];
GetClassName(pControl->GetSafeHwnd(), className, 256);
if (_tcscmp(className, L"Button") == 0)
{
CButton* pButton = reinterpret_cast<CButton*>(pControl);
if (pButton)
{
DWORD buttonStyle = pButton->GetStyle();
if ((buttonStyle & BS_GROUPBOX) == BS_GROUPBOX)
{
// We need to draw the group box
}
}
}
Is there a better way to render the groupbox here in NM_CUSTOMDRAW
?