Andrew Truckle
Andrew Truckle

Reputation: 19195

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.

Upvotes: 1

Views: 38

Answers (1)

Andrew Truckle
Andrew Truckle

Reputation: 19195

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.

Upvotes: 0

Related Questions