#pragma twice

KAB-studio > プログラミング > #pragma twice > 161 Version 8.19 MFC を使わずにアイテムを取得!

#pragma twice 161 Version 8.19 MFC を使わずにアイテムを取得!

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

 Version 8.19
MFC を使わずにアイテムを取得!

ではさっそく前回の続きを
あと関数が3つあったもんね
まずはその中の一番簡単なのから

// OK ボタンが押されました。
BOOL OnOk( HWND p_hDlgWnd )
{
    EndDialog( p_hDlgWnd, IDOK );
    return TRUE;
}

 OK ボタンを押したら閉じるってヤツね
今回は OK ボタンだけだど、本当はxボタンに対応するために IDCANCEL 
にも対応させた方がいいかな
 Version 8.09 ( No.151 ) のね
では次、ダイアログの初期化

// ダイアログの初期化。
BOOL OnInitDialog( HWND p_hDlgWnd )
{
    TVINSERTSTRUCT stInsertItem;
    stInsertItem.hParent = TVI_ROOT;
    stInsertItem.hInsertAfter = TVI_LAST;
    stInsertItem.item.mask = TVIF_TEXT;
    stInsertItem.item.pszText = "1番目のアイテム";
    
    HWND hMainTreeWnd
        = GetDlgItem( p_hDlgWnd, IDC_TREE_MAIN );
    HTREEITEM h1stItem
        = (HTREEITEM)SendMessage
            ( hMainTreeWnd
            , TVM_INSERTITEM
            , 0
            , (LPARAM)&stInsertItem
            );

    stInsertItem.item.pszText = "2番目のアイテム";
    SendMessage
        ( hMainTreeWnd
        , TVM_INSERTITEM
        , 0
        , (LPARAM)&stInsertItem
        );

    stInsertItem.hParent = h1stItem;
    stInsertItem.item.pszText = "1−1番目のアイテム";
    SendMessage
        ( hMainTreeWnd
        , TVM_INSERTITEM
        , 0
        , (LPARAM)&stInsertItem
        );


    return TRUE;
}

長い……けど、 Version 8.16 ( No.158 ) と同じね
あのときと同じことを3回してるってだけ
じゃ、最後のねー

// アイテムの選択が変更された時。
BOOL OnSelchangedTreeMain( NM_TREEVIEW *p_pstNmTreeView )
{
    char pchText[256];
    TVITEM stTvItem;
    stTvItem.mask = TVIF_TEXT;
    stTvItem.hItem = p_pstNmTreeView->itemNew.hItem;
    stTvItem.pszText = pchText;
    stTvItem.cchTextMax = 255;

    SendMessage
        ( p_pstNmTreeView->hdr.hwndFrom
        , TVM_GETITEM
        , 0
        , (LPARAM)&stTvItem
        );

    OutputDebugString( pchText );
    OutputDebugString( "\n" );

    return 0;
}

どっかで見たような、そうじゃないような……
これは Version 8.15 ( No.157 ) の〈今選択されているアイテムの情報
を取得する方法〉を MFC を使わずにしているんです
そういえばちょっと似てる……けど結構違うかな
そうだね、まずこの OnSelchangedTreeMain() って関数から
前回のを見ると、選択してるアイテムを変えるとこの関数が呼ばれるよう
になってるんだよね
そう、 TVN_SELCHANGED 通知メッセージが送られてきたらディスパッチす
るようにしてるからね
その時の LPARAM が NM_TREEVIEW にキャストされて渡されてるのね。こ
の辺は Version 8.15 と同じ?
同じ。あのときは LPARAM は出てこなかったけど、実際にはこういうふう
に LPARAM から NM_TREEVIEW のポインタにキャストできるから
つまり LPARAM から NMHDR のポインタにもキャストできるわけね
そゆこと。次の TVITEM の準備は Version 8.15 のと同じ。そのあとの

    SendMessage
        ( p_pstNmTreeView->hdr.hwndFrom
        , TVM_GETITEM
        , 0
        , (LPARAM)&stTvItem
        );

これがつまり

    m_cMainTree.GetItem( &stTvItem );

の代わりなわけね
そう、コントロールの操作はさっきの OnInitDialog() で 
TVM_INSERTITEM したようにメッセージを送ってします
で、アイテムの情報をもらうのが TVM_GETITEM なわけね
 TVM_INSERTITEM と使い方はほとんど同じだから大丈夫かな。こうやって
