#pragma twice

KAB-studio > プログラミング > #pragma twice > 195 Version 10.17 ステータスバーをクリック!

#pragma twice 195 Version 10.17 ステータスバーをクリック!

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

 Version 10.17
ステータスバーをクリック!

「今回は、ステータスバーをクリックしたときのメッセージを受け取ってみ
ます」
『……それって意味ある?』
「あんまりないかも。どちらかというと、前に使った【通知メッセージ】の
復習の方が大きいかも」
『通知メッセージって、 Version 5.29 ( No.094 ) とか 
Version 8.10 ( No.152 ) とかに出てきたのだね』
「そう、コントロールがなにか操作された時に送られてくるメッセージ。ス
テータスバーはコントロールのひとつだから」
『同じように通知メッセージが送られてくるってことね』
「そういうこと。じゃあ、まずは試してみましょう。この前のステータス
バーを作った部分を次のように修正してください」

HWND g_hStetusBarWnd;
const int ID_STATUS_BAR = 5001; // まずここを追加。

// ウィンドウが作られます。
LRESULT OnCreate
    ( HWND p_hWnd
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    // ステータスバーを作ります。
    g_hStetusBarWnd = CreateStatusWindow
        ( WS_CHILD | WS_VISIBLE
        , "テスト"
        , p_hWnd
        , ID_STATUS_BAR // ここを修正。
        );
    if( g_hStetusBarWnd == NULL )
    {
        // ステータスバーが作られませんでした。
        return -1;
    }

    // 分割するコードはあってもなくてもいいです。

    return 0;
}

『ほとんど変わんないね』
「 CreateStatusWindow() の第4引数に渡す ID を別にしただけだからね。
さっきも言ったように、ステータスバーはコントロールのひとつ。さて問
題。コントロールにはどんなのがある?」
『どんなのって、いっぱいあるよね。ボタンとかエディットボックスとか』
「そうそう。そういうのに ID ってあったでしょ」
『あ! この ID_STATUS_BAR は、ステータスバーっていうコントロールの 
ID ってことなんだ』
「そういうこと。だから、この ID_STATUS_BAR の値は他のコントロールと
重ならないようにね」
『それってどう調べるの?』
「メニューの【表示】−【シンボルブラウザ】のダイアログで確認できる
から。ちなみに、ここで値をセットすることもできるよ」
『どういうこと?』
「右側の【新規作成】ボタンを押して、 ID を ID_STATUS_BAR に、値を
5001 にして登録すれば」

const int ID_STATUS_BAR = 5001; // まずここを追加。

「の行は削除できるから」
『……つまり?』
「つまり、ボタンとかに使う ID を、別に何にも使わずに ID だけ登録でき
るってこと」
『あ、そっか、それをそのままステータスバーに使えるわけね』
「このシンボルブラウザなら割り当てられてる ID を確認してから登録でき
るから、他と間違えて同じ値をつけることがなくて安心かも」
『同じ値を付けることってできるの?』
「うん、シンボルブラウザでも普通にできるから。それをすると、最悪、ス
テータスバーを押すのと〈終了〉コマンドが一緒になっちゃって」
『アプリが閉じちゃう』
「ってこともあり得るから。さて、今度はステータスバーをクリックしたと
きのメッセージを受け取るように、ウィンドウプロシージャを修正します」

// ウィンドウプロシージャ。
LRESULT CALLBACK WndProc
    ( HWND p_hWnd
    , UINT p_uiMessage
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    if( p_uiMessage == WM_CREATE )
    {
        return OnCreate( p_hWnd, p_wParam, p_lParam );
    }
    else if( p_uiMessage == WM_DESTROY )
    {
        return OnDestroy();
    }
    else if( p_uiMessage == WM_RBUTTONUP )
    {
        return OnRButtonUp( p_hWnd, p_wParam, p_lParam );
    }
    else if( p_uiMessage == WM_COMMAND )
    {
        if( LOWORD( p_wParam ) == ID_MENU_TEST )
        {
            return OnMenuTest( p_hWnd, p_wParam, p_lParam );
        }
    }
    else if( p_uiMessage == WM_NOTIFY ) // ここから下を追加。
    {
        if( p_wParam == ID_STATUS_BAR )
        {
            NMHDR *pNmhdr = (NMHDR*)p_lParam;
            if( pNmhdr->code == NM_CLICK )
            {
                // クリックされました。
                OutputDebugString( "クリックされました。\n" );
                return 0;
            }
        }
    }

    // 標準的な処理をします。
    return DefWindowProc( p_hWnd, p_uiMessage, p_wParam, p_lParam );
}

