InitApp関数内のGetStockObject関数で
ウィンドウの背景色を変更できる。
// ウィンドウの背景(黒に設定)
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);《定義できる色(
wingdi.hで定義されているブラシの色)》
ブラシの種類 色 DKGRAY_BRUSH ダークグレイ GRAY_BRUSH グレイ LTGRAY_BRUSH ライトグレイ WHITE_BRUSH 白 BLACK_BRUSH 黒 NULL 最初に表示したときの下の画像をそのまま背景にする(中空)
CreateWindow関数の第6,7引数に横幅、高さをそれぞれ指定することにより、ウィンドウの大きさを制御する。
「CW・・・」はデフォルト値で、通常640×480ピクセルのウィンドウが表示される。《例1》任意の大きさにする
/* ウィンドウクラスの登録ができたので、ウィンドウを生成する */ hWnd = CreateWindow( szWinName, // ウィンドウクラスの名前 "Skeleton 背景を黒に", // ウィンドウタイトル WS_OVERLAPPEDWINDOW, // ウィンドウスタイル CW_USEDEFAULT, // ウィンドウの左角X座標(Windowsに任せる) CW_USEDEFAULT, // ウィンドウの左角Y座標(Windowsに任せる)320, // ウィンドウの幅(320に固定)240, // ウィンドウの高さ(240に固定)HWND_DESKTOP, // 親ウィンドウ(なし) NULL, // メニュー(なし) hThisInst, // このプログラムのインスタンスのハンドル NULL // 追加引数(なし) );《例2》常にその解像度で最大の大きさにする
RECT rcRect;←InitAppの最初で宣言/* ディスクトップの大きさを取得 */←CreateWindow関数の直前に追加hWnd = GetDesktopWindow(); // デスククトップのハンドルを取得 GetWindowRect(hWnd, &rcRect); // デスクトップの矩形を得る(left,topは常に0) /* ウィンドウクラスの登録ができたので、ウィンドウを生成する */ hWnd = CreateWindow( szWinName, // ウィンドウクラスの名前 "Skeleton 背景を黒に", // ウィンドウタイトル WS_OVERLAPPEDWINDOW, // ウィンドウスタイル CW_USEDEFAULT, // ウィンドウの左角X座標(Windowsに任せる) CW_USEDEFAULT, // ウィンドウの左角Y座標(Windowsに任せる)rcRect.right, // デスクトップの幅rcRect.bottom, // デスクトップの高さHWND_DESKTOP, // 親ウィンドウ(なし) NULL, // メニュー(なし) hThisInst, // このプログラムのインスタンスのハンドル NULL // 追加引数(なし) );
CreateWindow関数の第4,5引数に表示位置のX座標、Y座標をそれぞれ指定することにより、ウィンドウの表示位置を制御する。
「CW・・・」はデフォルト値。《例1》任意の位置へ表示する
/* ウィンドウクラスの登録ができたので、ウィンドウを生成する */ hWnd = CreateWindow( szWinName, // ウィンドウクラスの名前 "Skeleton 背景を黒に", // ウィンドウタイトル WS_OVERLAPPEDWINDOW, // ウィンドウスタイル0, // ウィンドウの左角X座標(一番左)0, // ウィンドウの左角Y座標(一番上)CW_USEDEFAULT, // ウィンドウの幅(Windowsに任せる) CW_USEDEFAULT, // ウィンドウの高さ(Windowsに任せる) HWND_DESKTOP, // 親ウィンドウ(なし) NULL, // メニュー(なし) hThisInst, // このプログラムのインスタンスのハンドル NULL // 追加引数(なし) );《例2》常に画面の中央へ表示する
// マクロの定義←includeの次に指定#define WINDOW_WIDTH 640 // ウィンドウの幅 #define WINDOW_HEIGHT 480 // ウィンドウの高さ RECT rcRect;←InitAppの最初で宣言/* ディスクトップの大きさを取得 */←CreateWindow関数の直前に追加hWnd = GetDesktopWindow(); // デスククトップのハンドルを取得 GetWindowRect(hWnd, &rcRect); // デスクトップの矩形を得る(left,topは常に0) /* ウィンドウクラスの登録ができたので、ウィンドウを生成する */ hWnd = CreateWindow( szWinName, // ウィンドウクラスの名前 "Skeleton 背景を黒に", // ウィンドウタイトル WS_OVERLAPPEDWINDOW, // ウィンドウスタイル(rcRect.right - WINDOW_WIDTH) / 2, // 画面中央の左角X座標(rcRect.bottom - WINDOW_HEIGHT) / 2, // 画面中央の左角Y座標WINDOW_WIDTH, // ウィンドウの幅 WINDOW_HEIGHT, // ウィンドウの高さ HWND_DESKTOP, // 親ウィンドウ(なし) NULL, // メニュー(なし) hThisInst, // このプログラムのインスタンスのハンドル NULL // 追加引数(なし) );
アイコンには次の2種類がある。
- 1.ラージアイコン
- デスクトップやエクスプローラ上に表示されるアイコン
- 2.スモールアイコン
- 実行時のタスクバーやタイトルバー上に表示されるアイコン
スケルトンプログラムでは、システムが用意したアイコンを使うよう設定してある。
/* ウィンドウクラスを定義する */ ・ ・ wc.hIcon = LoadIcon(hThisInst,IDI_APPLICATION); // ラージアイコン wc.hIconSm = LoadIcon(hThisInst,IDI_WINLOGO); // スモールアイコン ・ ・《POINT》LoadIcon関数
アイコンオブジェクト = LoadIcon(インスタンス名, リソース名); オリジナルアイコンを作成し、利用するには次の作業が必要。
- アイコンをリソースとしてプロジェクトに組み込む。
「挿入」→「リソース」を選択し、「リソースのタイプ」ウィンドウでIconを選択して「新規作成」ボタンをクリック。- エディタが開くので、アイコンを作成する。
- アイコンリソース名をデフォルトで指定している名前からダブルクォーテーションを付けた
"XXXXXX"の形(例、"ICON")に変更する。リソースを右クリックし、プロパティを開き、IDを変更する。(デフォルトの名前を使うのはプログラム的に面倒になる)- リソースファイルを保存。
「保存」ボタンをクリックし、「Script1.rc」という名前で保存。- 作成したりソースをプロジェクトへ追加。
「プロジェクト」→「プロジェクトへ追加」→「ファイル」→「ファイルの選択」で、作成したリソースファイル「Script1.rc」とヘッダファイル「resource.h」を選択。- リソースに追加したアイコンを使うよう、プログラムを修正。
#include "resource.h"・ ・ /* ウィンドウクラスを定義する */ ・ ・ wc.hIcon = LoadIcon(hThisInst,"ICON"); // ラージアイコン wc.hIconSm = LoadIcon(hThisInst,"ICON"); // スモールアイコン ・ ・
- ラージアイコン、スモールアイコンでそれぞれ違うアイコンを使うこともできる。
- アイコン生成ソフトなどで作成したアイコンを使う場合、作成したアイコンをプロジェクトのフォルダに移動後、リソースの追加でインポートする。
(1)ウィンドウ内に文字列を表示する
//============================================================================= // Windows関数 //============================================================================= LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {HDC hdc; // デバイスコンテキストPAINTSTRUCT ps; // 再描画用構造体char str[] = "Hello World"; // 表示文字列switch (message) {case WM_PAINT:hdc = BeginPaint(hWnd, &ps); // 描画開始TextOut(hdc, 1, 1, str, strlen(str));EndPaint(hWnd, &ps); // 描画終了break;case WM_DESTROY: // 閉じるボタンをクリックした時 PostQuitMessage(0); // WM_QUITメッセージを発行 break; default: // 上記以外のメッセージはWindowsへ処理を任せる return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
- ウィンドウ内に何かを表示させるときは「WM_PAINT」メッセージ処理で行う。
- WM_PAINTメッセージは再描画についての対応処理が含まれており、他のウィンドウによる表示妨害に対しても対応済みである。
- string.hはwindows.hでインクルード済みなので、ソース内でインクルードする必要はない?
(2)マウスクリックに対応する(左ボタンクリックで1文字表示)
(1)のプログラムを改造し、マウスの左ボタンをクリックすると表示文字列がy方向(縦)に下がって表示されるようにする。
//============================================================================= // Windows関数 //============================================================================= LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; // デバイスコンテキスト PAINTSTRUCT ps; // 再描画用構造体 char str[] = "Hello World"; // 表示文字列static int y = 0; // 表示座標switch (message) {case WM_LBUTTONDOWN:if (y < 430)y += 18;elsey = 0;InvalidateRect(hWnd, NULL, 1);break;case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // 描画開始 TextOut(hdc,0,y, str, strlen(str)); EndPaint(hWnd, &ps); // 描画終了 break; case WM_DESTROY: // 閉じるボタンをクリックした時 PostQuitMessage(0); // WM_QUITメッセージを発行 break; default: // 上記以外のメッセージはWindowsへ処理を任せる return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
- 描画処理はWM_PAINTで行う。
- 左ボタンが押されたら
という処理をさせる。
- 表示位置を設定
- InvaridateRect関数を発行することにより、WM_PAINTメッセージを発行させる
(3)キーボード入力に対応する
(1)のプログラムを変更し、最初に文字「+」を表示し、カーソルキーを押すことによりその文字を上下左右に動かすプログラムを作る。
//============================================================================= // Windows関数 //============================================================================= LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; // デバイスコンテキスト PAINTSTRUCT ps; // 再描画用構造体 char str[] ="+"; // 表示文字列static int x = 0, y = 0;switch (message) {case WM_KEYDOWN:switch (wParam){case VK_LEFT:x -= 5;if (x < 0)x = 0;break;case VK_RIGHT:x += 5;if (620 < x)x = 620;break;case VK_UP:y -= 5;if (y < 0)y = 0;break;case VK_DOWN:y += 5;if (435 < y)y = 435;break;}InvalidateRect(hWnd, NULL, 1);break;case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // 描画開始 TextOut(hdc,x,y, str, strlen(str)); EndPaint(hWnd, &ps); // 描画終了 break; case WM_DESTROY: // 閉じるボタンをクリックした時 PostQuitMessage(0); // WM_QUITメッセージを発行 break; default: // 上記以外のメッセージはWindowsへ処理を任せる return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
- 描画処理はWM_PAINTで行う。
- カーソルキーが押されたら
という処理をさせる。
- 方向に従って表示位置を設定
- InvaridateRect関数を発行し、WM_PAINTメッセージを発行させる
※「VK_LEFT」「VK_RIGHT」などは
仮想キーコードといい、標準ライブラリに定義されている。詳しくは用語集の「仮想キーコード」の項を参照。(4)1文字を一定時間ごとに移動させる(タイマーの使用)
(1)のプログラムを変更し、一定時間ごとに文字「+」を移動させる。
// マクロの定義#define WS_WIDTH 630 // ウィンドウの大体の横幅#define WS_HEIGHT 460 // ウィンドウの大体の高さ#define TIMER_ID 1 // タイマーID#define TIMER_RATE 100 // タイマーの間隔(ミリ秒)#define SPEED 10 // 文字の移動量/* タイマーをセットする */SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL); ←WinMain関数のメッセージループの前に追加/* タイマーを削除する */KillTimer(hWnd, TIMER_ID); ←WinMain関数のメッセージループの後に追加//============================================================================= // Windows関数 //============================================================================= LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; // デバイスコンテキスト PAINTSTRUCT ps; // 再描画用構造体 char str[] ="+"; // 表示文字列static int x = 0, y = 0;// 表示座標 switch (message) {case WM_TIMER:x += SPEED;if (WS_WIDTH < x)x = 0;InvalidateRect(hWnd, NULL, TRUE);break;case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // 描画開始 TextOut(hdc,x,y, str, strlen(str)); EndPaint(hWnd, &ps); // 描画終了 break; case WM_DESTROY: // 閉じるボタンをクリックした時 PostQuitMessage(0); // WM_QUITメッセージを発行 break; default: // 上記以外のメッセージはWindowsへ処理を任せる return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
- 描画処理はWM_PAINTで行う。
- 一定時間が経過したら
という処理をさせる。
- 表示位置を設定
- InvaridateRect関数を発行し、WM_PAINTメッセージを発行させる