[VisualStudio] ToolBarにドロップダウンボタンを表示する

自分が嵌ったのでメモ代わりに。MFC限定だし別にTipsでもないが、もしかしたら誰かの助けになるかも。ソース内のm_wndToolBarはCToolBarで、アプリケーションウィザードがどこかで作成しているものです。

アプリケーションウィザードが吐いたCMainFrame::OnCreate()の中に以下のコードを挿入すれば、ツールバーにメニューを入れたりできる。ちょうど、

    // TODO: ツール バーをドッキング可能にしない場合は以下の3行を削除
    //       してください。

の下あたりに挿入すればよい。


001 m_wndToolBar.ModifyStyle(0,TBSTYLE_LIST); // ボタンの横にテキストを入れる
002 m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS // ドロップダウンボタンを使用する
003 | TBSTYLE_EX_MIXEDBUTTONS // テキストありとなしの混在を許す
004 );
005
006 // 文字列の設定
007 m_wndToolBar.SetButtonText(0, "Sepあり▼");
008 m_wndToolBar.SetButtonText(1, "Sepなし▼");
009 m_wndToolBar.SetButtonText(2, "貼り付け");
010 m_wndToolBar.SetButtonText(3, "印刷");
011
012 CToolBarCtrl *pToolBarCtrl = &m_wndToolBar.GetToolBarCtrl();
013
014 TBBUTTONINFO tbi;
015 tbi.dwMask = TBIF_STYLE;
016 tbi.cbSize = sizeof(TBBUTTONINFO);
017
018 // はさみボタンの設定
019 pToolBarCtrl->GetButtonInfo(ID_EDIT_CUT, &tbi);
020 tbi.fsStyle |= (TBSTYLE_DROPDOWN // ドロップダウンボタンを表示
021 | BTNS_SHOWTEXT // テキストを表示
022 );
023 pToolBarCtrl->SetButtonInfo(ID_EDIT_CUT, &tbi);
024
025 // コピーボタンの設定
026 pToolBarCtrl->GetButtonInfo(ID_EDIT_COPY, &tbi);
027 tbi.fsStyle |= (TBSTYLE_DROPDOWN // ドロップダウンボタンを表示
028 | BTNS_WHOLEDROPDOWN // ドロップダウンボタンはセパレートではない
029 | BTNS_SHOWTEXT // テキストを表示
030 );
031 pToolBarCtrl->SetButtonInfo(ID_EDIT_COPY, &tbi);
032
033 // 貼り付けボタンの設定
034 pToolBarCtrl->GetButtonInfo(ID_EDIT_PASTE, &tbi);
035 tbi.fsStyle |= (BTNS_SHOWTEXT); // テキストを表示
036 pToolBarCtrl->SetButtonInfo(ID_EDIT_PASTE, &tbi);
037

ハンドルは、CMainFrame::OnNotify()で行う。


001 BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
002 {
003 CMenu menu;
004 menu.LoadMenu(IDR_MENU1);
005 RECT rc;
006 // TODO: この位置に固有の処理を追加するか、または基本クラスを呼び出してください
007 if (((LPNMHDR)lParam)->code == TBN_DROPDOWN)
008 {
009 CToolBarCtrl& rTBC = m_wndToolBar.GetToolBarCtrl();
010 rTBC.GetItemRect(rTBC.CommandToIndex(((LPNMTOOLBAR)lParam)->iItem), &rc);
011 ClientToScreen(&rc);
012 switch (((LPNMTOOLBAR)lParam)->iItem)
013 {
014 case ID_EDIT_CUT:
015 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, rc.left, rc.bottom, this);
016 menu.DestroyMenu();
017 // AfxMessageBox("ここでメニューを出す");
018 break;
019 case ID_EDIT_COPY:
020 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, rc.left, rc.bottom, this);
021 menu.DestroyMenu();
022 break;
023
024 default:
025 break;
026 }
027 return TRUE;
028 }
029
030 return CFrameWnd::OnNotify(wParam, lParam, pResult);
031 }
032