Version 9.12
ツールバーを操作する!
「前回は実際にツールバーを使ってみました」
『って言ってもメニューなんかとほとんど同じだけどねー』
「というわけで、今回はプログラム側から操作してみます」
『やっぱそう来るわけね……』
「嫌そうだね」
『べつにー。で、どうするの?』
「えーっと、 Version 9.09 ( No.170 ) を軽く読み返してもらうと分かる
けど、ツールバーを作ったりするときには m_wndToolBar ってメンバ変数を
使います」
『ってことは、操作もこの変数使ってするんだ』
「そう、というわけでいつものテスト用メンバ関数に、次のようなコードを
書き込んでください」
void CMainFrame::OnMenuTest()
{
// ツールバーコントロールを取得します。
CToolBarCtrl &rcToorBarCtrl
= m_wndToolBar.GetToolBarCtrl();
// ボタンが淡色かどうかチェック。
BOOL bIsEnabled
= rcToorBarCtrl.IsButtonEnabled( ID_FILE_NEW );
if( bIsEnabled == FALSE )
{
TRACE( "無効状態です\n" );
}
else
{
TRACE( "有効状態です\n" );
}
}
『お、ちょっと長い』
「でも後半は」
『あー、ただ if でメッセージ分けてるだけね』
「そう、重要なのは前半」
// ツールバーコントロールを取得します。
CToolBarCtrl &rcToorBarCtrl
= m_wndToolBar.GetToolBarCtrl();
「えーっと、参照って憶えてる?」
『 Version 4.14 ( No.064 ) でやったね、ポインタみたいのだよね』
「そうそう、ポインタみたいに他の変数の代わりになる変数なんだけど、ア
ドレスを使ったり -> を使ったりする必要がないっていうの」
『この rcToorBarCtrl は参照なんだね、 & 付けて変数作ってるから』
「そう。これは CToolBar::GetToolBarCtrl() が参照を返すから」
『?? 参照とかより、そっちの方がわかんない』
「うん、その辺説明するね。 Version 9.09 ( No.170 ) で見たように、
ツールバーは外側の MFC が作ったツールバーの中に、ウィンドウズの本物
のツールバーが入ってる形になってます」
『ウィンドウクラスが違ったんだよね』
「 m_wndToolBar メンバ変数のクラス CToolBar は、 MFC の外側を管理す
るためのクラス」
『これが外側のツールバーを作ってるわけね』
「そゆこと。ってことは、中の本当のツールバーはまた別って事。本当の
ツールバーを操作するのは CToolBarCtrl ってクラス」
『あ、さっき参照作ったクラス!』
「そうそれ。この CToolBarCtrl クラスのメンバ変数が CToolBar の中に隠
れてて、 CToolBar は本当のツールバーを操作するときにそのメンバ変数を
使ってツールバーを操作するんです」
『なんかヤな感じ……』
「なんで?」
『だって、ドレイっぽくない?』
「うーん……」
『まーいーや。で?』
「あ、で、本当のツールバーを操作する場合、 CToolBar では操作できない
んです」
『なんで? CToolBar から CToolBarCtrl 操作してもらえばいいんじゃな
いの?』
「そういう機能が CToolBar にはないんです」
『やっぱヤな感じ』
「で、代わりに CToolBarCtrl メンバ変数を外から操作できるようにして、
それを使って直接本当のツールバーを操作してください、っていう仕組みに
なってるわけ」
『あ! そっか、それがさっきの参照なんだ』
「そゆこと。あの参照は、 CToolBar の中の CToolBarCtrl メンバ変数への
参照。だからあれを使えば」
『本当のツールバーを操作できる!』
「ってわけ。で、実際に操作してる部分が」
BOOL bIsEnabled
= rcToorBarCtrl.IsButtonEnabled( ID_FILE_NEW );
「 CToolBarCtrl::IsButtonEnabled() は、ボタンが有効だったら 0 以外、
無効だったら 0 を返す関数」
『 ID_FILE_NEW は【ファイルを新規作成】ボタンね。これって普通は使え
るよね』
「そう、だから」
『ビルドして実行! お、〈有効状態です〉って出た!』
「ってわけ。同じように」
void CMainFrame::OnMenuTest()
{
// ツールバーコントロールを取得します。
CToolBarCtrl &rcToorBarCtrl
= m_wndToolBar.GetToolBarCtrl();
// ボタンが淡色かどうかチェック。
BOOL bIsEnabled
= rcToorBarCtrl.IsButtonEnabled( ID_EDIT_CUT );
if( bIsEnabled == FALSE )
{
TRACE( "無効状態です\n" );
}
else
{
TRACE( "有効状態です\n" );
}
}
「 ID_FILE_NEW が ID_EDIT_CUT になっただけだから」
『 ID_EDIT_CUT は〈切り取り〉……あ、これって最初は淡色表示なんだ
ね』
「そう、だから」
『ビルドして実行! お、今度は〈無効状態です〉って出た』
「こんなふうに、ボタンが有効か無効かを取得できるってわけ」
『質問!』
「はい火美ちゃん」
『なんで FALSE と比べてるんだっけ。 TRUE と比べちゃいけないって、憶
えてはいるんだけど……』
「 Version 5.10 ( No.075 ) で簡単に触れてるけど、 FALSE が 0 なのは
決まってるけど、 TRUE は 0 以外だからどんな値か分からないわけ」
『それだといけないの?』
「 CToolBarCtrl::IsButtonEnabled() のリファレンス見てみて」
『あ、〈ボタンが有効な場合は 0 以外を返します。〉ってある』
「つまり CToolBarCtrl::IsButtonEnabled() が返すのは 0 以外の、特に決
まってない数字」
『それが TRUE の決まってない数字と同じになるとは限らない、だから比べ
ちゃいけない!』
「そゆこと。ちなみに TRUE と FALSE は Version 6.05 ( No.105 ) で出て
きたマクロのひとつ」
『あ! だから全部大文字なんだ』
「 Visual C++ では WinDef.h で」
#define TRUE 1
『 1 は 1 なのね』
「でも、 TRUE が 0 以外ってのは決まりだから」
『 1 って決めつけて使っちゃいけない!』
「そゆこと。その辺は忘れずに」
『はーい。と、話を戻して』
「えーっと、そういうわけで、 CToolBarCtrl の参照を受け取って、そのメ
ンバ関数を使えば、本当のツールバーを直接操作できるってことだけど」
『でもさ、操作って感じじゃないよね』
「あ、そうだね。じゃあ今度は操作してみようか」
void CMainFrame::OnMenuTest()
{
// ツールバーコントロールを取得します。
CToolBarCtrl &rcToorBarCtrl
= m_wndToolBar.GetToolBarCtrl();
// ボタンを淡色化。
rcToorBarCtrl.Indeterminate( ID_FILE_NEW, TRUE );
}
『お、今度は CToolBarCtrl::Indeterminate() ってメンバ関数使ってる』
「これは、第2引数が 0 以外なら淡色にして、 0 なら普通の色にします」
『なんか、 TRUE と FALSE が逆っぽいような……』
「これは〈淡色表示にする〉メンバ関数、つまりネガティブな意味を持って
るから、他のポジティブな意味のメンバ関数と逆になっちゃうんだよね」
『分かりにくい……』
「この辺はウィンドウズの仕様だからねー」
『 MFC じゃないんだ』
「この CToolBarCtrl::Indeterminate() は、ツールバーのウィンドウに
TB_INDETERMINATE ってメッセージ送ってるんだよ」
『あ、そっか、これもコントロールだからメッセージで操作するんだ』
「そゆこと。 CToolBarCtrl のメンバ関数のほとんどは、頭に TB_ が付い
てるツールバー用メッセージを送るだけのもの」
『だから、わけわかんなくてもそれは MFC のせいじゃないってことね』
「そういうこと。ま、そういうわけで、 TRUE を渡せば淡色表示にします」
『 ID_FILE_NEW をするのね。ビルドして実行! お、左端の白いボタンが
無効になった!』
「ってわけ」
『……あれ?』
「どしたの火美ちゃん」
『このボタン、押せるよ?』
「うん、淡色表示にしただけだから」
『なにそれ。なんかサギっぽい!』
「このメンバ関数は淡色表示にするだけで、無効化とかとは関係ないから
ね。無効化はこうするんだけど……」
void CMainFrame::OnMenuTest()
{
// ツールバーコントロールを取得します。
CToolBarCtrl &rcToorBarCtrl
= m_wndToolBar.GetToolBarCtrl();
// ボタンを有効化。
rcToorBarCtrl.EnableButton( ID_EDIT_CUT, TRUE );
}
『うんうん、これなら分かりやすいね。さっきの IsButtonEnabled() と対
になってる感じだし』
「なんだけど……」
『なに、その煮え切らない言い方は』
「とりあえず試してみて」
『ほい。 ID は ID_EDIT_CUT だから切り取りボタンが……あれ? なーん
か、一瞬色が変わってるっぽいんだけど、またすぐ淡色になっちゃう!』
「これは Version 9.06 ( No.167 ) に出てきた」
void CMainFrame::OnUpdateMenuTest(CCmdUI* pCmdUI)
{
}
『あ、有効か無効か変えるメンバ関数!』
「そう、こっちの方が強いから、有効化や無効化ができないんです」
『そういう優先順位ってあるんだ……』
「ま、 MFC の場合は有効化・無効化用の機能がちゃんとあるんだから」
『そっち使えってことね』
「そういうこと……」
/*
Preview Next Story!
*/
『なんかありがためいわくって気もするね』
「まーね、 MFC ってそいうとこあるから」
『ありがたいのと迷惑なのと、どっちが多い?』
「……それは難しいねたとえばステータスバー」
『ステータスバー?』
「これはツールバーと似た仕組みになってるから」
『解りやすいってこと?』
「というわけで次回」
< Version 9.13 ステータスバーを使ってみる! >
『につづく!』
「まぁ、本音を言えば……」
『本音を言えば?』
「………………………………………………………………………………」
『言ってないし!』