除了定义日期和时间选取器字段的标准格式字符之外,还可以通过将自定义格式字符串的某些部分指定为回调字段来自定义输出。 若要声明回调字段,请在格式字符串的正文中包含一个或多个“X”字符(ASCII Code 88)。 例如,以下字符串“'Today is: 'yy'/'MM'/'dd' (Day 'X''”会导致日期和时间选取器控件将当前值显示为年份,后跟月份、日期,最后显示一年中的日期。
注释
回调字段中的 X 数与将显示的字符数不对应。
可以通过重复“X”字符来区分自定义字符串中的多个回调字段。 因此,格式字符串“XXddMMMdd”、“yyyXXX”包含两个唯一回调字段“XX”和“XXX”。
注释
回调字段被视为有效字段,因此应用程序必须准备好处理DTN_WMKEYDOWN通知消息。
在日期和时间选取器控件中实现回调字段由三个部分组成:
初始化自定义格式字符串
处理DTN_FORMATQUERY通知
处理DTN_FORMAT通知
初始化自定义格式字符串
使用调用 CDateTimeCtrl::SetFormat
初始化自定义字符串。 有关详细信息,请参阅 在日期和时间选取器控件中使用自定义格式字符串。 设置自定义格式字符串的一个常见位置是 OnInitDialog
包含对话类的函数或 OnInitialUpdate
包含视图类的函数。
处理DTN_FORMATQUERY通知
当控件分析格式字符串并遇到回调字段时,应用程序会发送DTN_FORMAT和DTN_FORMATQUERY通知消息。 回调字段字符串包含在通知中,以便可以确定正在查询的回调字段。
发送DTN_FORMATQUERY通知,以检索将在当前回调字段中显示的字符串的最大允许大小(以像素为单位)。
若要正确计算此值,必须使用控件的显示字体计算字符串的高度和宽度,以替换字段。 通过调用 GetTextExtentPoint32 Win32 函数,可以轻松实现字符串的实际计算。 确定大小后,将该值传递回应用程序并退出处理程序函数。
以下示例是提供回调字符串大小的一种方法:
void CMyDialog::OnDtnFormatqueryDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMATQUERY pDTFormatQuery =
reinterpret_cast<LPNMDATETIMEFORMATQUERY>(pNMHDR);
CDC *pDC = NULL;
CFont *pFont = NULL;
CFont *pOrigFont = NULL;
// Prepare the device context for the GetTextExtentPoint32 call.
pDC = GetDC();
if (NULL == pDC)
{
return;
}
pFont = GetFont();
if (NULL == pFont)
{
pFont = new CFont();
VERIFY(pFont->CreateStockObject(DEFAULT_GUI_FONT));
}
pOrigFont = pDC->SelectObject(pFont);
// Check to see if this is the callback segment desired. If so,
// use the longest text segment to determine the maximum
// width of the callback field, and then place the information into
// the NMDATETIMEFORMATQUERY structure.
if (!_tcscmp(_T("X"), pDTFormatQuery->pszFormat))
{
::GetTextExtentPoint32(pDC->m_hDC, _T("366"), 3, &pDTFormatQuery->szMax);
}
// Reset the font in the device context then release the context.
pDC->SelectObject(pOrigFont);
ReleaseDC(pDC);
*pResult = 0;
}
计算当前回调字段的大小后,必须为该字段提供一个值。 此作在DTN_FORMAT通知的处理程序中完成。
处理DTN_FORMAT通知
应用程序使用DTN_FORMAT通知来请求将替换的字符串。 以下示例演示了一种可能的方法:
void CMyDialog::OnDtnFormatDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMDATETIMEFORMAT pDTFormat = reinterpret_cast<LPNMDATETIMEFORMAT>(pNMHDR);
COleDateTime oCurTime;
m_DateTimeCtrl.GetTime(oCurTime);
_itot_s(oCurTime.GetDayOfYear(), pDTFormat->szDisplay,
sizeof(pDTFormat->szDisplay) / sizeof(TCHAR), 10);
*pResult = 0;
}
注释
通过将通知处理程序的第一个参数强制转换为正确的类型来找到指向 NMDATETIMEFORMAT 结构的指针。