上面cha的回复是正确的解决方案。为了使控件服从 SetMonthCalFont 调用,您必须禁用视觉主题。虽然有一些技巧。
1)您不能只在 CDateTimeCtrl 对象上调用 SetWindowTheme,因为该调用仅适用于该即时窗口而不是子窗口。月份下拉菜单是一个子窗口,因此不受影响。因此,您必须处理控件的 DTN_DROPDOWN 通知,并在其中获取子月份控件并从中删除视觉主题。
2)在发送DTN_DROPDOWN通知之前确定月份子控件的大小/位置。因此,即使您执行上面的#1,它的大小也不会正确。所以,你必须更新大小。
3) 显然,意图确实是传递一个空字符串而不是一个带有 1 个空格的字符串,尽管 MSDN 文档似乎表明了这一点。
4) 下面的代码没有考虑日历下拉控件靠近屏幕边缘的情况。如果发生这种情况,可能需要修改代码以解决它并移动其位置以使其仍然可见。
上面的信息由 Microsoft 支持中的 Dave Anderson 提供,下面的代码解决了问题并让控件使用自定义字体正确显示。
因此,我在对话框 InitInstance() 中的 CDateTimeCtrl 对象上调用 SetMonthCalFont(),然后还使用以下代码处理 DTN_DROPDOWN 通知。
请注意,Dave 提供了一个警告,“这种方法依赖于日期和时间选择器控件的实现细节,这些细节将来可能会发生变化,并可能导致下面的代码中断”。
void DSomeDialog::OnDtnDropdownMyDateTimeCtrl(NMHDR *pNMHDR, LRESULT *pResult)
{
HWND hWndDateTime = (HWND)pNMHDR->hwndFrom;
HWND hWndMonthCal = DateTime_GetMonthCal(hWndDateTime);
HWND hWndDropDown = ::GetParent(hWndMonthCal);
DWORD dwWidth;
WINDOWINFO wi;
if (hWndMonthCal && hWndDropDown)
{
RECT rcIdeal;
//
// Remove the window theme from the month calendar
// control
SetWindowTheme(hWndMonthCal, L"", L"");
//
// Get the ideal size of the month calendar control
ZeroMemory(&rcIdeal, sizeof(rcIdeal));
MonthCal_GetMinReqRect(hWndMonthCal, &rcIdeal);
dwWidth = MonthCal_GetMaxTodayWidth(hWndMonthCal);
if (dwWidth > (DWORD)rcIdeal.right)
{
rcIdeal.right = dwWidth;
}
//
// Add some padding
InflateRect(&rcIdeal, 3, 3);
//
// Determine the new size of the drop down window such
// that the client area of the window is large enough
// to display the month calendar control
ZeroMemory(&wi, sizeof(wi));
wi.cbSize = sizeof(WINDOWINFO);
::GetWindowInfo(hWndDropDown, &wi);
AdjustWindowRectEx(&rcIdeal, wi.dwStyle, FALSE, wi.dwExStyle);
//
// Update the size of the drop down window
::SetWindowPos(hWndDropDown,
NULL,
0,
0,
rcIdeal.right - rcIdeal.left,
rcIdeal.bottom - rcIdeal.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
}
*pResult = 0;
}