#pragma twice

KAB-studio > プログラミング > #pragma twice > 170 Version 9.09 ツールバーを使ってみよう!

#pragma twice 170 Version 9.09 ツールバーを使ってみよう!

前のページへ 表紙・目次へ 次のページへ

 Version 9.09
ツールバーを使ってみよう!

「今回はツールバーについて見てみます」
『おー』
「ツールバーはメニューの下にある横棒。だけど……えっと、 
Version 9.01 ( No.162 ) の時みたいに Spy++ を起動して、ツールバーに
照準合わせてみて」
『ほいほい。2重なんだよね』
「そう、そこがポイント。【ウィンドウクラス】って憶えてる?」
『 Version 5.23 ( No.088 ) でやったね』
「このウィンドウクラス名を見ると、ウィンドウの素性がだいたい判るんで
す」
『え、そうなの?』
「たとえば、ダイアログコントロールなんかはウィンドウズが提供してくれ
るものだから、あらかじめ全部ウィンドウクラス名が決まってます」
『ボタンが BUTTON とか?』
「そうそう、それ。 MSDN の CreateWindow() のページに書いてあるから一
通り見てみて」
『たいがいのコントロールはちゃんとあるんだね』
「もし他のアプリで〈あれ、このコントロール、動きが変〉とか思ってウィ
ンドウクラス名を調べてみたら標準のコントロールじゃなかった、っていう
ことは結構多いよ」
『そういう意味で素性が判るってわけね』
「そゆこと。というわけで、コントロールバーに照準を合わせて、
【ウィンドウ検索】ダイアログの【クラス】の所を見てみて」
『えっと、外側のが AfxControlBar42d で、内側のが ToolbarWindow32 だ
ね』
「まず、本当のツールバーは内側の ToolbarWindow32 の方」
『本当?』
「つまりこれが、ウィンドウズが用意してくれてるツールバー」
『あー、ツールバーもウィンドウズが用意してくれてるんだ』
「で、外側の AfxControlBar42d は、 MFC が作ったウィンドウ」
『これはウィンドウズのじゃないんだねー』
「そう。だから、 MFC が作ったウィンドウの上に、ウィンドウズのツール
バーが乗ってるって感じかな」
『フレームウィンドウの上にビューウィンドウが乗ってるみたい』
「それに近いかも。ちなみに Afx っていうのは MFC の印だと思って」
『あ! そういえば Afx ってよく出てきたねー』
「 MFC のマクロや関数の頭に付いてるからね。こういうとこを見れば素性
が判るってこと」
『でもそれを知らないと判らないじゃん』
「だから今憶えて」
『んー』
「さて、今ので判ったように、ツールバー自体はウィンドウズが提供してく
れてるものです」
『例によって、 MFC でも使えるし、 API だけでも使えるって事ね』
「そゆこと。ま、その辺を踏まえつつ、実際に使ってみます」
『ってゆーか、最初から表示されてるよね』
「うん。これは CMainFrame::OnCreate() の中で」

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// 略。
    // 注:横幅を短くするために改行しています。
    if  ( !m_wndToolBar.CreateEx
            ( this
            , TBSTYLE_FLAT
            , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER
                | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC
            ) 
            ||
            !m_wndToolBar.LoadToolBar( IDR_MAINFRAME )
        )
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // 作成に失敗
    }

// 略
}

「ってしてるでしょ。ここでツールバーを作ってます」
『確かに CreateEx() ってなんか作ってる感じ……だけどちょっと複雑ね』
「これは悪いプログラムの書き方かも。まず if を取ると」

         !m_wndToolBar.CreateEx
            ( this
            , TBSTYLE_FLAT
            , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER
                | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC
            ) 
            ||
            !m_wndToolBar.LoadToolBar( IDR_MAINFRAME )

『んーと、小カッコがこうだから……』

         !m_wndToolBar.CreateEx
            ( this
            , TBSTYLE_FLAT
            , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER
                | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC
            ) 

『と』

            !m_wndToolBar.LoadToolBar( IDR_MAINFRAME )

