Usar campos de devolución de llamada en un control de selector de fecha y hora
Además de los caracteres de formato estándar que definen campos del selector de fecha y hora, puede personalizar la salida especificando determinadas partes de una cadena de formato personalizado como campos de devolución de llamada. Para declarar un campo de devolución de llamada, incluya uno o varios caracteres "X" (código ASCII 88) en cualquier parte del cuerpo de la cadena de formato. Por ejemplo, la siguiente cadena "'Today is: 'yy'/'MM'/'dd' (Day 'X')'" (Hoy es: 'aa'/'mm'/'dd' [Día 'X']) hace que el control de selector de fecha y hora muestre el valor actual como el año seguido del mes, la fecha y, por último, el día del año.
Nota:
El número de X en un campo de devolución de llamada no se corresponde con el número de caracteres que se mostrarán.
Puede distinguir entre varios campos de devolución de llamada en una cadena personalizada repitiendo el carácter "X". Por lo tanto, la cadena de formato "XXddddMMMdd", "yyyXXX" contiene dos campos de devolución de llamada únicos, "XX" y "XXX".
Nota:
Los campos de devolución de llamada se tratan como campos válidos, por lo que la aplicación debe estar preparada para controlar los mensajes de notificación DTN_WMKEYDOWN.
La implementación de campos de devolución de llamada en el control de selector de fecha y hora consta de tres partes:
Inicialización de la cadena de formato personalizado
Control de la notificación DTN_FORMATQUERY
Control de la notificación DTN_FORMAT
Inicialización de la cadena de formato personalizado
Inicialice la cadena personalizada con una llamada a CDateTimeCtrl::SetFormat
. Para obtener más información, consulte Usar cadenas de formato personalizado en un control de selector de fecha y hora. Un lugar común para establecer la cadena de formato personalizado está en la función OnInitDialog
de la clase de diálogo contenedora o en la función OnInitialUpdate
de la clase de vista contenedora.
Control de la notificación DTN_FORMATQUERY
Cuando el control analiza la cadena de formato y encuentra un campo de devolución de llamada, la aplicación envía los mensajes de notificación DTN_FORMAT y DTN_FORMATQUERY. La cadena de campo de devolución de llamada se incluye con las notificaciones para que pueda determinar qué campo de devolución de llamada se está consultando.
La notificación DTN_FORMATQUERY se envía para recuperar el tamaño máximo permitido en píxeles de la cadena que se mostrará en el campo de devolución de llamada actual.
Para calcular correctamente este valor, debe calcular el alto y el ancho de la cadena, para sustituirlo por el campo, mediante la fuente de presentación del control. El cálculo real de la cadena se logra fácilmente con una llamada a la función GetTextExtentPoint32 Win32. Una vez determinado el tamaño, vuelva a pasar el valor a la aplicación y salga de la función del controlador.
El ejemplo siguiente es un método para proporcionar el tamaño de la cadena de devolución de llamada:
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;
}
Una vez calculado el tamaño del campo de devolución de llamada actual, debe proporcionar un valor para el campo. Esto se hace en el controlador para la notificación de DTN_FORMAT.
Control de la notificación DTN_FORMAT
La aplicación usa la notificación DTN_FORMAT para solicitar la cadena de caracteres que se sustituirá. En el ejemplo siguiente se muestra un posible método:
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;
}
Nota:
El puntero a la estructura NMDATETIMEFORMAT se localiza convirtiendo el primer parámetro del controlador de la notificación en el tipo adecuado.