SSブログ
ウィンドウズ アプリケーションのプログラミング講 ブログトップ

Windows C++プログラミング講座 「型」って何だ?? [ウィンドウズ アプリケーションのプログラミング講]

このページでは、「」についてお話します。

C++言語には、沢山のがあります。特にウィンドウズアプリケーションの開発を
する場合、コールバック関数などの色々な場面でウィンドウズ独特の型が登場して
慣れないうちは、戸惑ったりします。

そもそも、「」って何のためにあるかと言いますと

記憶領域の確保

のためにあります。

これは、どういう事かと言いますと、例えば一つの変数を考えて欲しいのですが、
数学の場合の「x」とか「y」とかの変数って、値は自分の頭で覚えていました。

x=5とか…

xは5なんだな…って自分の頭で覚えていたのです。

しかし、プログラムの場合は、そうは行きません。
どこかに覚えておくメモのようなものが必要なんです。

さらに言えば、メモする「事」や「モノ」の「タイプ」と言いますか形式のようなものも
必要なんです。

なぜかと言いますと、ただ単に数値をメモするなら良いのですが、
例えば文章などをメモしておく場合などは、メモできる文字数など、
メモできる場所の大きさをちゃんとしておかないとダメなんです。

x = 5

ならば、変数「x」に「5」と言う値が記憶されますが、
これは、「x」と言う「名前」の変数に「5」と言う「数値」が記憶される事を
意味します。


仮に、「x」と言う名前の「数値」を記憶するためのメモを使いたいときは、
あらかじめ「x」という名前で「数値」を記憶するための「領域」を確保しなければ
ならないのです。

その領域を確保するために必要なのが「型」です。
言い換えれば、「ひな形」って感じなのかもしれません。

「型」が分かれば、確保された領域には「どんな値が記憶されるか」が分かります。
逆に言えば、「型」が指定されれば「どれだけ領域を確保すれば良いのか」が分かります。

そして、「確保された領域にはどんなタイプの値が記憶されるか」も分かるのです。

C++言語の場合、変数を使用する場合は
必ずあらかじめ「変数」を「型」の指定と共に宣言しなければなりません。

この「変数を宣言」する事によって、指定された「型」によって必要な領域が
宣言された「変数の名前」で確保されます。

確保された領域には、「変数の名前」でアクセスする事が出来て、
ちょうど数学の変数と同じ感覚で使用する事が出来るようになります。



C++言語には、「int」型というものがあります。
これは「Integer」の略で「イント型」って私は読んでます。整数という意味です。

「int」型は、整数値を記憶できる領域を確保するための型で、32bit4バイトの
領域が確保されます。

この確保された4バイトの領域は「x」という名前です。

次の行の「x = 5;」は単に「x」に5を代入と理解してもいいのですが、
厳密には、「x」という名前の記憶領域に「5」を記録するという意味です。

そして、この記録された値は、変更されるまでずっと保持されます。
(でも電源切ると消えます)


ウィンドウズのプログラミングでは、独特の型がたくさんあります。
例えば「HWND型」とかです。

これは、32bitで4バイトの整数値で「int型」と同じなんです。
じゃぁ「HWND」なんてややこしい型を使わないで「int型」でいいじゃないか!

と思うかも知れませんが、大規模なプログラムを書いていると分かると思うのですが、
同じタイプの型でも、「何の目的の変数なのか」が分かるようにしておかないと、
結局は混乱してしまうんです。

同じ整数値なのですが、

単なる数値なのか…

ウィンドウへのハンドルなのか…

インスタンスへのポインタなのか…

一体、何を表す「整数値」なのか、「型」によって分かるようになっているんです。

ウィンドウズには、結局は「int型」と同じなのに、わざわざ別の型で表される事が
大変多いです。

でも、それらは全く別物として扱った方が好ましいので、
あまり難しく考えない方が良いと思います。


「int型」は、汎用的に使う変数用で、
「HWND型」は、ウィンドウハンドル。
「LRESULT」は同じ32bit整数値だけどコールバック関数の戻り値。

のように全て32bit整数値だけども、全て用途の違う別物と考えて使用して
目的に応じて使い分けられています。

実際に、コンパイラも別物として扱っているので
間違えると、ちゃんとエラーになってくれます。

そうやって、別の型の変数を間違って使うことを避けて
バグを最小限に抑えるようになっているのです。


