visual-c++mfcdatetimepicker

Setting colour properties of Date / Time Picker in MFC


Create a Dialog project and:

In OnInitDialog do the following:

SetWindowTheme(m_Date.GetSafeHwnd(), L" ", L" ");
m_Date.SetMonthCalColor(MCSC_BACKGROUND, DarkModeTools::kDarkSheetBackgroundColor);
m_Date.SetMonthCalColor(MCSC_MONTHBK, DarkModeTools::kDarkControlBackgroundColor);
m_Date.SetMonthCalColor(MCSC_TEXT, DarkModeTools::kDarkTextColor);
m_Date.SetMonthCalColor(MCSC_TITLEBK, RGB(0, 120, 215));
m_Date.SetMonthCalColor(MCSC_TITLETEXT, DarkModeTools::kDarkTextColor);
m_Date.SetMonthCalColor(MCSC_TRAILINGTEXT, RGB(128, 128, 128));

// m_Date.SetMonthCalFont
auto pCalendar = m_Date.GetMonthCalCtrl();
if (pCalendar)
{
    SetWindowTheme(pCalendar->GetSafeHwnd(), L" ", L" ");
    // pCalendar->SetCalendarBorder(8); // Default is 4
    pCalendar->SetColor(MCSC_BACKGROUND, DarkModeTools::kDarkSheetBackgroundColor);   // Dark background
    pCalendar->SetColor(MCSC_MONTHBK, DarkModeTools::kDarkControlBackgroundColor);      // Slightly lighter dark
    pCalendar->SetColor(MCSC_TEXT, DarkModeTools::kDarkTextColor);      // Light gray text
    pCalendar->SetColor(MCSC_TITLEBK, RGB(0, 120, 215));     // Windows 11 accent blue
    pCalendar->SetColor(MCSC_TITLETEXT, DarkModeTools::kDarkTextColor); // White text for contrast
    pCalendar->SetColor(MCSC_TRAILINGTEXT, RGB(128, 128, 128)); // Dimmed gray for non-month days
}

None of the properties are applied:

enter image description here

Yet, if I drag a Calendar control onto my dialog and do a similar exercise, it works:

enter image description here

I saw this related question:

Is there a way to get the handle of the entry field in a date time picker (DTP)?

To quote:

hwndEdit only seems to be valid when the control has the DTS_APPCANPARSE style and you click the date text with the mouse (I tested this with OutputDebugString and a timer). The edit control is created and destroyed dynamically. The hwndUD handle is only valid if DTS_UPDOWN is set and the hwndDropDown is only valid while the dropdown is visible.

But it doesn't help me colour the components. It looks like I have to go ownerdraw, but the bulk of this is fine. Just the remaining little bits of white.


Solution

  • I missed part of the documentation about GetMonthCalCtrl:

    Date and time picker controls create a child month calendar control when the user selects the drop-down arrow. When the CMonthCalCtrl object is no longer needed, it's destroyed, so your application must not rely on storing the object representing the date time picker control's child month calendar.

    datetimepicker with calendar

    So, I derived a class and added the following handler:

    void CDarkModeDateTimeCtrl::OnDtnDropdown(NMHDR* pNMHDR, LRESULT* pResult)
    {
        auto pCalendar = GetMonthCalCtrl();
        if (pCalendar)
        {
            SetWindowTheme(pCalendar->GetSafeHwnd(), L" ", L" ");
            // pCalendar->SetCalendarBorder(8); // Default is 4
            pCalendar->SetColor(MCSC_BACKGROUND, DarkModeTools::kDarkSheetBackgroundColor);   // Dark background
            pCalendar->SetColor(MCSC_MONTHBK, DarkModeTools::kDarkControlBackgroundColor);      // Slightly lighter dark
            pCalendar->SetColor(MCSC_TEXT, DarkModeTools::kDarkTextColor);      // Light gray text
            pCalendar->SetColor(MCSC_TITLEBK, RGB(0, 120, 215));     // Windows 11 accent blue
            pCalendar->SetColor(MCSC_TITLETEXT, DarkModeTools::kDarkTextColor); // White text for contrast
            pCalendar->SetColor(MCSC_TRAILINGTEXT, RGB(128, 128, 128)); // Dimmed gray for non-month days
        }
    
        *pResult = 0;
    }
    

    This works correctly. Bu I still have issues with my use of SetMonthCalColor.