#pragma twice

KAB-studio > プログラミング > #pragma twice > 126 Version 7.06 四角な構造体

#pragma twice 126 Version 7.06 四角な構造体

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

 Version 7.06
四角な構造体

前回はリソースっていうものについて紹介しました
ようするに、ウィンドウズの中に作られて、ハンドルが返ってくるのがリ
ソース、でいいんでしょ?
そ。ちょっとあいまいなものだしね
あいまいって変なのー
で、この〈リソース〉は、ウィンドウズの仕組みの話
そりゃそーね
リソースもそうだし、デバイスコンテキストや GDI もウィンドウズ関係
のことだね。で、この Ver 7 では、同時に言語の話もしていきます
言語って、 C++ 言語ってこと?
そういうこと。 MFC では、デバイスコンテキストとかを使いやすくする
ために、いろんな C++ 言語の機能を使ってるんです
変数がなくなったら自動的に消されちゃうってアレ?
そう、あれ。そういう部分も少しずつ教えてくからね
……それは覚悟しろってこと?
いや、まぁ、別にペース上げるわけじゃないから、混乱しないでってこ
と。実際、今回は、両方いっぺんに憶えてもらうし
げげ
まずは、ウィンドウのサイズについて。ウィンドウのサイズは 
GetWindowRect() って API を使います

void CAnimeDlg::OnBDraw() 
{
    RECT stRect;
    ::GetWindowRect( GetSafeHwnd(), &stRect );
    TRACE
        ( "%d, %d, %d, %d\n"
        , stRect.left, stRect.top
        , stRect.right, stRect.bottom );
}

……なーんとなく分かるけど、 RECT ってのが謎
 RECT は〈構造体〉っていうのの一種
構造体?
構造体っていうのは、クラスの機能限定版……みたいなもの
うっわ、すっげー歯切れ悪!
その理由はあとでね。 RECT を見てみると、こういうふうになっていま


