#pragma twice

KAB-studio > プログラミング > #pragma twice > 153 Version 8.11 ツリービューコントロールを作ろう!

#pragma twice 153 Version 8.11 ツリービューコントロールを作ろう!

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

 Version 8.11
ツリービューコントロールを作ろう!

前回の最後に

WM_ : 普通のメッセージ。ウィンドウプロシージャで受ける
*M_ : コントロールに送って操作する。 EM_ とか
*N_ : 通知メッセージ。コントロールから WM_COMMAND と一緒に来る

って説明しました
で、なんか最後のが違うって言ってたよね
言いました。これは、通知メッセージは WM_COMMAND と一緒に送られてく
るものだけじゃなくて、 WM_NOTIFY ってメッセージと一緒に送られてくる
ものもあるから
 WM_NOTIFY の notify って〈通知〉って意味だよね。こっちの方がむし
ろ通知メッセージっぽいね
この WM_COMMAND が送られてくるか WM_NOTIFY が送られてくるかってい
うのは、コントロールの種類によって決まります
エディットボックスは WM_COMMAND だったね
そう、ほとんどのコントロールは WM_COMMAND で送られてきます。 
WM_NOTIFY が送られてくるのはツリービューコントロールやリストビューコ
ントロールとかの、比較的新しいコントロールだけ
新しい?
まー、ウィンドウズ95からって意味での新しいってこと
ウィンドウズ3.1の頃はなかった?
たぶん……で!
で?
その WM_NOTIFY を使うためにはツリービューコントロールとかを使わな
きゃいけない
つまりこれからツリービューコントロールを作るわけね
そうなるんだけど……普通にそれをやると大変だから、まず MFC で使っ
てみることにします
 MFC ? 今のプロジェクトで MFC 使えるの?
使えないから、新しくプロジェクト作ります

というわけで、今の SimpleDialog を閉じて、新しく MFC プロジェクト
を作って
ほいほい。【MFC AppWizard (exe)】で普通にダイアログのを作ればいい
んだよね
そうそう。プロジェクト名は MfcDialog にでもしといて
ほいほい
作ったら、そこにツリービューコントロールを貼り付けて
ツリービューコントロールって、横向きの手の指みたいなのだよね
手の指……そうそれ
貼り付けたよ
次にそのツリービューコントロールの ID を IDC_TREE_MAIN に
ほい
さらに、プロパティの【スタイル】ページで【ボタンあり】と
【線を表示】と【最上位にも線を表示】をオンにして
これがないと、エクスプローラーとかみたくなんないんだね
そうなんだよね、最初からそういうスタイルになってないから、これをし
ないとツリービューコントロールっぽくならないから忘れずに。じゃ、とり
あえずビルドして実行してみて
ほい。んー、でもツリービューコントロールに何も表示されないね
そう、そこは自分で追加しなきゃいけないんです。プログラム書いてね
あらま、それは面倒
うん、結構面倒かも
げ……
まず、クラスウィザードを表示して
あ、操作するのにメンバ変数作るんだね
その通り。 Version 5.31 ( No.096 ) とかでやったね
同じようにすればいいんだよね
そう。【メンバ変数】ページで IDC_TREE_MAIN を選択して
【変数の追加】を押して
ほい。あれ、【カテゴリ】が最初から〈コントロール〉になってる
ツリービューコントロールとかは複雑だから、普通の変数に置き換えられ
ないんです
だから変数版のメンバ変数は作れないわけね。メンバ変数は m_cMainTree 
でいい?
うんそれで。このメンバ変数を使って、ツリービューコントロールに項目
を追加してみます。追加するのはおなじみの OnInitDialog() に

BOOL CMfcDialogDlg::OnInitDialog()
{
// 略。 
    // TODO: 特別な初期化を行う時はこの場所に追加してください。
    m_cMainTree.InsertItem( "1番目のアイテム" );// この1行を追加。

    return TRUE;
}

ん、追加するのって1行だけでいいの?
とりあえず
じゃーとりあえずビルドして実行。おお、ツリービューコントロールに
〈1番目のアイテム〉が追加された!
この CTreeCtrl::InsertItem() で項目……アイテムっていうのもあれだ
から【アイテム】って呼ぶね
ほいアイテム。ゲームなんかのアイテムと同じ?
そう同じ。このアイテムの追加を CTreeCtrl::InsertItem() でします
んーと、これを

    m_cMainTree.InsertItem( "1番目のアイテム" );
    m_cMainTree.InsertItem( "2番目のアイテム" );

ってやると……あー、どんどん増えてくけど、ツリーになんないね。1番
目のアイテムの……子アイテムってどうやって入れるの?
それには CTreeCtrl::InsertItem() の隠された引数を使います
隠された引数?
 CTreeCtrl::InsertItem() のリファレンスを見てみて