『に分かれてるんだよね』
「そう、それを || で継ないでるだけ」
『 || って、どっちかが 0 以外なら 0 以外になるんだよね』
「そうそう。 Version 6.10 ( No.110 ) を参照ってことで、でもここでは 
! が付いてるから」
『な、なんか複雑……』
「まず最初の m_wndToolBar.CreateEx() を呼んでるところから」
『 m_ ってことはメンバ変数なんだね』
「そう、 m_wndToolBar は CMainFrame のメンバ変数。 MainFrame.h の方
を見れば分かるからあとで見ておいて」
『はーい』
「この m_wndToolBar は CToolBar 型」
『まさにツールバーって感じね』
「で、 CToolBar::CreateEx() でツールバーを作ります。それが最初の部
分」
『 this って……なんだっけ、自分自身のポインタとかなんとかなんだよ
ね』
「やっぱ this って難しいかもね……今呼ばれてる 
CMainFrame::OnCreate() ってメンバ関数も、どこかで 
m_wndToolBar.CreateEx() みたいな感じに呼ばれてるはず」
『はずよね』
「その m_wndToolBar にあたる変数があるわけでしょ。そのポインタ」
『……まだよく分かんない』
「だね……これは後でちゃーんと説明するから、それまでは。あ!」
『な、なに?』
「んー、ちょっと間違った説明の仕方かもしれないけど、 
CToolBar::CreateEx() の第1引数にはツールバーを置くウィンドウのポイ
ンタを渡す必要があるんです」
『ツールバーを置くウィンドウ、つまりフレームウィンドウ……あー、って
ことは CMainFrame のポインタを渡すわけだから』
「だから this 」
『だまされてる気がする……』
「うん、ちょっと間違ってる部分もあるし、今のところはそのくらいって事
で」
『えっと、2番目の引数は、なんかのフラグみたいだけど』
「これはツールバーのスタイルを決めるフラグ」
『あれ? でも3番目の引数もそんな感じっぽいけど』
「うん、こっちもスタイル。ものすごく分かりにくいんだけど……第2引数
のは本当のツールバーにだけ渡したいスタイル、第3引数はツールバー全体
にも渡したいスタイル、ってところかな」
『……なんかよくわかんないね』
「僕も分からない」
『何それ』
「一応関数の中を見ればそうらしいっていうのは分かるんだけどね。 MSDN 
の方には詳しく書かれてないし。ま、この辺はパスってことで」
『テキトーねー』
「で、次に」

            !m_wndToolBar.LoadToolBar( IDR_MAINFRAME )

「を呼んでます。この CToolBar::LoadToolBar() を呼ぶと、ツールバーを
実際に作ります」
『へ? さっき作ったんじゃないの?』
「さっきはウィンドウとしてのツールバーだけ。ここでは、リソースの 
IDR_MAINFRAME からツールバーのボタンひとつひとつを読み込んで追加して
いるんです」
『あら、面倒そう』
「確かに。で、このふたつでツールバーは完成。めでたく表示されるという
わけです」
『あ、ちょっと試していい?』
「どうぞ」
『この部分をコメントアウトすると……げ! エラーになっちゃった』
「 ASSERT() しちゃったね。これは、下の方に」

    // TODO: ツール バーをドッキング可能にしない場合は以下の3行を
    //       削除してください。
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

「ってあるでしょ、こっちもコメントアウトしないとダメだから」
『あ、こっちもしたら大丈夫だね。うん、ツールバーないし』
「この部分でツールバーを実際にウィンドウにくっつけてるんです。で、
その時にツールバーが作られてないと」
『くっつけるものがないんだ』
「そゆこと。あ、ちなみに ASSERT() って憶えてる?」
『 Version 6.17 ( No.117 ) でやったね。あっちゃいけないのを網に掛け
るってゆーの。そっか! ここだと、ツールバーが作られてないのにウィン
ドウにくっつけようとしたから!』
「そゆこと。つまりこの ASSERT() は〈まずツールバーを作って、そのあと
ウィンドウにくっつける〉っていう手順を守らせるためのものってこと」
『……でも今の ASSERT() だけでそれってわかるもん?』
「うーん、ちょっと難しいかもね……」
『あ、あとひとつ質問! さっきの if の ! とか || とかっていまいち分
かんないんだけど』
「そうだねそれはちゃんとやっておこうか。さっきのをはしょって書くと」

    if  ( 
            !m_wndToolBar.CreateEx() 
            ||
            !m_wndToolBar.LoadToolBar()
        )

『だいぶはしょったね……』
「で、この if の中をひとつひとつ見ていきます。 CToolBar::CreateEx() 
は、作れたら 0 以外、作れなかったら 0 を返します」
『それが ! で逆になるんだから、 作れたら 0 、作れなかったら 0 以外
ね』
「で、次の CToolBar::LoadToolBar() も、うまくいったら 0 以外、ダメ
だったら 0 」
『これも逆になるから、うまくいったら 0 、ダメだったら 0 以外ね』
「 || は〈どっちかが 0 以外なら 0 以外、両方とも 0 の時だけ 0 〉だか
ら」
『えっと……あ、両方うまくいった時だけ 0 になるんだね』
「言い換えるとどっちかがダメだったら 0 以外。で、 if の中に入って 
return しちゃうから、ダイアログは作られません」
『ほー。つまりツールバーがちゃんと作られてるかどうか調べてるのね』
「でも実は CToolBar::CreateEx() がエラーだと CToolBar::LoadToolBar() 
は呼ばれないんだけどね」
『え? なんで??』
「というわけで次回に続く!」

/*
    Preview Next Story!
*/
『なんかここ最近、いろんな話が出てくるね』
「そうだね、文法的なこととかウィンドウズのこととか」
『まとめて教えた方がいくない?』
「火美ちゃんは API かたっぱしから教わりたい?」
『それなんかヤダ』
「というわけで次回」
< Version 9.10 ショートサーキット >
『につづく!』
「飽きないためにもいろんなことを少しずつ、ってことで」
『にしても話が飛びすぎのよーな……』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。