#pragma twice

KAB-studio > プログラミング > #pragma twice > 199 Version 10.21 ツールバーとクライアントエリア

#pragma twice 199 Version 10.21 ツールバーとクライアントエリア

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

 Version 10.21
ツールバーとクライアントエリア

「前回はウィンドウに文字列を表示してみました」
『前にやったのの SDK 版ってことだったんだよね。でも』

    TextOut
        ( hDC
        , 0
        , 28
        , pchText
        , strlen( pchText ) 
        );

『の 28 ってのが謎なのよねー』
「試しに 0 にしてみると?」
『ビルドして実行。あ”、なんも表示されなくなっちゃった……』
「実はこの時、文字列はツールバーの裏に表示されてるんです」
『えっ? あっ、ってことは 28 ってツールバーの高さ!?』
「そう。【クライアントエリア】って憶えてる?」
『うん、 Version 7.02 ( No.122 ) でやったね。タイトルバーやメニュー
じゃない、こっちが描画していい部分のことだよね』
「そのクライアントエリアはメニューの中、つまり、ツールバーはそのクラ
イアントの中に置いてあるんです」
『げ! ツールバー置いたらその分クライアントエリアが狭くなるわけじゃ
ないの???』
「そうじゃないんです。だから、その分ずらして描画する必要があるわけ」
『うー』
「ちなみに、この 28 って数字はツールバーの状態で変わるから、実際には
実行時に取得した値を使った方がいいかな」
『どゆこと?』
「えっとね……ツールバーって OnCreate() で作ってるよね」
『うん』
「その上にこの変数を置いて」

int g_iToolBarHeight;   // ツールバーの高さ。

『グローバル変数ってヤツ?』
「そういうこと。で、 OnCreate() の最後に3行追加します」

// ウィンドウが作られます。
LRESULT OnCreate
    ( HWND p_hWnd
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    // 中略。 Version 10.19 ( No.197 ) のと同じ。

    // ツールバーの高さを取得します。
    RECT stRect;
    GetWindowRect( hToolBarWnd, &stRect );
    g_iToolBarHeight = stRect.bottom - stRect.top;

    return 0;
}

『 GetWindowRect() ってウィンドウの位置とか高さとか取得するのだよ
ね。 hToolBarWnd はツールバーのウィンドウハンドル……そっか、これで
ツールバーの高さがわかるんだ』
「この API でツールバーのウィンドウの上側の位置と下側の位置を取得し
て、それを引けば高さになるから。で、さっきの 28 の所は」

    TextOut
        ( hDC
        , 0
        , g_iToolBarHeight
        , pchText
        , strlen( pchText ) 
        );

『ってするとちょうどツールバーの高さの分だけ下に表示するわけね』
「あ、ちなみに、 MFC の場合にはまた違った状態だから。 Version 9.01 
( No.162 )
 で紹介したビューウィンドウって憶えてる?」
『うん、ウィンドウの真ん中の白い四角いウィンドウ……あ!』
「そういうこと。今は大元のウィンドウのクライアントエリアに描いてたか
らツールバーを避けなきゃいけなかったけど」
『そもそも、そのツールバーの中にウィンドウひとつ作って、そこに表示す
ればいいんだ!』
「それが MFC のビューウィンドウにあたるってことだね」
『ってことは、今はフレームウィンドウに直に描いてるようなもんなのね。
じゃあさ、 SDK でもビューウィンドウ……って作れないの?』
「もちろん作れるよ。 MFC だって SDK の上に成り立ってるものなんだか
ら。ただ……」
『ただ?』
「実際には管理とか難しいから。たとえば、今ツールバーの問題が出たけ
ど、同じようにツールバーやステータスバーの中に入るように」
『ウィンドウのサイズ決めて、表示しなきゃいけない……』
「しかも、フレームウィンドウのリサイズをしたら」
『げっ、それにもあわせなきゃいけない!!』
「そういうこと。 MFC はそこまでの枠組みがしっかりできてるからいいけ
ど」
『 SDK だけだと、そこも自分で作らなきゃいけないわけね……ふー』
「だから、今回はとりあえずフレームウィンドウだけで、ね。では、目的
だった、テキストエディタもどきを作ります。まず、さっきみたいにグロー
バル変数を OnCreate() を置きます」

