Использование полей обратного вызова элемента выбора даты и времени
Помимо стандартных символов формата, определяющих поля выбора даты и времени, можно настроить выходные данные, указав определенные части строки настраиваемого формата в качестве полей обратного вызова. Чтобы объявить поле обратного вызова, добавьте один или несколько символов X (ASCII Code 88) в текст строки формата. Например, следующая строка "'Сегодня: 'yy'/'MM'/'dd" (Day 'X')", приводит к тому, что элемент управления выбора даты и времени отображает текущее значение в виде года, за которым следует месяц, дата и, наконец, день года.
Примечание.
Число X в поле обратного вызова не соответствует числу отображаемых символов.
Вы можете различать несколько полей обратного вызова в настраиваемой строке, повторяя символ X. Таким образом, строка формата "XXdddddMMMddd", "yxXXX" содержит два уникальных поля обратного вызова, "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 найден путем приведения первого параметра обработчика уведомлений к соответствующему типу.