C++言語には「型」を自分で作る事ができる機能があるので、
このような事ができるのです。

クラスを使って「型」を作ることもできるし、
構造体も、一つの「型」です。

また、「int型」に「別名」を付けることにより新たに「型」を作ることも出来ます。



こんな風に「CNUM」とかって言う(まぁゲームとかでキャラクタの番号入る数値とか…)
整数値なんだけど、特化した目的で使う数値が入る変数に使ったり…

単に「int型」だと使用目的がわかりにくくなるので別名をつけたりします。

そうやって、型が増えていきます。

ウィンドウズのプログラミングの場合は、あらかじめ定義された型が沢山あって
最初はとっつきにくい部分はあるとは思うのですが、
意外とすぐに慣れてしまう程に使用目的が特化しているので大丈夫だと思います。

理屈を習うよりも慣れてしまったほうが、早いと思いますよ。






Windows C++プログラミング講座 第1回 コールバック関数(関数の話) [ウィンドウズ アプリケーションのプログラミング講]

前回は、単にウィンドウを表示すると言う単純なアプリケーション(と呼べるか…)を
作ってみました。(出来たでしょうか?)

今回は、前回の最後でお話した通りに「コールバック関数」についてお話します。
また、ちょっと手を加えて


コールバック関数に、どのように手を加えてアプリケーションを作っていくか
に触れていきます。(いきなりですが…)


前回にお話したコールバック関数とは、


これです。この

LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp)

この部分についてお話したいのですが、これは「関数」です。


厳密には、



この「 { 」から「 } 」で囲まれた部分を含んで「関数」です。

⇒関数についての詳しい説明(記事編集中ですゴメンなさい)


この、コールバック関数の戻り値の型は「LRESULT」ですが、これはLRESULT型なんだなって思っておいて良いと思います。

一応、説明しますとエル・リザルトと読み32bitの整数値で、S_OK / S_FALSE が値です。
意味不明でしょう?

だから、今は「LRESULT型」なんだな。と思って下さい。(それで大丈夫です)

「CALLBACK」が書いてある事によって、これはコールバック関数である事が決定します。


【そもそも「コールバック関数」ってなんだ??】


そう思うのも当たり前ですね。

コールバック関数とは、関数を呼び出す時に、別の関数のアドレスをパラメータとして渡して、呼び出した関数からパラメータとして渡された別の関数を呼び出すようにする事で、

最初に呼び出した関数から呼び出される別の関数の事を「コールバック関数」と言います。

難しいですねーーー♪


ここでは、ウィンドウズアプリケーションの開発が目的なので、
単純に、作成したウィンドウから呼び出される関数の事だと思っておいて下さい。

ただ、なんで作成したウィンドウから関数が呼び出されるかと言いますと、
作成したウィンドウに何か操作をした時に、メッセージを受け取る事が必要なんですよ。

さらに、そのメッセージを受け取って、メッセージに応じた処理をする事が必要なのです。

だから、ウィンドウを複数作った場合は、基本的にはウィンドウの数だけ
コールバック関数が必要なんです。

それぞれのウィンドウには、専用のコールバック関数が必要なんです。
それぞれのウィンドウの個別のメッセージをそのウィンドウ専用に処理するコールバック関数です。

お分かりでしょうか?


今回は、ウィンドウは一つだけ作成するので、コールバック関数も一つです。
それが、「WndProc」という名前の関数なんです。
ちなみに、「WndProc」のアドレスはちゃんとウィンドウに登録してありますよ。


【コールバック関数のパラメータ】


コールバック関数のパラメータ(引数)は、4つです。

ちょっと最初はとっつきにくいでしょうが、

(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp)

この4つのパラメータが渡されます。

ちょっと分かりにくい型がならんでますよね。

HWND hWnd
UINT msg
WPARAM wp
LPARAM lp

この4つ。
慣れてしまうと、何て事はないのですが、最初はとっつきにくいと思うので、
解説しますと、

HWND hWnd

これは、HWND型。ウィンドウハンドル型です。

⇒おいおい!「型」って何だ???の方はこちら

ウィンドウの情報などを取得したり、ウィンドウを操作したり色々するのに必要なハンドルなんです。
ちょっとポインタと似た感じなのですが、ポインタとは違うと認識した方が良いです。(本当はポインタと同じですが)
あくまでハンドルです。
ウィンドウズのアプリケーションを作っていれば、すぐ慣れると思いますよ。

