【Visual C++ 2008】【MFC】
「ダイアログにビットマップ付きボタンを実装する(4bitカラー編)」「ダイアログにビットマップ付きボタンを実装する(24bitカラー編)」のボタンに、ツールヒントを表示する方法。
(1)
リソースビューにて、Toolbarの該当する(ツールヒントを表示したい)ボタンを選択して、[プロパティ]-[その他]-[Prompt]に表示する文字列を入力する。
その際、頭に必ず「\n」を付加すること。
(例)
\nファイルを開く
もしくは、rcファイルを直接書き換えるなら、以下を追加する。
(例)
IDBUTTON1,IDBUTTON2,IDBUTTON3にそれぞれ「ファイルを開く」「すべてを保存」「終了」のツールヒントを表示する場合。
STRINGTABLE
BEGIN
IDBUTTON1 "\nファイルを開く"
IDBUTTON2 "\nすべてを保存"
IDBUTTON3 "\n終了"
END
IDはボタンのIDと一致させる。
(2)
OnInitDialogの「// TODO: 初期化をここに追加します。」より後にて、一連のツールバー読み込み処理の最後に以下を記述。
(ツールバークラス(CToolBar)のメンバ変数がm_wndToolBarの場合)
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS);
(3)
ダイアログのクラスヘッダのprotectedに、メンバ関数定義を追加。
afx_msg BOOL OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult);
(4)
メッセージマップに、以下を追加。
これで、TTN_NEEDTEXTWメッセージがダイアログに飛ぶと、OnToolTipText関数を呼び出す。
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
(5)
メンバ関数を記述。
これは、Visual C++付属サンプルに入っている「DLGCBR32」のMdlsmain.cppより引用したものである。
オリジナルの関数は、メッセージがTTN_NEEDTEXTA,TTN_NEEDTEXTW、
[構成プロパティ]-[全般]-[プロジェクトの既定値]-[文字セット]が「Unicode文字セットを使用する」「マルチバイト文字セットを使用する」
の順列組み合わせ4パターンに対応している。
以下に示した関数は、TTN_NEEDTEXTWと「Unicode文字セットを使用する」の組み合わせのみを取り出した。
(コメントもそのままなので、差分を取って確認してください)
BOOL CXxxxDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult)
{
// allow top level routing frame to handle the message
if (GetRoutingFrame() != NULL)
return FALSE;
// need to handle both ANSI and UNICODE versions of the message
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
wchar_t szFullText[256];
CString strTipText;
UINT_PTR nID = (UINT_PTR)pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
// idFrom is actually the HWND of the tool
nID = ((UINT_PTR)(WORD)::GetDlgCtrlID((HWND)nID));
}
if (nID != 0) // will be zero on a separator
{
AfxLoadString((UINT)nID, szFullText);
// this is the command id, not the button index
AfxExtractSubString(strTipText, szFullText, 1, '\n');
}
wcsncpy_s(pTTTW->szText, (sizeof(pTTTW->szText)/sizeof(pTTTW->szText[0])),
strTipText, _TRUNCATE);
*pResult = 0;
// bring the tooltip window above other popup windows
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE);
return TRUE; // message was handled
}
7/Vista/XP/2000で動作確認したところ、メッセージマップでTTN_NEEDTEXTAのみ記述した場合は、TTN_NEEDTEXTAが飛んでくる。 TTN_NEEDTEXTWのみ(あるいは両方)記述した場合は、TTN_NEEDTEXTWが飛んでくる。 これは、Unicode文字セット/マルチバイト文字セットのどちらでコンパイルしても同様である。 どの組み合わせでも正常動作するが、TTN_NEEDTEXTA,TTN_NEEDTEXTWのメッセージの違いが何に依存しているのかは不明である。
(メモ)
- サンプルの場所は、C:\Program Files\Microsoft Visual Studio 9.0\Samples\1041\AllVCLanguageSamples.zip
- MSDNライブラリの「CControlBar::SetBarStyle」「CControlBar::GetBarStyle」を参照のこと