日付と時刻の選択フィールドを定義する標準の書式指定文字に加えて、カスタム書式指定文字列の特定の部分をコールバック フィールドとして指定することで、出力をカスタマイズできます。 コールバック フィールドを宣言するには、書式指定文字列の本文の任意の場所に 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 構造体へのポインターは、通知ハンドラーの最初のパラメーターを適切な型にキャストすることによって検出されます。