余りにも登場機会が多いので…

《ちょっと余談》

HWNDは、ウィンドウハンドルなのですが、結局はポインタなんです。でも、OSが管理する内部の情報のために、プログラマが参照する事が許されていません。
あくまで、各ウィンドウのオブジェクトを識別するためのものなのです。

(余談終わり)


UINT msg

これは、UINT型の変数「msg」の宣言ですが、UINT型とは符号なし32bit整数と言う意味です。要するに正の整数と言う意味ですね。

この変数「msg」には、実際のウィンドウメッセージが渡されます。

私たちは、この「msg」の受け取った整数値を調べることにより、ウィンドウにユーザーがどんな操作をしたか分かります。

「msg」の値に応じた処理をプログラムする事で、アプリケーションに機能を付けていくのです。
この作業が最もメインな作業となる事でしょう。


WPARAM wp
LPARAM lp

この2つのパラメータは、今は気にしなくて良いと思います。
「msg」には、メッセージを識別する値。そして、WPARAM型の「wp」とLPARAM型の「lp」に何らかのデータやパラメータを加えることがあるのです。

メッセージによっては、パラメータがある事があると言うわけです。
これは、必要な時に使ってみて理解するのが好ましいと思います。

今の段階では、こんなパラメータがあるんだなと思っておいて下さい。


【最低限の覚える事】


HWND hWnd
UINT msg

この2つのパラメータの事が、なんとなく分かれば良いと思います。

HWND hWnd これは、ウィンドウハンドル

UINT msg これは、メッセージが渡されます。

これで、最低限の事は出来るのです。


【コールバック関数をもう一度見てみましょう】




コールバック関数は分かったけど、関数の内部に色々書いてありますね。




これです。

switch(msg)

と書いてあって、なにやら書いてありますが、これは「switchステートメント」と言います。
変数「msg」は、ウィンドウメッセージが渡されて記憶されています。
記憶されている値は、整数です。

switchステートメントとは、()内の変数の値によって「条件分枝」を行う事が出来ます。
コードの書式は、




こんな書式です。
「テスト式」の部分の値によって、分枝します。
「式1」、「式2」の部分には 0や1などの整数値が入ります。

「テスト式」の値によって対応するサブステートメントが実行されます。
対応する値が存在しない場合は全て「default」の部分が実行されます。

分かりやすく書き直してみると、






こんな感じになります。なんとなくお分かりでしょうか?
あっ。ちなみに、自分でコレ書けるようにならなくて大丈夫ですよ。
どうせコピペだし、自然に書けるようになってくるし、学校の勉強ではないので、コレ見て意味が分かればOKです。


では、コールバック関数の「switch(msg)」に戻ります。





switch(msg)の中身は、

case WM_DESTROY:



default:

って言うのがありますよね。

「default」って言うのは、対応する条件が無かった場合全部ここを実行する部分なので気にしなくて大丈夫です。

WM_DESTROY

って言うのは何かと言いますと、ウィンドウを破棄するときに送信されるメッセージなんです。

簡単に言うと、ウィンドウの右上の「×ボタン」を押すとこのメッセージがコールバック関数に送信されるのです。

ちなみに、「WM_DESTROY」と言う文字には、「2」と言う値が割り当てられています。
どう言う事かと言いますと、

case WM_DESTROY:

と書くと、

case 2:

と書いたのと同じ意味なんです。
何で「WM_DESTROY」と書くかと言いますと、メッセージの内容が分かりやすいからです。
「2」とかの数値だと、何のメッセージの処理を書いた部分か分からなくなるんです。

「WM_DESTROY」だと、WMコレはウィンドウメッセージと言う意味。
ウィンドウの破棄のメッセージと言う意味だとなんとなく分かるように、このように書きます。

この、

case WM_DESTROY:

の部分には、

PostQuitMessage(0);

と書いてありますが、アプリケーションを終了するメッセージを送信する関数なんです。

ここの意味は、ウィンドウを閉じる操作をした場合は、アプリケーションを終了されると言うコードが書いてあるのです。


「default」の部分には、

return (DefWindowProc(hWnd , msg , wp , lp));

と書いてあります。

これは、OS管理する所のデフォルトのウィンドウのプロセスに戻ると言う命令です。
パラメータも受け取ったまま返してあります。


