Supporting dark mode with CGridCellCombo in CGridCtrl

ChuckieAJ 311 Reputation points
2025-03-07T18:56:45.17+00:00

Info: CGridCellCombo

The CodeProject site is not yet working correctly so I could provide download link if needed.In-place editing in dark mode still uses light controls. Here are some examples:

Image Image

This is the pertinent code from the class:

 // Create a control to do the editing
BOOL CGridCellCombo::Edit(int nRow, int nCol, CRect rect, CPoint /* point */, UINT nID, UINT nChar)
{
    m_bEditing = TRUE;
    
    // CInPlaceList auto-deletes itself
    m_pEditWnd = new CInPlaceList(GetGrid(), rect, GetStyle(), nID, nRow, nCol, 
                                  GetTextClr(), GetBackClr(), m_Strings, GetText(), nChar);
    DarkModeTools::ApplyThemeToControl(m_pEditWnd);

    return TRUE;
}


// Override draw so that when the cell is selected, a drop arrow is shown in the RHS.
BOOL CGridCellCombo::Draw(CDC* pDC, int nRow, int nCol, CRect rect,  BOOL bEraseBkgnd /*=TRUE*/)
{
#ifdef _WIN32_WCE
    return CGridCell::Draw(pDC, nRow, nCol, rect,  bEraseBkgnd);
#else
 	//Used for merge cells
	//by Huang Wei
	if(	m_Hide && !IsMerged())
	{
		return TRUE;
	}

   // Cell selected?
    //if ( !IsFixed() && IsFocused())
    if (GetGrid()->IsCellEditable(nRow, nCol) && !IsEditing())
    {
        // Get the size of the scroll box
        CSize sizeScroll(GetSystemMetrics(SM_CXVSCROLL), GetSystemMetrics(SM_CYHSCROLL));

        // enough room to draw?
        if (sizeScroll.cy < rect.Width() && sizeScroll.cy < rect.Height())
        {
            // Draw control at RHS of cell
            CRect ScrollRect = rect;
            ScrollRect.left   = rect.right - sizeScroll.cx;
            ScrollRect.bottom = rect.top + sizeScroll.cy;

			HTHEME hTheme = OpenThemeData(AfxGetMainWnd()->GetSafeHwnd(), L"COMBOBOX");
			if (hTheme)
			{
				int state = GetGrid()->IsWindowEnabled() ? CBXS_NORMAL : CBXS_DISABLED;
				DrawThemeBackground(hTheme, pDC->GetSafeHdc(), CP_DROPDOWNBUTTON, state, &ScrollRect, nullptr);
				CloseThemeData(hTheme);
			}
			else
			{
				// Fallback to DrawFrameControl if themes are not available
				if (GetGrid()->IsWindowEnabled())
					pDC->DrawFrameControl(ScrollRect, DFC_SCROLL, DFCS_SCROLLDOWN);
				else
					pDC->DrawFrameControl(ScrollRect, DFC_SCROLL, DFCS_SCROLLDOWN | DFCS_INACTIVE);
			}

            // Adjust the remaining space in the cell
            rect.right = ScrollRect.left;
        }
    }

    CString strTempText = GetText();
    if (IsEditing())
        SetText(_T(""));

    // drop through and complete the cell drawing using the base class' method
    BOOL bResult = CGridCell::Draw(pDC, nRow, nCol, rect,  bEraseBkgnd);

    if (IsEditing())
        SetText(strTempText);

	return bResult;
#endif
}

I tried to tweak by using SetWindowTheme but no joy. I just can;t sucessfully upgrade CGridCtrl and the combo cell derivative to use dark mode theme.

Update

See: https://github.com/ChrisMaunder/gridctrl_combo/issues/1

If I add the code to the CInPlaceLIST constructor it will show the combo as dark:

SetWindowTheme(GetSafeHwnd(), L"DarkMode_CFD", nullptr);
COMBOBOXINFO cbi{};
cbi.cbSize = sizeof(COMBOBOXINFO);
if (GetComboBoxInfo(pControl->GetSafeHwnd(), &cbi) && cbi.hwndList)
{
	SetWindowTheme(cbi.hwndList, L"DarkMode_Explorer", nullptr);
}

Image

But the in-place edit / droplist is still white. I tried to modify the CtlClr etc but no joy.

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,874 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.