日時指定コントロールでのコールバック フィールドの使い方

更新 : 2007 年 11 月

日時指定フィールドを定義する標準書式文字のほかに、カスタム書式指定文字列の一部をコールバック フィールドに指定して、表示形式をカスタマイズできます。コールバック フィールドを宣言するには、書式指定文字列の該当箇所に文字 "X" (ASCII コード 88) を 1 つ以上指定します。たとえば、"'Today is: 'yy'/'MM'/'dd' (Day 'X')'" と指定すると、日時指定コントロールに、現在の日時が、年、月、日、年の通算日の形式で表示されます。

1887cywc.alert_note(ja-jp,VS.90).gifメモ :

コールバック フィールド内の X の数は、表示される文字数に対応していません。

"X" 文字を繰り返すことで、カスタム文字列の複数のコールバック フィールドを識別できます。したがって、書式指定文字列 "XXddddMMMdd', 'yyyXXX" では、2 種類の固有のコールバック フィールド "XX" および "XXX" が識別されます。

1887cywc.alert_note(ja-jp,VS.90).gifメモ :

コールバック フィールドは有効なフィールドとして処理されるため、アプリケーションで DTN_WMKEYDOWN 通知メッセージを処理する必要があります。

日時指定コントロールでのコールバック フィールドは、以下の 3 段階で実装します。

  • カスタム書式指定文字列の初期化

  • DTN_FORMATQUERY 通知の処理

  • DTN_FORMAT 通知の処理

カスタム書式指定文字列の初期化

CDateTimeCtrl::SetFormat を呼び出してカスタム文字列を初期化します。詳細については、「日時指定コントロールでのカスタム書式指定文字列の使い方」を参照してください。通常、カスタム書式指定文字列を設定する場所は、コンテナとなるダイアログ クラスの OnInitDialog 関数またはコンテナとなるビュー クラスの OnInitialUpdate 関数です。

DTN_FORMATQUERY 通知の処理

コントロールで書式指定文字列が解析され、コールバック フィールドであることが認識されると、DTN_FORMAT 通知メッセージ、および DTN_FORMATQUERY 通知メッセージが送信されます。コールバック フィールド文字列は通知と共に指定されているので、どのコールバック フィールドがクエリの対象になっているかを判断できます。

DTN_FORMATQUERY 通知は、現在のコールバック フィールドに表示される文字列の最大許容サイズをピクセル単位で取得するために送信されます。

この値を正しく計算するには、コントロールの表示フォントを基に、フィールドに代入される文字列の高さと幅を計算します。文字列の実際の計算は、Win32 関数である GetTextExtentPoint32 を呼び出して行います。サイズが決定したら、値をアプリケーションに戻し、ハンドラ関数を終了します。

次のコードは、コールバック文字列のサイズを指定する例です。

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;
}
1887cywc.alert_note(ja-jp,VS.90).gifメモ :

NMDATETIMEFORMAT 構造体へのポインタを見つけるには、通知ハンドラの最初のパラメータを該当する型にキャストします。

参照

概念

コントロール (MFC)

参照

CDateTimeCtrl の使い方