Visual C++ 2008 MFCです。
http://msdn.microsoft.com/ja-jp/library/bb983962.aspx
現在、上記の「エクスプローラのサンプル」にあるような、
押すとポップアップメニューが出てくるだけのツールバーボタンを
自分のアプリケーションに取り入れようとしています。
取り入れること自体はできているのですが、
その他のボタンと表示方法が統一できないものかと調べています。
このサンプルはちょっと古いスタイルのようなので、
VCのアプリケーションウィザードが出力する下記のルーチンを追加したところ、
ツールバー内のコマンドがコマンド名+説明文付きで表示されるようになりました。
InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
ところが、右端のポップアップのみのボタン(表示形式)だけは、
Viewsの1行のみが表示されています。
m_wndToolBar.ReplaceButton (ID_VIEW_VIEWS,
CMFCToolBarMenuButton ((UINT)-1, menuViews,
GetCmdMgr ()->GetCmdImage (ID_VIEW_VIEWS), _T(Views)));
CMainFrame::OnToolbarReset()内の上記の箇所のViewsを、
メニュー内のコマンドと同じように、
Views\nViewsなどと改行を挟んで2行書いてみましたが、
2行がそのまま改行付きで表示されてしまいました。
コマンドIDを-1にしたポップアップメニュー形式のボタンは
他のボタンと同じようなツールチップの表示にすることはできないものでしょうか?
ツールチップを設定するのには別の方法があります。
CMainFrameに以下の関数を追加して下さい。
virtual BOOL GetToolbarButtonToolTipText(CMFCToolBarButton* /*pButton*/,
CString& /*strTTText*/);
IDが-1にボタンに対して通知が来るかはテストしていませんが、
ひょっとしたらこれでいけるかもしれません。
試してみて下さい。
追加です。
メインでなくても
ツールバーにもありますね。
OnUserToolTip()
です。
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=JA-JP&k=k
(ONUSERTOOLTIP);k(DevLang-%22C%2B%2B%22);k(TargetOS-WINDOWS)&rd=true
> CMainFrameに以下の関数を追加して下さい。
> virtual BOOL GetToolbarButtonToolTipText(CMFCToolBarButton* /*pButton*/,
CString& /*strTTText*/);
えーとさん、情報ありがとうございます。
IDが-1のボタンも、この関数には来るようです。
ただ、IDが-1なボタンに対して、とりあえず無条件にstrTTTextの内容を
ああああ\nいいいいに置き換えてみましたが、
やはり通常の複数行文字列として表示されてしまいました。
えーとさんからいただいた情報を元に
CMFCToolBar::OnToolHitTest()を調べてみましたが、
CString strDescr;
CFrameWnd* pParent = GetParentFrame();
if (pParent->GetSafeHwnd() != NULL)
{
pParent->GetMessageString(pButton->m_nID, strDescr);
}
CTooltipManager::SetTooltipText(pTI, m_pToolTip, AFX_TOOLTIP_TYPE_TOOLBAR,
strTipText, strDescr);
という箇所を見る限り、IDを-1にしてしまったものはstrDescrが作成されず、
その結果、CTooltipManager::SetTooltipText()にはstrTipTextのみが渡され、
他のコマンドと同じような2段表示にはならないということかもしれません。
IDを-1にしないまま、それ自体のイベントが発生しないボタンやメニュー
(戻るボタンのようにボタンと▼との間で動作が分かれていない)にできれば
解決できるのかもしれませんが、その方法はご存じではありませんでしょうか。
なら、
ツールバーに対してOnToolHitTest()をオーバーライドし、
選択した位置からID=-1である目的のCMFCToolBarButtonが得られるので
その場合、デフォルトの処理を飛ばすのではなく
CTooltipManager::SetTooltipText()の処理を参考に
SendMessage()でツールチップメッセージを飛ばせば良いと思います。
忙しくて詳しく検証できませんが、やってみてください。
> IDを-1にしないまま、それ自体のイベントが発生しないボタンやメニュー
> (戻るボタンのようにボタンと▼との間で動作が分かれていない)にできれば
> 解決できるのかもしれませんが、その方法はご存じではありませんでしょうか。
昔MFCのソースを調べていた時、この内容のような処理が出来そうな感じでした。
ただどこかと言われると...
私のところはVC++2005なので検証できないのですが、
コマンドIDを-1にするのがまずい気がします。
なぜなら、MFCのインクルードファイル内で、
#define IDC_STATIC (-1) // all static controls
の定義とバッティングするからです。
おそらく、MFC内でもIDC_STATICはいろんな意味で
特別扱いしているはずです。
今回の件が解決しても一難去ってまた一難の可能性が高いです。
> CTooltipManager::SetTooltipText()の処理を参考に
> SendMessage()でツールチップメッセージを飛ばせば良いと思います。
ありがとうございます。
こちらの方法も調べてみます。
>> IDを-1にしないまま、それ自体のイベントが発生しないボタンやメニュー
>> (戻るボタンのようにボタンと▼との間で動作が分かれていない)にできれば
>> 解決できるのかもしれませんが、その方法はご存じではありませんでしょうか。
> 昔MFCのソースを調べていた時、この内容のような処理が出来そうな感じでした。
個人的にはこちらのほうが、他のボタンにも載せたい機能ではあるので、
まずこちらのほうが可能かどうか調べてみたいと思います。
(これができれば、ツールバーのボタン自体をコマンドUIで無効にできますよね)
> 私のところはVC++2005なので検証できないのですが、
> コマンドIDを-1にするのがまずい気がします。
この方法は、VC2008のMFC Feature Packに含まれるツールバーでは
標準的な技法になっていて、サンプルでもこのようになっています。
CMFCToolBar::ReplaceButton()でコマンドIDを-1に置き換えると、
ポップアップメニューに相当するボタン(▼が付いたもの)になります。
ここでコマンドIDを残すと、ボタン部分と▼部分が分かれた、
エクスプローラの「戻る」(←|▼)などのような「|」入りのボタンになってしまい、
「←」部分をクリックするとそれ自体のコマンドが実行されてしまうのです。
なるほど、背景は分かりました。
>CMFCToolBar::ReplaceButton()でコマンドIDを-1に置き換えると、
>ポップアップメニューに相当するボタン(▼が付いたもの)になります。
>ここでコマンドIDを残すと、ボタン部分と▼部分が分かれた、
>エクスプローラの「戻る」(←|▼)などのような「|」入りのボタンになってしまい、
>「←」部分をクリックするとそれ自体のコマンドが実行されてしまうのです。
というわけで、私では分からなそうです^^;