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