win32
//説明 //アプリケーション(.exe)実行でまず、呼び出される //2 int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) /* HINSTANCE hInst:実行中のアプリケーションを識別するための整数値を受け取るもの。(もっとも、一意に決められるものではない) HINSTANCE hPrevInst: 昔の名残 LPSTR lpCmdLine:コマンドライン int nCmdShow:メインウィンドウの最初の表示状態を表す値がここに格納される。 */ { //2−1 WNDCLASS wndcls; //ウインドウの初期状態、属性を登録する HWND hWnd; //ウインドウハンドル(ウィンドウを操作するにはウィンドウハンドルが 必要)整数値。識別するため。 MSG msg; //クリックとか、ユーザーがアクションを起こした時に必要になってくるもの。構造体で、 typedef struct tagMSG { HWND hwnd; UINT message; //メッセージ(たとえば、WM_QUIT,WM_PAINTなど) WPARAM wParam; //メッセージに属するパラメタ LPARAM lParam; //同じく。 DWORD time; //起きた時間 POINT pt; //起こった位置 } MSG , * PMSG; //という形になっている。 //2−2 //ウインドウクラスの登録 //2−3 //メイン・ウィンドウの作成 作成するだけで、本来ウィンドウを表示するための関数ではない。 WS_VISIBLEとかあるけど、それはまた別箇と //考える。 //2−4 //引数にしたがって,ウィンドウの初期表示状態を指定する //ShowWindowはnCmdShowがWinMainの第4引数と対応している。 //UpdateWindowはウィンドウの更新をする関数。起動時はすぐに更新する必要があるので、明示的に呼び出している。 //WM_PAINTメッセージをメッセージキューに送らず、直接送る。 ShowWindow( hWnd, nCmdShow); UpdateWindow( hWnd); /***********WM_QUITメッセージを受け取った場合以外、ループが延々と続く。***********/ //2−5 // メッセージ・ループ //GetMessageでメッセージキューからメッセージを取出し、msgにメッセージ情報が格納される。 //WM_QUIT以外のメッセージをうけとったときは1,WM_QUITのメッセージを受け取ったときは0となる。 /*補足*/ //GetMessageとPeekMessageの違いはメッセージキューが空の時ちがう。 //GetMessageはメッセージキューが空の時でも待機する。 //(よって、WM_QUITのメッセージを受け取らない限りはこのループは永久に続く!) //PeekMessageはメッセージキューが空の時に待機せず、while文を抜け出してしまう。 //PeekMessageはゲームプログラミング(アクション、シューティングなどの動きが大切なアプリケーション)に向いているといえる。 while( GetMessage( &msg, 0, 0, 0) ){ TranslateMessage(&msg); // DispatchMessage( &msg); } //PeekMessageを使いたい場合は、次のようにコードを書くとよい。 while (1) { //PM_NOREMOVEを指定すれば、キューからメッセージを取り出すことなく //メッセージの内容を見ることができる。 if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE) ) { if(msg.message) break; //WM_QUITのときだけwhile文を抜けて、アプリケーションを終了する。 DispatchMessage(&msg); } else { //アイドル時の処理を行う。 } } //TranslateMessage関数はキーボードのメッセージを文字メッセージに変換する関数。 //DispatchMessage関数はウインドウプロシージャーに送る。 //このばあいは、ウィンドウ・クラスのlpfnWndProcにWndProc関数(メッセージ処理関数)を登録したから、 //その関数に処理が移る。 /*補足*/ //以上はユーザーがクリックしたなど、システムでの動作により、messageが送られる仕組みであるが、 //アプリケーション自体がメッセージを送るようにしたいときはどうすればよいだろうか? //たとえば、ユーザーが右クリック->閉じるメッセージとか、最小化するメッセージを送りたい 時 //ユーザー名義のメッセージ(たとえば、この時だけファイルを操作していいですよというメッセージ)を送りたい 時など //そのときはPostMessageや、SendMessage関数を使用する。 //違いは、SendMessage関数はメッセージを直接(メッセージキューに追加せずに)送って、処理するのを見届ける関数。 //リアルタイムで操作を反映したいときに使うとよい。 //PostMessage関数はメッセージをメッセージキューに送るだけの関数。送るだけなので、そのメッセージが処理しないうちに、 //PostMessage関数が終わっていることがある(というかそのほうが多い) //Windowプログラムの仕組み(キューで受け取る)を考慮すれば、PostMessage APIを使うほうが望ましい。 //1 //1-1 //uMsg(メッセージ定数)を受け取って、それぞれの場合に処理される。 //1−2 case WM_DESTROY://右上の×ボタンが押されたときとかにこのメッセージがuMsgに格納される。 PostQuitMessage( 0); //WM_QUITメッセージをメッセージキューに追加する関数。引数にWM_QUITに通知したいデータを格納 return 0; } //1-3 // 処理しない(大部分の)メッセージはシステムに任せる return DefWindowProc( hWnd, uMsg, wParam, lParam); /***********WM_QUITメッセージを受け取った場合以外ループが延々と続く。***********/ //2-6 // WM_QUITメッセージのときは2-5のループを抜けるから、wParamをプログラムの終了コードにする。 return msg.wParam; //SendMessageのメッセージ送信に関連して… //一般的にメッセージはメッセージキューに送られるが、例外がいくつかあって、 //たとえば、UpdateWindow( hWnd);によるWM_PAINTメッセージの送信 //WM_ACTIVATE,WM_SETFOCUS,WM_SETCURSORメッセージ //SendMessage関数による、好きなメッセージの送信 //などがあげられる。
#include <windows.h> // ウィンドウ・クラス名 #define MYWNDCLSNAME "MyWindowClass" //1 LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //1−1 switch( uMsg){ //1−2 case WM_DESTROY: PostQuitMessage( 0); return 0; } // 処理しないメッセージはシステムに任せる①−3 return DefWindowProc( hWnd, uMsg, wParam, lParam); } //2 int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { //2−1 WNDCLASS wndcls; HWND hWnd; MSG msg; // ウィンドウ・クラスの登録 2−2 ZeroMemory( &wndcls, sizeof(wndcls) ); wndcls.lpfnWndProc = WndProc; wndcls.hInstance = hInst; wndcls.hIcon = LoadIcon( 0, IDI_APPLICATION); wndcls.hCursor = LoadCursor( 0, IDC_ARROW); wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND; //wndcls.hbrBackground = (BBRUSH)GetStockObject(WHITE_BRUSH);と書くことも。 wndcls.lpszClassName = MYWNDCLSNAME; //#define MYWNDCLSNAME "MyWindowClass" if( RegisterClass( &wndcls) == 0) return -1; // メイン・ウィンドウの作成 2−3 hWnd = CreateWindow( MYWNDCLSNAME, "My Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, NULL); if( hWnd == 0) return -2; // 引数にしたがって,ウィンドウの初期表示状態を指定する 2−4 ShowWindow( hWnd, nCmdShow); UpdateWindow( hWnd); // メッセージ・ループ 2−5 while( GetMessage( &msg, 0, 0, 0) ){ TranslateMessage(&msg); DispatchMessage( &msg); } // WM_QUITメッセージのwParamをプログラムの終了コードにする 2−6 return msg.wParam; }
stdafx.hは windows.h stdlib.h malloc.h memory.h tchar.h という5つのヘッダーファイルがインクルードされている。