( Windef.h より抜粋)
typedef struct tagRECT
{
    LONG    left;
    LONG    top;
    LONG    right;
    LONG    bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
(抜粋ここまで)

???
これはちょっと分かりにくいよね。シンプルに書くと

struct tagRECT
{
    LONG    left;
    LONG    top;
    LONG    right;
    LONG    bottom;
};

クラスみたいでしょ
でもメンバ関数ないね
そう、構造体は〈メンバ変数しかないクラス〉って考えてもらうといいか

メンバ変数だから stRect.left ってできるんだ
そゆこと。 LONG 型は Ver 6.03 ( No.103 ) でやったからいいね
ようするに long 型ね
で、これに typedef を組み合わせてるのが上の。だから

typedef tagRECT RECT;

とかと同じ
でもさ、 class はそういうのしてないよね。 AnimeDlg.h 見ても

class CAnimeDlg : public CDialog
{
// 以下略。

って感じだし
この辺も、さっきの〈クラスの機能限定版〉とかと一緒に説明するから。
っていうか、この辺は複雑なんだよねー
げげ
だから、あとでまとめて説明するから。とりあえず今は、構造体は〈クラ
スもどき〉って憶えておいて
はーい
で、 RECT は API の方で用意してくれてる構造体で、とにかく【四角】
の情報を格納するための型
たとえばウィンドウの四角?
そう! もう一度メンバ変数を見てみて

struct tagRECT
{
    LONG    left;
    LONG    top;
    LONG    right;
    LONG    bottom;
};

最初ふたつ、 left と top は、四角の左上の X 座標と Y 座標
 X 座標とかって、 Ver 7.01 ( No.121 ) で SetPixel() に使ったのと同
じ?
それと同じ。たとえば GetWindowRect() でウィンドウの四角を取って、
その RECT::left と RECT::top を SetPixel() に渡せば
ウィンドウの左上隅に点が打てると
そゆこと。残りふたつ、 RECT::right と RECT::bottom は、四角の右下
隅の X 座標と Y 座標
あれ? 四角って言ったら4つありそうだけど
ううん、左上隅と右下隅さえあれば、右上隅と左下隅は分かるから。右上
隅の X 座標は右下隅の X 座標と同じだし、右上隅の Y 座標は左上隅の Y 
座標と同じだし
そういえば
だから左上隅と右下隅だけ。あ、ちなみに RECT は rectangle って英語
の略。 rectangle は〈長方形〉って意味だから
ベタベタなのね
で、 GetWindowRect() って API は第1引数で指定したウィンドウの左上
と右下を、第2引数で渡した RECT 構造体に格納します
戻り値で返すんじゃないんだね
構造体を戻り値で返すのは大変なんだよね
でもクラスは返すよね。 CString とか
その辺も構造体とクラスの微妙な関係ってとこかな
なんか、聞けば聞くほど変な感じ……
ま、それはそうなんだけどね。話を戻して、 GetWindowRect() の第2引
数には RECT 型変数のアドレスを渡します
そのポインタを通して変数に座標を入れてくれるわけね
あと、 GetWindowRect() にも MFC 版があります。 MFC 版は CWnd のメ
ンバ関数 CWnd::GetWindowRect() 

void CAnimeDlg::OnBDraw() 
{
    RECT stRect;
    GetWindowRect( &stRect );
    TRACE
        ( "%d, %d, %d, %d\n"
        , stRect.left, stRect.top
        , stRect.right, stRect.bottom );
}

さっきのは CWnd::GetSafeHwnd() のウィンドウハンドル渡してるんだか
ら、これと結果は同じになるわけよね。あ、そういえば試してなかった。ビ
ルドして実行、【描く!】ボタンっと

206, 81, 595, 492

これがウィンドウの四角?
そう、画面の左上隅からの位置。試しに、ダイアログ色々なとこに置いて
から【描く!】ボタン押してみて
ぽち。あ、ちゃんと値が変わってる。左上に持ってけば減るし、右下に
持っていけば増えるし。……
どしたの?
このダイアログ、画面の左上からはみ出させちゃったらどうなるの?
やってみ?
ほい。あ、マイナスになった!

-42, -16, 347, 395

おー、なんかすごい
あと、ウィンドウのサイズは変わってないのを確認してあいて
どゆこと?
 right - left 、 bottom - top の値は、ダイアログをどこに置いても同
じでしょ
 389 と 411 、同じ。あ、これってダイアログのサイズなんだ!
そゆこと。縦のサイズと横のサイズね。ウィンドウのサイズを変えな
きゃ、これはずっと一緒だから
ウィンドウのサイズ変えたら、これも変わるの?
もちろん。そのための API なんだもの
ほー。ん? そのための?
そう。実は、ウィンドウの位置関係の API ってこれくらい。だから、た
とえば〈ウィンドウの画面上の位置〉とか〈ウィンドウのサイズ〉を取得す
るのにもこの API 使うから
便利な API とか揃ってないの?
ないんだよねー。特に API は、必要最小限のものしか用意しないってい
う方針だから
確かに、ウィンドウの四角が分かれば、他も分かるんだろうけど……
最後に、もうひとつ似たような API 、 GetClientRect() を紹介します

void CAnimeDlg::OnBDraw() 
{
    RECT stRect;
    ::GetClientRect( GetSafeHwnd(), &stRect );
    TRACE
        ( "%d, %d, %d, %d\n"
        , stRect.left, stRect.top
        , stRect.right, stRect.bottom );
}

うわ、ほとんど同じ……
 API が GetClientRect() になっただけだね。〈クライアントエリア〉
って憶えてる?
 Ver 7.02 ( No.122 ) でやったのだよね。タイトルバーとかを除いた部
分ってゆーの
そうそう。この GetClientRect() はそのクライアントエリアのサイズを
取得するための API 
サイズ?
試してみると分かるかも
ほい

0, 0, 383, 386

あ、左上の座標が 0 だ
クライアントエリアはウィンドウの中の一部だから、位置は関係ないんで
サイズだけ返ってきます
やっぱウィンドウよりちょっと小さいね
ウィンドウに描画する時にはクライアントエリアに描くことになるだろう
から、こっちの方が使うこと多いかな?

/*
    Preview Next Story!
*/
それにしても、 API って親切じゃないってゆーか
もっと種類多い方がいい?
その方が便利じゃない?
憶える API 増えるけど
…… API って全部でいくつくらいあるの?
いや、何百ってあるから数え切れないけど
な、何百ぅ!?
というわけで次回
< Version 7.07 構造体とクラス >
につづく!
まだ増え続けてるし、メッセージとかも入れると……
あ、あたし降りる〜!!
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。