#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のトップページをご覧ください。