【結局何すれば良い?】


結局ですね、今まで見てきたコールバック関数って、書き換える必要なんてないんですよ。
書き加える事はあっても書き換える事は、最初はほとんどありません。

このまま使います。

もう一度、コールバック関数を見てみましょう。




実は、私達は「// メッセージ処理」とかかれたところに、
色々なウィンドウメッセージに応じた




こういう物を書き加えていくだけなんです。

ウィンドウメッセージは沢山あって、既に値が割り当てられていますが、
私達は、値についてはあまり意識しなくて大丈夫なのです。





せっかくだから、何かやってみましょう。

と言うわけで、ウィンドウを左クリックしたときに発生するメッセージを
追加してみましょう。

どこに追加するかと言いますと、

「// メッセージ処理」と書かれた部分に挿入する形で書きます。
それ以外は、全くいじらなくていいです。





追加したのは、




これですが、

「case WM_LBUTTONDOWN」これはわかりますよね。
左クリックした時に発生するメッセージを処理する所です。(ちなみに値は513ですが)

MessageBox(NULL , "左クリックしたよ\r\nHello World!\r\nじゃないよ!" , "楽しいトレンドニュース" , MB_OK);

これは、メッセージボックスを表示する関数です。これを実行すると

HelloWorld.jpg

こんなメッセージボックスが表示されます。



(これは書きかけです。まだ未完成です。ゴメンなさい…)




ウィンドウズ アプリケーションのプログラミング講座(楽しトレンド的な初心者向け) [ウィンドウズ アプリケーションのプログラミング講]

定期的に色々な人から「プログラム教えて」と言われます。
プログラム言語の知識のある方は、ちょっと戸惑うと思うのですが、

漠然と「プログラム教えて」と言われると、なんて言って良いのやら少々混乱するのですが、要するに「ウィンドウズのアプリケーション」が自分で作れるようになりたいという事なのでしょう。

と言っても、だんだんとこの手の質問にも慣れてくるので、私の方から
「要するにウィンドウズのアプリが自分で作れるようになりたいのでしょう?」と聞き返してみます。

すると、「そうそう♪そう言う事♪」とニコニコしながら答えます。

意外と、C言語やC++言語でのウィンドウズアプリケーション開発が出来るようになりたいと思っていらっしゃる方も多いのだと知り、ちょっと初心者向けの記事を書いてみようかなと思いました。


【全くの初心者の方が気をつけるべき事】


ウィンドウズアプリケーション開発をするに当たって、気をつけて欲しい事があるのですが、それは…


プログラミング」と「ウィンドウズアプリケーション開発」と言うものは、
全くの別物なんです。

これは、どういう事かと言いますと、
「ウィンドウズのアプリケーション」と言うものは、何かのプログラム言語を利用して開発するものであって、

C++言語を勉強する = ウィンドウズのアプリケーション開発

とは違うのです。

ウィンドウズのアプリケーションを「C++言語を利用して開発する」と言う言い方が正しいのです。

意味がお分かりでしょうか?

本来は、C++言語を勉強した後にウィンドウズのアプリケーションの開発の仕方を勉強するのが通常です。

とは言え、ウィンドウズのアプリケーション開発がしたい人に先に「C++」の勉強を進めても多分、挫折してしまう人が多いと思うので、可能な限り同時進行出来るようにしたいと思います。(可能なのだろうか…)

まぁ…必要なことを必要な時に少しづつ解説しながら進めていきたいと思います。

でも、あまり細かく解説しているとゴチャゴチャしすぎて余計にワケが分からなくなってしまうと思うので、必要最低限の解説にしたいと思いますので、細かくはご自分で色々なサイト等で勉強して下さいね。

と言うわけで、いきなり本題に入ります。


【いざ!ウィンドウを作る!】


通常は、「Hello World!」を表示するプログラムから入るのがプログラム言語入門の「おやくそく」です。

しかし、面白くないので飛ばします。

後で自分でやってみてください。

私は、いまだにコンパイラは「Visual C++ 2003」を使っているのですが、
無料の物を手に入れて使ってくださいね。

VC++2003をお持ちの方は、そのままお使いいただけますが、違うバージョンや
フリーコンパイラをお使いの方は、その都度ちょっと手直しして頑張って下さいね。
(その方が勉強になります)

ウィンドウズのアプリケーションを作る場合って言うのは、