ほい。あれれ? メンバ関数がいっぱいある
関数は引数が違うものをいっぱい作れるから。これを【オーバーロード】
って言います
オーバーロードって前にやったね
 Version 7.09 ( No.129 ) でやった【演算子のオーバーロード】と同
じ。あれは演算子だったけど、こっちは普通の関数
???
んー、演算子のオーバーロードの方は難しいかも……うん、〈同じ〉発言
は撤回
なんですと?
とりあえずは、普通のオーバーロードと、演算子のオーバーロードは別に
憶えた方がいいかも
別に?

普通のオーバーロード:同じ名前の関数を、引数の変えて色々作ること
演算子のオーバーロード:クラスに演算子を使えるように関数を作ること

って憶えた方が今は楽かもね
うん、この方が分かりやすい……けど、ホントは同じなの?
そう、 C++ では演算子も関数の一種、って見方が強いからね
演算子も関数の一種、ねぇ……
というわけで話を戻して
 CTreeCtrl::InsertItem() にはオーバーロードしてて、関数が4つある
ね。あれ? でもさ、今呼んでる、引数ひとつのってないよ?
そこでもうひとつ使うのが、引数の省略。 Version 5.13 ( No.078 ) で
教えたように
そっか、引数に = で値入れとくと、それは省略できるんだ。それだと、
省略して引数ひとつだけにできるのは

HTREEITEM InsertItem
    ( LPCTSTR lpszItem
    , HTREEITEM hParent = TVI_ROOT
    , HTREEITEM hInsertAfter = TVI_LAST 
    );

だけだからこれだね
そう、このメンバ関数が呼ばれてます
質問! これってどうやって選ぶの? 似たような引数のがあったら?
これ、自分で〈どのメンバ関数を選ぶ〉っていうのは決められません。関
数に渡した引数の型と数を見て自動的に決められます
決められなかったら? 引数が似てたりして、たとえば

void Test( int p_i );
void Test( int p_i, int p_i2 = 0 );

で、引数ひとつしか渡さないとか
そしたらコンパイルエラーになります。逆に言うと、オーバーロードした
り引数の省略をしたりするときは、似たような引数にならないように作らな
きゃいけないってこと
あー、ってことはあたしの例だと、 Test() って関数を作るときに注意し
なきゃいけないのね
そゆこと。作っても呼べないからどっちか削ることになるし、この例な


void Test( int p_i );

はいらないでしょ
そっか、引数省略したらこれと同じになるから
もしくは引数の省略をやめるか
それって

void Test( int p_i );
void Test( int p_i, int p_i2 );

ってことね。でもさっきの方が、関数ひとつだけでいいからいいんじゃな
い?
その辺は議論の的だったり……場合によって使い分けが必要だから
場合?
たとえば、引数を省略したときとしないときとで、呼ばれる関数を変えた
いときとか
そっか、引数省略の方だと、関数ひとつだから困るってこともあるんだ
その辺は、火美ちゃんがオーバーロード関数を作る時になったらの話だ

おお
さて話を戻して、さっきの CTreeCtrl::InsertItem() 、省略してた第2
引数に〈これから追加するアイテムの親〉を渡すと、その親の子アイテムと
して追加することができます

BOOL CMfcDialogDlg::OnInitDialog()
{
// 略。 
    // TODO: 特別な初期化を行う時はこの場所に追加してください。
    HTREEITEM hParentItem
        = m_cMainTree.InsertItem( "1番目のアイテム" );
    m_cMainTree.InsertItem( "2番目のアイテム", hParentItem );

    return TRUE;
}

 HTREEITEM ってので、さっきのメンバ関数の戻り値受け取ってるね
これは頭に H が付いてるとおり
ハンドル!
なんです。ツリービューコントロールのアイテムを操作するためのハンド
ルで
これを第2引数に渡すと、これが親になるから〈2番目のアイテム〉が
〈1番目のアイテム〉の子アイテムになるわけねー
ちなみに第2引数を省略すると TVI_ROOT っていうのが渡されます
これを渡すと追加したアイテムが親になるわけね
ちなみに【ルート】は【根っこ】って意味
木の根っこだから親ってわけねー

/*
    Preview Next Story!
*/
アイテムの追加とか、簡単だね
 MFC だからねー
またかい! だったら MFC だけでいーじゃん
それだとできることが限られちゃうからね
できることねー
火美ちゃんはどんなアプリ作りたいの?
へ? あたし、そーゆーのないよ
ないって……
というわけで次回
< Version 8.12 ツリーアイテム >
につづく!
だって水希ちゃんが教えてくれるから勉強してるだけでー
それでいいの?
いーの
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。