日付と時刻指定したフィールドを定義する標準書式文字に加え、コールバック フィールドとしてカスタム書式指定文字列の特定の部分を指定して出力をカスタマイズできます。コールバック フィールドを宣言するには、書式指定文字列の本体に一つ以上を 「X」文字 (ASCII 88)コードのどこからでも含めます。たとえば、次の文字列 「今日は次のとおりです: " yy'/" の MM'/" dd により日 (x) " 「日付を発生させ、月に続く年として現在の値を表示する日時指定コントロールは、最終的に年日の日付を入力します。
[!メモ]
コールバック フィールドの X's の数は、表示される文字の数に対応しません。
カスタム文字列に複数のコールバックのフィールド間で 「X」の文字を繰り返すことによって区別できます。したがって、書式指定文字列 「XXddddMMMdd は、 "」 yyyXXX 2 個の一意のコールバック フィールドを、 「xx」と 「XXX」含まれています。
[!メモ]
コールバック フィールドは、有効なフィールドとして扱われるため、アプリケーションは DTN_WMKEYDOWN の通知メッセージを処理する必要があります。
日付と日時指定コントロールのコールバック フィールドを実行すると、 3 人の部分から構成されます:
カスタム書式指定文字列の初期化
DTN_FORMATQUERY の通知の処理
DTN_FORMAT の通知の処理
カスタム書式指定文字列の初期化
CDateTimeCtrl::SetFormatに呼び出しを持つカスタム文字列を初期化します。詳細については、 日時指定コントロールのカスタム書式指定文字列を使用するを参照してください。カスタム書式指定文字列を設定する共通の場所を含むビュー クラスの OnInitialUpdate の含むダイアログ クラスの OnInitDialog 関数に含まれています。
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 の構造体へのポインターは、適切な型へ通知ハンドラーの最初のパラメーターをキャストしてもあります。