Sdílet prostřednictvím


Použití polí zpětného volání v ovládacím prvku pro výběr data a času

Kromě standardních znaků formátu, které definují pole pro výběr data a času, můžete výstup přizpůsobit zadáním určitých částí řetězce vlastního formátu jako polí zpětného volání. Chcete-li deklarovat pole zpětného volání, zadejte jeden nebo více znaků "X" (kód ASCII 88) kdekoli v těle řetězce formátu. Například následující řetězec "Dnes je: yyy'/'MM'/'dd' (Den 'X')", způsobí, že ovládací prvek pro výběr data a času zobrazí aktuální hodnotu jako rok následovaný měsícem, datem a nakonec dnem v roce.

Poznámka

Počet X v poli zpětného volání neodpovídá počtu znaků, které se zobrazí.

Opakováním znaku "X" můžete rozlišovat mezi více poli zpětného volání ve vlastním řetězci. Řetězec formátu "XXddddMMMddd", "yyyXXX" obsahuje dvě jedinečná pole zpětného volání, XX a XXX.

Poznámka

Pole zpětného volání se považují za platná pole, takže aplikace musí být připravená na zpracování DTN_WMKEYDOWN zpráv oznámení.

Implementace polí zpětného volání v ovládacím prvku pro výběr data a času se skládá ze tří částí:

  • Inicializace řetězce vlastního formátu

  • Zpracování oznámení DTN_FORMATQUERY

  • Zpracování oznámení DTN_FORMAT

Inicializace řetězce vlastního formátu

Inicializace vlastního řetězce voláním CDateTimeCtrl::SetFormat. Další informace naleznete v tématu Použití řetězců vlastního formátu v ovládacím prvku Výběr data a času. Běžným místem pro nastavení vlastního řetězce formátu je OnInitDialog funkce třídy dialogového okna nebo OnInitialUpdate funkce obsahující třídy zobrazení.

Zpracování oznámení DTN_FORMATQUERY

Když ovládací prvek analyzuje formátovací řetězec a narazí na pole zpětného volání, aplikace odešle DTN_FORMAT a DTN_FORMATQUERY oznámení zprávy. Řetězec pole zpětného volání je součástí oznámení, abyste mohli určit, které pole zpětného volání se dotazuje.

Oznámení DTN_FORMATQUERY se odešle, aby se načetla maximální povolená velikost v pixelech řetězce, který se zobrazí v aktuálním poli zpětného volání.

Chcete-li správně vypočítat tuto hodnotu, je nutné vypočítat výšku a šířku řetězce, aby bylo možné nahradit pole pomocí zobrazovaného písma ovládacího prvku. Skutečný výpočet řetězce se snadno dosáhne voláním funkce GetTextExtentPoint32 Win32. Po určení velikosti předejte hodnotu zpět aplikaci a ukončete funkci obslužné rutiny.

Následující příklad je jednou z metod zadání velikosti řetězce zpětného volání:

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;
}

Po výpočtu velikosti aktuálního pole zpětného volání je nutné zadat hodnotu pole. To se provádí v obslužné rutině pro oznámení DTN_FORMAT.

Zpracování oznámení DTN_FORMAT

Aplikace používá oznámení DTN_FORMAT k vyžádání řetězce znaků, který bude nahrazen. Následující příklad ukazuje jednu možnou metodu:

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;
}

Poznámka

Ukazatel na strukturu NMDATETIMEFORMAT je nalezen přetypováním prvního parametru obslužné rutiny oznámení na správný typ.

Viz také

Používání atributu CDateTimeCtrl
Ovládací prvky