「ウィンドウ」
「メニュー」
「ボタン」
「その他のコントロール」
「名前を付けて保存などのダイアログ」

他にも沢山の機能がありますが、全部OSから借りてくるんですよ。
そうそう、全部ウィンドウズっていうOSが持っていて、借りてきて使うんです。

だから、私たちプログラマは「その機能の使い方」に従ってプログラムを書くだけなんです。

簡単でしょう??

要するに、「ウィンドウを表示」したい場合は、ウィンドウをOSから借りてきます。
ウィンドウを借りる手続きを「決まり通り」にプログラムすれば、ウィンドウを借りることができます。

沢山ある機能の内、使いたい機能の「使い方」を調べて、その通りにプログラムを書くのです。それだけです。

そして、ほとんどの場合は使う機能は、ほぼ決まっていて、すぐに覚えてしまいます。
覚えられなくても、メモ帳などで保存しておけば後でコピペとかで使えるので大丈夫なんです。やってみれば分かりますご安心下さい。


《実践あるのみ!》


まず、コンパイラで「空のファイル」を作ってください。
(作り方はそれぞれのマニュアル等で調べて下さいね)

「空のファイル」なので、他の機能は全く必要ありません。

「ファイル名」は、何でも良いですが、私はあえて「Main.cpp」としました。

そこに下のコードをコピペしましょう。

※テキストエリア内で「Ctrl+A」で全て選択です。
※「Ctrl+C」でコピー
※「Ctrl+V」でペースト





このコードを「Main.cpp」にペーストしてコンパイル後に実行すれば、
普通にウィンドウが表示されます。

と言っても、メニューもないし何もない真っ白なウィンドウが表示されるだけの
味気ないものなのですが、全てはこのコードに追加して好きなアプリケーションを
作っていくのです。

終了する場合は、メニューがないので「右上の×」で終了して下さい。

何らかのエラーになる場合は、コンパイラに合わせて手直しして下さい。


私がアプリケーションを作る場合も、最初はこのコピペから始まります。
なぜかと言いますと、ウィンドウズのアプリケーションって、ほとんどの場合は構造が同じなんですよ。

まず、ウィンドウが一つあってメニューがあって…

のように最初の部分ってほとんど同じです。

同じコードを毎回書くのが面倒クサイので、メモ帳に保存しておいてコピペで使います。
多少の仕様の違いがあれば、ちょっと手を加えるだけで大丈夫なので、イチイチ不要な手間をかけません。


最初は、たった今コピペしたこのコードの意味はわからなくて大丈夫です。
後から細かく解説しますが、この基本となるコードの意味が分からなくてもアプリケーションの開発は出来るので、分かってきたら後から細かく意味を理解していけば良いと思いますよ。

だって、理解できても毎回コピペ使うわけだし、理解するのは必要になってからで十分だと思います。


アプリケーション開発で必要なのは、コードの一番下の部分です。





この部分です。

この「ウィンドウプロージャ」と呼ばれる部分は、必要不可欠な関数で、「コールバック関数」と呼ばれます。

この「コールバック関数」とは、表示したウィンドウからの「メッセージ」を受け取る関数で、マウス操作などウィンドウに操作を加えた場合は、全てこの関数で受け取ることが出来るのです。

・マウスでクリックした
・メニューの「新規作成」を選択した
・メニューの「終了」を選択した
・メニューバーの「上書き保存」のボタンをクリックした

その他の操作も全部メッセージとして受け取ることが出来ます。

そして、それら「メッセージ」には、全てに「番号」が付いていて、
その番号を調べる事によって「何の操作をしたのか」がわかるようになっています。


要するに、私たちプログラマは、この「コールバック関数」に
「ウィンドウからのメッセージ」に応じたコードを書いていく事が主な作業となるのです。

だから、私たちはほとんど「コールバック関数」へのコードの追加の作業をやっている時間が最も長いのです。

まずは、この「コールバック関数」の部分の事を勉強する事にしましょう♪


今回は、この辺にして
次回は実際に「コールバック関数」に少々手を加えていきたいと思います。

すると、ウィンドウズのアプリケーションがどのようの作られていくのか分かってくると思います。


今回は「序章」的な感じなので第0回とでもしておきましょうか。
次回、第一回へ続く。



ウィンドウズ アプリケーションのプログラミング講 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。