![]() 【ご購入はこちらへ】 |
本書は C 言語の習得者が Windows 上で動作するグラフィカルなゲームアプリケーションを開発できるようになるまでを導く、ゲーム開発と Windows API のための学習書です。 複雑な C++ 言語は使わずに、C 言語だけで Windows 上で動作するウィンドウアプリケーションの開発方法をシンプルに、サンプルコードを交えながら解説します。 Windows 上で動作するグラフィカルなゲームプログラムを作成するには、Windows API (Windows が提供しているウィンドウなどを制御するための関数群)を理解しなければなりません。 本書では、ゲーム開発に必要な API や、応用可能と思われる API を中心にウィンドウアプリケーションの開発方法を解説するため、Windows プログラミング入門者がスマートにゲーム開発にまでたどり着くことができます。 通常の Windows API 入門書籍では扱われないような、部分透明や半透明などのビットマップ処理方法なども、サンプルコード付きで解説しています。 |
|---|
現在見つかっている本書の技術的な誤り、誤植の修正を以下に公開します。
| 頁 | 原文 | 訂正 |
|---|---|---|
| 16 表1.3 | UNICODE が定義されていれば PSTR、そうでなければ PWSTR | UNICODE が定義されていれば PWSTR、そうでなければ PSTR |
| 17 表1.3 | UNICODE が定義されていれば PCSTR、そうでなければ PCWSTR | UNICODE が定義されていれば PCWSTR、そうでなければ PCSTR |
| 17 表1.3 | LCPTSTR | LPCTSTR |
| 32 表1.7 | ウィンドウが再描画されたときに発生 | ウィンドウの描画が必要になったときに発生 |
| 79 | ペンのスタイルとしては実践、破線、点線などが | ペンのスタイルとしては実線、破線、点線などが |
| 268 | 100回程度しかWN_TIMERメッセージを発行できないのです | 100回程度しかWM_TIMERメッセージを発行できないのです |
| 297 | NULL , TEXT("m1.bmp") , IMAGE_BITMAP , | NULL , TEXT("fore1.bmp") , IMAGE_BITMAP , |
| 297 | NULL , TEXT("m2.bmp") , IMAGE_BITMAP , | NULL , TEXT("fore2.bmp") , IMAGE_BITMAP , |
| 332 | TruenPiece() | TurnPiece() |
| 332 | MovePiece(PIEVE_DOWN) | MovePiece(PIECE_DOWN) |
| 333 表9.1 | TruenPiece() | TurnPiece() |
| 修正前 1行目〜 |
|---|
#include <windows.h>
#define APP_NAME TEXT("Sample_MainWindow") |
| 修正後 1行目〜 |
#define _WIN32_WINNT 0x0400
#include <windows.h>
#define APP_NAME TEXT("Sample_MainWindow") |
| 修正理由 |
| 一部の開発環境を除いて、識別子 WM_MOUSEWHEEL が宣言されていないという問題が発生します。WM_MOUSEWHEEL は winuser.h ヘッダで宣言されていますが、#define _WIN32_WINNT 0x0400 が宣言されていないと認識されません。 |
| 修正前 25行目〜 |
|---|
case WM_LBUTTONUP: SetWindowLong(hWnd , GWL_STYLE , WS_POPUP); ShowWindow(hWnd , SW_SHOW); return 0; case WM_RBUTTONUP: SetWindowLong(hWnd , GWL_STYLE , WS_OVERLAPPEDWINDOW); ShowWindow(hWnd , SW_SHOW); return 0; |
| 修正後 25行目〜 |
case WM_LBUTTONUP: SetWindowLong(hWnd , GWL_STYLE , WS_POPUP); SetWindowPos( hWnd , HWND_TOP , 0 , 0 , 0 , 0 , SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME | SWP_SHOWWINDOW ); return 0; case WM_RBUTTONUP: SetWindowLong(hWnd , GWL_STYLE , WS_OVERLAPPEDWINDOW); SetWindowPos( hWnd , HWND_TOP , 0 , 0 , 0 , 0 , SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME | SWP_SHOWWINDOW ); return 0; |
| 修正理由 |
| Windows XP より以前の Windows (98/Me/2000 など) で発生した不具合を解消しました。 ウィンドウデータの中には、キャッシュされており、SetWindowLong 関数を使って変更しても SetWindowPos 関数を呼び出すまでは有効にならないものもあります。 特に、フレームスタイルを変更した場合は、SWP_FRAMECHANGED フラグをセットして SetWindowPos 関数を呼び出すさなければ、キャッシュが正しく更新されません。 |
| 修正前 24行目〜 |
|---|
hBitmap = LoadImage( (HINSTANCE)GetWindowLong(hWnd , GWL_HINSTANCE) , BMPFILE , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE ); |
| 修正後 24行目〜 |
hBitmap = LoadImage( NULL , BMPFILE , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE ); |
| 修正理由 |
| ファイルイメージを読み込む場合は LoadImage() の最初の引数は NULL を指定します。 |
| 修正前 38行目 |
|---|
LRESULT CALLBACK WindowProc (
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
ThreadParam param;
DWORD dwID; |
| 修正後 38行目 |
LRESULT CALLBACK WindowProc (
HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
static ThreadParam param;
DWORD dwID; |
| 修正理由 |
| スレッド起動時に WindowProc 関数のローカル変数のポインタを引数に渡しますが、スレッド実行時に WindowProc のローカル変数が破棄されてしまった場合正常に動作しないことがあります。そのため、ローカル変数が破棄されないように static を宣言に追加します。 |
| 修正前 43行目 |
|---|
case WM_LBUTTONUP: if (ResumeThread(hThread) == 0) SuspendThread(hThread); return 0; |
| 修正後 43行目 |
case WM_LBUTTONUP: if (((LONG)ResumeThread(hThread)) <= 0) SuspendThread(hThread); return 0; |
| 修正理由 |
| システムによっては ResumeThread() 関数はサスペンドされていない hThread を渡すと失敗する可能性があります。そのため、ResumeThread() が失敗した場合もサスペンドするように記述した方が安全です。 |
| 修正前 24行目〜 |
|---|
/*フィールドのマスのテキスト表現*/
#define PIECE_FALSE TEXT("□")
define PIECE_TRUE TEXT("■") |
| 修正後 24行目〜 |
/*フィールドのマスのテキスト表現*/
#define PIECE_FALSE TEXT("□")
#define PIECE_TRUE TEXT("■") |
| 修正理由 |
| #define プロセッサディレクティブの # がありませんでした。このソースコードを修正しないままコンパイルした場合、コンパイルエラーが報告されます。付属の実行ファイルに問題はありません。 |
| 修正前 126行目〜 |
|---|
if (hBackBmp) {
HDC hBackDC = CreateCompatibleDC(hdc);
SelectObject(hBackDC , hBackBmp);
BitBlt(hdc , 0 , 0 , WND_WIDTH , WND_HEIGHT , hBackDC , 0 , 0 , SRCCOPY);
DeleteDC(hBackDC);
DeleteObject(hBackDC);
} |
| 修正後 126行目〜 |
if (hBackBmp) {
HDC hBackDC = CreateCompatibleDC(hdc);
SelectObject(hBackDC , hBackBmp);
BitBlt(hdc , 0 , 0 , WND_WIDTH , WND_HEIGHT , hBackDC , 0 , 0 , SRCCOPY);
DeleteDC(hBackDC);
} |
| 修正理由 |
| DeleteObject(hBackDC); は不要です。hBackDC は DeleteDC() 関数で削除されています。 |
本書の技術的な誤り、誤字脱字などが見つかれば third@fine.ocn.ne.jp までご連絡ください。
乱丁本、落丁本など、本の物理的な欠陥については WisdomSoft 及び赤坂玲音はサポートしておりません。