// 入力文字列を取っておくための変数。
const int TEXT_MAX_LENGTH = 256;
char g_pchText[TEXT_MAX_LENGTH + 1];

『前にテキストエディタもどきを作ったときには、メンバ変数に入れていた
し、 String クラス使ってたよね』
「そう、その辺は MFC との違いだし、実はその辺は非常に大きな意味を
持ってるんだけど」
『それはまた先の話?』
「そういうこと。で、この変数には入力した文字列を入れておきます。入れ
るのはもちろん、キー入力したときのハンドラ」
『 OnChar() ね』
「そういうこと」

// キー入力がありました。
LRESULT OnChar
    ( HWND p_hWnd
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    // 入力された文字を取り出して、文字列にします。
    char ch[2];
    ch[0] = (char)p_wParam;
    ch[1] = '\0';
    // それをくっつけます。
    if( strlen( g_pchText ) < TEXT_MAX_LENGTH )
    {
        // 文字列サイズをオーバーしてないのでくっつけまず。
        strcat( g_pchText, ch );
    }

    // そして再描画。
    InvalidateRect( p_hWnd, NULL, TRUE );
    return 0;
}

『 strcat() って?』
「第1引数の文字配列に、第2引数の文字列をくっつけるランタイム。一応
Version 5.07 ( No.072 ) でやったんだけどね」
『そんな昔のこと忘れたし……1回しか出てきてないし……』
「あとわかりにくいのはこれかな」

    char ch[2];
    ch[0] = (char)p_wParam;
    ch[1] = '\0';

「まず、 WM_CHAR は、入力された文字を WPARAM に入れて渡してきます」
『それを char にキャストして受け取るわけよね。でも配列?』
「そう、 strcat() に渡すためには文字列じゃないといけないから」
『その辺、ちょっとわかんないかも』
「ま、それは少ししたらみっちり教えるから大丈夫」
『少ししたら?』
「うん、結構すぐ。 InvalidateRect() はいいよね」
『再描画する API だね。だから、これを呼ぶと再描画されるから……どう
なるんだっけ』
「再描画するメッセージは?」
『 WM_PAINT だから、 OnPaint() が呼ばれる!』
「そういうこと」

// 再描画します。
LRESULT OnPaint
    ( HWND p_hWnd
    , WPARAM p_wParam
    , LPARAM p_lParam
    )
{
    PAINTSTRUCT stPaintStruct;
    HDC hDC
         = ::BeginPaint
                ( p_hWnd
                , &stPaintStruct 
                );
    // この行は削除。
    TextOut
        ( hDC
        , 0
        , g_iToolBarHeight
        , g_pchText // ここと、
        , strlen( g_pchText ) // ここを修正。
        );

    ::EndPaint
        ( p_hWnd
        , &stPaintStruct 
        );

    return 0;
}

『表示する文字をさっきのに変えたのね』
「こうすれば」
『おおっ、またもやテキストエディタもどきに!!』
「ここまでは、はっきり言ってこれまでの復習だから、よく読み返して、ど
こがどう継ながってるのか理解してね」
『はーい』

/*
    Preview Next Story!
*/
「 SDK 編は来週で終わりです」
『そっか、 MFC でやったのはもうだいたいやったんだね。次は?』
「みっちり基礎を勉強してもらいます」
『げげ!』
「でも実用度はかなり高いと思うよ」
『ほんとかなー』
「本当……だけど、つまらないと思う」
『げげげ!』
「というわけで次回」
< Version 10.22 SDK のまとめ、そして文字列へ >
『につづく!』
「でも絶対役に立つから!!」
『ほんとかなー』
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。