Version 7.01
描画してみよう!
『祝、バージョン7!』
「祝って……何が?」
『なんでも。で、バージョン7はなにすんの?』
「バージョン7では、総合的なことを教えていこうと思ってます」
『つまり応用ってこと?』
「そゆこと。やることは今までの知識でだいたいできる、でも実際にプログ
ラムを組んでみると難しい、みたいな部分について教えていこうと思ってま
す」
『おお、やっとそこまで!?』
「ってゆーか、普通はこういうのを先に勉強したりするんだろうけどね、本
を読んだりしてって場合には」
『確かに本とか読むとそうかも。でもマイペースでいいよねー』
「いいのかなぁ」
『あんたがゆーな!』
「まーまー。このバージョンでは、まずダイアログに絵を描いてみます」
『おお!』
「その〈絵を描く〉ってことにすんごくいろんなことが詰まってるから、ま
ずはその辺をしっかりと」
『ほい』
「そのあとタイマーっていうのを使って、ここでメッセージについて教えま
す」
『メッセージって前にやったよね』
「簡単にだけどね。今回はもうちょっと詳しく。で、アニメーションさせて
みたいんでダブルバッファってものについても教えます」
『ダブルバッファ? バッファって文字列受け取るの?』
「ううん、それとは違うの。この辺は結構上級者向けかもね」
『へー』
「今回はそういう感じに進めていこうと思ってます。目標、26回!」
『絶対無理』
「あうー。さて、まずはプロジェクトの作成から。いつもの MFC 使ったダ
イアログクラスを作って」
『ほい。Ver 5.01 ( No.066 ) のと同じ方法でいいんだよね。プロジェクト
名は……今、アニメーションさせるって言ってたよね?』
「うん、最終的にはそこまでやってみたいかな」
『じゃー Anime プロジェクトで。いつものダイアログエディタだ』
「じゃあまず真ん中の〈TODO:〉を削除して、ボタンをひとつ追加して。こ
れを押したら描くようにしたいから」
『じゃ、【描く!(&D)】で IDC_B_DRAW でいい?』
「そんなとこだね。さらに、【ピクチャー】を貼り付けてダイアログいっぱ
いくらいに広げて」
『ピクチャー?』
「ボタンとかエディットボックスとかのある【コントロール】ツールボック
スの、最初から2番目、つまり矢印の右側」
『あー、謎のサボテン砂漠ね』
「サボテン砂漠、確かにそう見える……」
『これのプロパティは……ん? ID が IDD_ANIME_DIALOG ?』
「それはダイアログのプロパティ。今の状態のピクチャーだと〈枠〉だけだ
から、枠の部分で右クリックしてプロパティ選んで」
『ほい。今度は大丈夫そう……あれ? IDC_STATIC って前に見たような』
「そう。 Ver 3.12 ( No.037 ) でやった、普通の文字列をダイアログに貼
り付ける【スタティック】と同じ」
『さっきの〈TODO:〉のだね』
「このピクチャーはそれに近いの。普通のスタティックは文字列を表示する
けど、ピクチャーはアイコンやビットマップを表示するのに使います」
『ってことは、これにアイコン貼れるの?』
「貼れるよ。このプロパティで【タイプ】を【アイコン】にして【イメー
ジ】を IDR_MAINFRAME にして」
『ほい。お、いつもの MFC のへんてこなアイコンが出た!』
「もしダイアログにちょっとアイコンを貼り付けたいっていう時には」
『こうすればいいわけね』
「で、今回はアイコンを貼り付けるわけじゃないから。まず【 ID 】は
IDC_S_CANVAS にして、【タイプ】は【四角形】、【色】は【白】にして」
『ほいほいほい。……あれ? いつのまにか小さくなってる』
「【タイプ】を【アイコン】にしちゃったからね。もう一度ダイアログいっ
ぱいに広げておいて」
『ほい』
「ダイアログの方はこれで完成。今度はプログラムの方。まずクラスウィ
ザードで IDC_S_CANVAS に変数を関連づけます」
『【表示】−【ClassWizard】で【メンバ変数】のページで IDC_S_CANVAS
をダブルクリック』
「【カテゴリ】を【コントロール】、【変数のタイプ】を【 CStatic 】に
して」
『へー、 CStatic なんてクラスがあるんだ。変数名は?』
「まー適当に…… m_cCanvasStatic にでもしといて」
『ほい。次は?』
「次は【描く!】ボタンを押したら呼ばれる関数作って」
『ほい。【描く!】ボタンを右クリックして【イベント】、んでそのまま
【追加と編集】っと。CAnimeDlg::OnBDraw() ができたよ』
「それじゃ、その中にこういうコードを書き込んで」
void CAnimeDlg::OnBDraw()
{
COLORREF dwColor = RGB( 255, 0, 0 );
HDC hDC = ::GetDC( m_cCanvasStatic.GetSafeHwnd() );
::SetPixel( hDC, 10, 10, dwColor );
}
『うわぁ、知らないのばっかし……』
「これまで一度も使ってないのばかりかも」
『まーいーや。ビルドして実行、【描く!】ボタンを押す……何か起きた?』
「 IDC_S_CANVAS の左上をよーく見てみて」
『……あ、赤い点が』
「こうすれば、 IDC_S_CANVAS の ( 10, 10 ) に点を描くことができます」
『地味……。 ( 10, 10 ) って、左側が横軸で右側が縦軸?』
「そうだよ。たとえば」
::SetPixel( hDC, 50, 50, dwColor );
『右下にずれた』
「最初のふたつの引数が、四角形の左上の点の、 X 座標と Y 座標、つまり
横軸と縦軸ね。その次のふたつの引数は四角形の右下の点の X 座標と Y 座
標」
『最後のは? ってゆーか1行目でなんか謎なことしてるんだけど』
「これだね」
COLORREF dwColor = RGB( 255, 0, 0 );
「まず、ウィンドウズで色を表す時には COLORREF 型を使います」
『だから FillSolidRect() でもそれを受け取ってるのね』
「ちなみに COLORREF は DWORD 型から typedef されてるからここでは dw
を変数の頭に付けてます。はい問題、 DWORD ってなんでしょ」
『4バイトの符号なし整数でしょ、 Ver 5.16 ( No.081 ) でやったね』
「そうです。で、その4バイトの中になんとかして色を入れなきゃいけな
い、そのために使うのが RGB() ってマクロです」
『これマクロなんだ』
「そ。さて、こっからはちょっとプログラムの話からそれて、色の話に入り
ます」
『色?』
「そう、色。〈光の三原色〉と〈色の三原色〉って知ってる?」
『丸の中に色が描いてあるヤツでしょ。光の三原色は赤青緑で、全部足すと
白になるの。色の三原色は赤青黄色で、全部足すと黒になるの』
「そんなとこかな。で、まず光の三原色から。光の色は、赤・青・緑を割合
を変えつつ足し合わせることで、どんな光の色も作ることができます」
『それが三原色って意味ね』
「そゆこと。全部足し合わせれば白になります。それに、どれもない、つま
り光がなければ当然真っ黒、闇になります」
『……なんかバカにされてるような気がするんだけど』
「でもこの辺って結構あいまいだと思うよ?」
『そう言われるとねぇ……』
「で、ディスプレイで色を出す時にはこの光の三原色を使います」
『色の三原色じゃないのね』
「そう。ディスプレイは中から〈光のビーム〉を出してて、それが見てる人
の目に入る仕組みだから」
『色の三原色は?』
「色の三原色は、光が何かに当たってはね返った色のこと。今回はディスプ
レイのことだけだから、色の三原色の話はパスね」
『あ、逃げた』
「逃げたわけじゃ……」
『で、それがどうつながってくるの?』
「あ、えーっと、もう一度これ見て」
COLORREF dwColor = RGB( 255, 0, 0 );
「光の三原色の赤・緑・青を英語で書くと」
『 Red 、 Green 、Blue ね』
「その頭文字で」
『 RGB ! そういう意味だったんだ』
「で、 RGB() マクロの引数もその R G B と同じ。今、真っ赤になったのは
R 、つまり第1引数が 255 だから」
『ってことは第2引数が 255 、つまり』
COLORREF dwColor = RGB( 0, 255, 0 );
『お、緑色になった!』
「もちろん第3引数は青色だから」
『 255 以上は?』
「ないよ。引数は引数なし1バイト整数だから」
『ってことは 0 から 255 ってことね』
「で、各色の割合を微妙に変えれば、どんな色も表現できるから」
『どんな色も? 金色も?』
「いや、〈金色〉って色はないから」
『絵の具にあるじゃん』
「いや、あれは違うから……まーいーや。そういう無理なの以外の色は作れ
るから。さて問題、赤・緑・青が 0 から 255 、ってことは、実際の色の種
類っていくつ?」
『どゆこと?』
「えーっと……赤と、緑と、青、それぞれ少しずつ割合変えればいろんな色
ができるでしょ。そうやって作れる色の数は? ってこと」
『えーっと、赤は 0 から 255 まで変えられて、緑もそうでしょ、ってこと
は赤が 0 のとき緑も 0 から 255 種類あって、赤が 1 のときも……だか
ら、 255 とおりが 255 とおりあるんだから』
「違うっ! 2進数のときやったでしょ、 0 から 255 なら」
『あ、 256 とおり! ちょっとボケただけよ。で、かけて 65536 とおりだ
ね』
「で、青も加えると?」
『それが 256 通りあるから…… 16777216 だって。かなり多いね』
「そう。で、これがよく言われてる〈フルカラー〉のこと」
『これが〈フル〉なんだ。もっと上はないの?』
「これ以上色数が増えても、人間の目には比べられないんだよね」
『なさけな』
「はいはい。で、ここで COLORREF のリファレンス見てみて」
『ダブルクリックして F1 っと。げ、英語!』
「 COLORREF も RGB() も API のだからねぇ、これはしょうがないかな。
で、この中にこういうふうに書いてあるでしょ」
0x00bbggrr
「これが、 RGB() マクロを作った後の COLORREF 変数の中身」
『 bb が青、 gg がグリーン、 rr が赤だよね』
「そう、つまり RGB() マクロは各引数を16進数2桁ずつに変換して、こ
ういうふうに各バイトに置くんです。1バイトの変数は char 。 unsigned
cher の範囲は?」
『 0 から 255 、だから RGB() の引数もそうなんだ』
「 DWORD の4バイトのうち、1バイト目は使わないで、2バイト目は青、
3バイト目に緑、4バイト目に赤が入るわけ。ちなみに2バイト目から4バ
イト目の3バイト、ビットで表すと?」
『1バイトは8ビットだから24ビットだね』
「よくフルカラーのことを〈24ビットカラー〉っていうのはこれが理由」
『【画面のプロパティ】のはそうだね』
「で、重要なとこ。別に色を表すのに、こういうふうに1変数に詰め込む必
要なんか、ホントはないわけ」
『クラスのメンバ変数に入れたり、ってこと?』
「そゆこと。でも API の仕様がこうなってる、からそれに従わなきゃいけ
ない。今回から教えてくのは、そういう〈 API のルール〉を知ってくこと
だから」
『なんかめんどそ』
/*
Preview Next Story!
*/
「実際面倒かもね」
『そなの?』
「そう、なんでやねん!」
『!?』
「って仕様が多々あるんだよねー」
『ビックリした……』
「というわけで次回」
< Version 7.02 デバイスコンテキスト >
『につづく!』
「ま、愚痴りながら憶えると早いかも」
『変な勉強法……』