在日期和时间选取器控件中使用回调字段
除了定义日期和时间选取器字段的标准格式字符之外,您还可以通过将自定义格式字符串的某些部分指定为回调字段来自定义您的输出。 若要声明回调字段,请在格式字符串主体中的任何位置包含一个或多个“X”字符(ASCII 代码 88)。 例如,以下字符串“Today is: 'yy'/'MM'/'dd' (Day 'X')'”会使日期和时间选取器控件将当前值按照“年、月、日和年积日”格式来显示。
注意
回调字段中 X 的数量并不对应于将要显示的字符数。
您可以通过重复“X”字符在自定义字符串中区分多个回调字段。 因此,格式字符串“XXddddMMMdd', '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 结构的指针。