TVM_GETITEM メッセージを送ることで、 stTvItem の中に情報を入れてくれ
ます


        ( p_pstNmTreeView->hdr.hwndFrom

がちょっと難しいかも
じゃ、ひとつずつ分けて

    p_pstNmTreeView->hdr

これは NM_TREEVIEW の hdr 変数を指してます
ポインタだから -> なんだよね
そう。この hdr は NMHDR 構造体で、この中の hwndFrom 変数を指してい
るのが

    hdr.hwndFrom

の部分
 -> が . になるのよね……
そう、前も言ったけど、この時点ではもう p_pstNmTreeView のことは忘
れて hdr だけを見て。 hdr はポインタじゃなくて普通の変数だから
 -> じゃなくて . なわけね
そゆこと。この hwndFrom には〈通知メッセージを送ってきたコントロー
ルのウィンドウハンドル〉が入ってるから
このウィンドウハンドル宛にメッセージを送ればいいわけね
あ、もちろんこの通知メッセージは TVN_SELCHANGED のことだから
質問!
はい火美ちゃん
さっきの MFC の例ではこの hwndFrom って使わなかったよね。なん
で?
ん、そうだね、結論から言えば

    m_cMainTree.GetItem( &stTvItem );

の方が間違い
げ、そうなの?
まず、どのツリービューコントロールから送られてきた通知メッセージか
どうかはこの hwndFrom を見ないと分からない、っていうのを憶えて
ほい憶えた
ってことは、ツリービューコントロールが複数あったら、その複数のツ
リービューコントロールから送られてきた通知メッセージが、この 
OnSelchangedTreeMain() に送られてくるってこと
げ、つまりいろんなツリービューコントロールのがごちゃ混ぜになって
入って来るんだ
だから、実際には hwndFrom を見てどう処理するか決めなきゃいけないわ
け。理想はコントロール毎に別の関数にディスパッチすることだね
ダイアログプロシージャのとこで振り分けちゃうわけね
で、今回の例ではツリービューコントロールはひとつだけだから、どんな
通知メッセージも、どのツリービューコントロールから送られてきたかは
はっきりと分かってるわけ
それが m_cMainTree なわけね
そゆこと。だからここでは問題ないってこと。あ、それに、これは MFC 
の問題じゃないからね
そなの?
 m_cMainTree の代わりに、 m_cMainTree の中に入ってるツリービューコ
ントロールのハンドルを操作する、ってことなら今の例でもできるから

    HWND hMainTreeWnd
        = GetDlgItem( p_hDlgWnd, IDC_TREE_MAIN );

 OnInitDialog() の中のだね。あ、そっか、これがそのツリービューコン
トロールのハンドルなんだ
そゆこと。だから、今回みたいにツリービューコントロールがひとつだけ
なら、 hwndFrom を使わずにこの hMainTreeWnd を使うって手もあるわけ
ひとつだけならそれも許されるわけね
あ、そうそう、当たり前って言えば当たり前だけど、 hMainTreeWnd と 
hwndFrom は値が同じ、つまり hMainTreeWnd == hwndFrom だから
おー、なるほど。同じツリービューコントロールだからハンドルも同じな
んだ。あ! もしかしてそれで通知メッセージがどこから送られてきたか調
べるとか?
あ、ううん、 NMHDR 構造体に idFrom ってメンバ変数があって、これが
送信元コントロールの ID になってるから
なんだ、便利なのがあるんだ。これと IDC_TREE_MAIN が同じか調べれば
いいわけね
そゆこと。というわけでダイアログプロシージャの話はここまで!
おお
最後になるけど、こういうふうに MFC を使わないでプログラムすること
を〈 SDK だけで作る〉って言います
 SDK って Version 5.31 ( No.096 ) のだね
そうそう。あ、同じく〈 API だけで作る〉とも言うから。こういう、 
MFC を使わない、 SDK だけで作る知識は MFC を使う時でも必要だから、
しっかりマスターしておいてね
 MFC も SDK 使ってるから、だよね?
そゆこと

/*
    Preview Next Story!
*/
とゆーわけで次回からは新章!
次回からは SDI アプリケーションについて見ていきます
って、それならさっきやったじゃん
 SDK じゃなくて、 SDI 
似たようなもんじゃないの?
全然違います
というわけで次回
< Version 9.01 SDI アプリを作ろう! >
につづく!
似てるんならパスしよ、パス
だから似てないんだって……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。