『あ、 WM_NOTIFY って前に出てきたね』
「そう、これが通知メッセージ。 Version 8.18 ( No.160 ) では、ダイ
アログプロシージャで通知メッセージを受け取ってます」

    else if( p_uiMessage == WM_NOTIFY )
    {
        if( p_wParam == IDC_TREE_MAIN )
        {
            NM_TREEVIEW* pstNmTreeView = (NM_TREEVIEW*)p_lParam;
            if( pstNmTreeView->hdr.code == TVN_SELCHANGED )
            {
                return OnSelchangedTreeMain( pstNmTreeView );
            }
        }
    }

『形式はかなり似てるね』
「通知メッセージそのものを比較するところくらいかな、違いは。一応、ひ
とつひとつ見ておこうか。まず、通知メッセージを受け取ったら、どの ID 
のコントロールからのメッセージか調べます」

        if( p_wParam == ID_STATUS_BAR )

『ここでさっきの、ステータスバーのコントロールが出てくるのね』
「そういうこと。ボタンとかならボタンの ID 。ステータスバーならス
テータスバーの ID ってこと」
『それで……ここは違うんだね』

            NMHDR *pNmhdr = (NMHDR*)p_lParam;

「ツリービューの時は LPARAM には NM_TREEVIEW 構造体のポインタが入っ
てたんだけど、 NM_CLICK の時は NMHDR 構造体のポインタが入ってるか
ら」
『 NM_CLICK が送られてきてるから NMHDR にキャストして……って、そ
れって変じゃん!! だって、 NM_CLICK が送られてきたって分かるの、
キャストしたあとじゃない』
「そう、よく分かったね。これはあとでちゃんと説明するけど、構造体って
こういうことができるようになってるんです。 NM_TREEVIEW の中身は」

[ NMHDR ][ UINT ][ TVITEM ][ TVITEM ][ POINT ]

「って感じに入ってるんです。この最初の所に NMHDR があるでしょ」
『これがあるとどうなの?』
「もしツリーバーの通知メッセージで LPARAM に NM_TREEVIEW へのポイ
ンタが入っていたとしても、それを NMHDR のポインタに変えても問題な
いってこと」
『???』
「……これは来週、ちゃんとやった方がいいかも」
『げ』
「げってことはないでしょ」
『うー』
「話を戻して、キャストをしたら、どんな通知メッセージが送られてきたの
か調べます」

            if( pNmhdr->code == NM_CLICK )

『 NM_CLICK はクリックされたときの?』
「そう。正確には右クリックされた時に送られてくる通知メッセージ。これ
はステータスバーに限らずにいろんなコントロールから送られてくるから」
『それこそ、ちゃんと ID を調べないとまずいわけね』
「そういうこと。で、クリックされてたら」

                // クリックされました。
                OutputDebugString( "クリックされました。\n" );

「の所に入ります」
『これはテスト用で、何かするんだったらちゃんと関数作った方がいいんだ
よね』
「もちろん。その場合の引数はどうするか微妙だけど」
『そっか、 WPARAM と LPARAM にするか、 NMHDR のポインタにするか、
ってことね』
「その辺は好みによるかも。あ、あとひとつ補足。今回、ステータスバーを
作ったときに、前回のいくつかにわけるって部分は省きました」
『そういえばそうだね』
「で、どうも〈分けた中のどれをクリックしたか〉は取得できないみたいで
す」
『げ、そうなんだ』
「マウスの位置を取得して、それでどれがクリックされたか調べるしかない
かもね」
『そんなことできんの?』
「カーソル位置を取得する API は?」
『 GetCursorPos() !』
「分割するときには左側からのサイズを渡すんだから」
『あ、あの配列の数字ねー。あ、できちゃいそう』
「そういうこと」

/*
    Preview Next Story!
*/
『やっぱり API って便利じゃないね』
「この辺はノウハウの方が重要かもね」
『つまりカーソル位置を知るための API は、みたいな?』
「そういうこと」
『でもそこまでまだ気が回らないなー』
「そのためには基礎をもっと勉強しないと」
『基礎ねー』
「というわけで次回」
< Version 10.18 構造体の構造 >
『につづく!』
「というわけで基礎を学びましょう!」
『う”、そういうの苦手なんだけど……』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。