次の方法で共有


日付と時刻の選択コントロールでのコールバック フィールドの使用

日付と時刻の選択フィールドを定義する標準の書式指定文字に加えて、カスタム書式指定文字列の特定の部分をコールバック フィールドとして指定することで、出力をカスタマイズできます。 コールバック フィールドを宣言するには、書式指定文字列の本文の任意の場所に 1 つ以上の "X" 文字 (ASCII コード 88) を含めます。 たとえば、次の文字列 "'Today is: 'yy'/'MM'/'dd' (Day 'X')' は、日付と時刻の選択コントロールに現在の値を年として表示し、その後に月、日付、最後に年の日を表示します。

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

"X" 文字を繰り返すことで、カスタム文字列内の複数のコールバック フィールドを区別できます。 したがって、書式指定文字列 "XXddddMMMdd"、'yyyXXX" には、"XX" と "XXX" の 2 つの一意のコールバック フィールドが含まれています。

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

日付と時刻の選択コントロールにコールバック フィールドを実装する方法は、次の 3 つの部分で構成されます。

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

  • DTN_FORMATQUERY通知の処理

  • DTN_FORMAT通知の処理

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

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

DTN_FORMATQUERY通知の処理

コントロールが書式指定文字列を解析し、コールバック フィールドを検出すると、アプリケーションはDTN_FORMATおよびDTN_FORMATQUERY通知メッセージを送信します。 コールバック フィールドの文字列は通知に含まれているため、クエリ対象のコールバック フィールドを特定できます。

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

この値を適切に計算するには、コントロールの表示フォントを使用して、フィールドに置き換える文字列の高さと幅を計算する必要があります。 文字列の実際の計算は、 GetTextExtentPoint32 Win32 関数を呼び出すと簡単に実現できます。 サイズが決まったら、値をアプリケーションに渡し、ハンドラー関数を終了します。

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

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通知は、置き換えられる文字列を要求するためにアプリケーションによって使用されます。 次の例は、考えられる 1 つの方法を示しています。

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 構造体へのポインターは、通知ハンドラーの最初のパラメーターを適切な型にキャストすることによって検出されます。

こちらも参照ください

CDateTimeCtrl の使用
コントロール