goo blog サービス終了のお知らせ 

プログラミングのメモ帳(C/C++/HSP)

日々のプログラミングで気づいた点や小技集を紹介します。(Windows 10/XP/Vista、VC2017、HSP)

第5章 ウインドウのプロシージャ関数

2012年03月10日 05時30分05秒 | 無料で学べる講座

このページはゲームループの基礎講座シリーズの1つです。
今回は第5章の「ウインドウのプロシージャ関数」について説明します。(戻る)

プロシージャ関数

//------------------------------------------------
// ウインドウのプロシージャ関数(OK)
//------------------------------------------------
static LRESULT CALLBACK mainWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    switch ( uMsg ){
        CASE WM_CREATE:
            /*
            初期化
            */
        CASE WM_CLOSE:
            /*
            後始末
            */
            DestroyWindow( hWnd );
        CASE WM_DESTROY:
            PostQuitMessage( 0 );
        CASE WM_PAINT:
        {
            PAINTSTRUCT     ps;
            HDC             hDC;
            
            hDC = BeginPaint( hWnd, &ps );
            /*
            描画処理
            */
            EndPaint( hWnd, &ps );
        }
        CASE WM_ENDSESSION:         PostMessage( hWnd, WM_CLOSE, 0, 0 );
        CASE WM_LBUTTONDOWN:        SendMessage( hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0 );
        CASE WM_LBUTTONDBLCLK:      SetWindowPos( hWnd, HWND_TOPMOST,   0, 0, 0, 0, (SWP_NOMOVE|SWP_NOSIZE) );
        CASE WM_RBUTTONDBLCLK:      SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, (SWP_NOMOVE|SWP_NOSIZE) );
        DEFAULT:                    return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }
    return 0;
}

ソース・ファイルに組み込む

//------------------------------------------------------------------------------
// 第5章 ウインドウのプロシージャ関数
//------------------------------------------------------------------------------
#include <tchar.h>
#include <Windows.h>

//------------------------------------------------
// break 付きのキーワード(OK)
//------------------------------------------------
#define CASE        break;case
#define DEFAULT     break;default

//------------------------------------------------
// 記号定数(OK)
//------------------------------------------------
#define SCREEN_STYLE        (WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME|WS_MAXIMIZEBOX))
#define SCREEN_WIDTH        (640)       // スクリーンの横幅(32ドット×20個)
#define SCREEN_HEIGHT       (480)       // スクリーンの高さ(32ドット×15個)

//------------------------------------------------
// 記号定数(OK)
//------------------------------------------------
#define ERRMSG_TITLE        TEXT("WinMain関数")
#define ERRMSG_WINREG       TEXT("ウインドウ・クラスが登録できません。")
#define ERRMSG_CREATE       TEXT("ウインドウが作成できません。")

//------------------------------------------------ // ウインドウのプロシージャ関数(OK) //------------------------------------------------ static LRESULT CALLBACK mainWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ){ CASE WM_CREATE: /* 初期化 */ CASE WM_CLOSE: /* 後始末 */ DestroyWindow( hWnd ); CASE WM_DESTROY: PostQuitMessage( 0 ); CASE WM_PAINT: { PAINTSTRUCT ps; HDC hDC; hDC = BeginPaint( hWnd, &ps ); /* 描画処理 */ EndPaint( hWnd, &ps ); } CASE WM_ENDSESSION: PostMessage( hWnd, WM_CLOSE, 0, 0 ); CASE WM_LBUTTONDOWN: SendMessage( hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0 ); CASE WM_LBUTTONDBLCLK: SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, (SWP_NOMOVE|SWP_NOSIZE) ); CASE WM_RBUTTONDBLCLK: SetWindowPos( hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, (SWP_NOMOVE|SWP_NOSIZE) ); DEFAULT: return DefWindowProc( hWnd, uMsg, wParam, lParam ); } return 0; }
//------------------------------------------------ // ウインドウ・クラスの登録(OK) //------------------------------------------------ static ATOM funcWindowClass( HINSTANCE hInstance, LPCTSTR lpClassName ) { WNDCLASSEX wcex = { 0 }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_DBLCLKS; wcex.lpfnWndProc = mainWindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wcex.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); wcex.hCursor = LoadCursor( NULL, IDC_ARROW ); wcex.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH ); wcex.lpszMenuName = NULL; wcex.lpszClassName = lpClassName; return RegisterClassEx( &wcex ); } //------------------------------------------------ // ウインドウ・サイズの設定(OK) //------------------------------------------------ static VOID funcSetClientSize( HWND hWnd, LONG sx, LONG sy ) { RECT rc1; RECT rc2; GetWindowRect( hWnd, &rc1 ); GetClientRect( hWnd, &rc2 ); sx += ((rc1.right - rc1.left) - (rc2.right - rc2.left)); sy += ((rc1.bottom - rc1.top) - (rc2.bottom - rc2.top)); SetWindowPos( hWnd, NULL, 0, 0, sx, sy, (SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE) ); } //------------------------------------------------ // ウインドウの作成(OK) //------------------------------------------------ static HWND funcCreateWindow( HINSTANCE hInstance, LPCTSTR lpClassName, LPCTSTR lpTitleName, int nCmdShow ) { HWND hWnd = CreateWindowEx( 0, // 拡張ウインドウ・スタイル lpClassName, // ウインドウのクラス名 lpTitleName, // ウインドウのタイトル名 SCREEN_STYLE, // ウインドウのスタイル CW_USEDEFAULT, // ウインドウの横軸位置 CW_USEDEFAULT, // ウインドウの縦軸位置 CW_USEDEFAULT, // ウインドウの横幅 CW_USEDEFAULT, // ウインドウの高さ NULL, // 親ウインドウのハンドル NULL, // メニューバーのハンドル hInstance, // インスタンスのハンドル NULL ); // ウインドウ作成のデータ if ( hWnd != NULL ){ funcSetClientSize( hWnd, SCREEN_WIDTH, SCREEN_HEIGHT ); ShowWindow( hWnd, nCmdShow ); UpdateWindow( hWnd ); } return hWnd; } //------------------------------------------------ // メイン関数(OK) //------------------------------------------------ extern int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { LPCTSTR lpClassName = TEXT("Lesson5WndClass"); LPCTSTR lpTitleName = TEXT("第5章 ウインドウのプロシージャ関数"); MSG Msg; // ウインドウ・クラスの登録 if ( funcWindowClass(hInstance,lpClassName) == 0 ){ MessageBox( NULL, ERRMSG_WINREG, ERRMSG_TITLE, (MB_OK|MB_ICONERROR) ); return -1; } // ウインドウの作成 if ( funcCreateWindow(hInstance,lpClassName,lpTitleName,nCmdShow) == NULL ){ MessageBox( NULL, ERRMSG_CREATE, ERRMSG_TITLE, (MB_OK|MB_ICONWARNING) ); return -2; } // メッセージ・ループ while ( GetMessage(&Msg,NULL,0,0) > 0 ){ TranslateMessage( &Msg ); DispatchMessage( &Msg ); } UNREFERENCED_PARAMETER( hPrevInstance ); UNREFERENCED_PARAMETER( lpCmdLine ); return Msg.wParam; } //------------------------------------------------------------------------------ // End of Lesson5.cpp //------------------------------------------------------------------------------

上記の 着色された場所 がウインドウ・プロシージャの mainWindowProc 関数の部分です。

雛型ウインドウとは

アプリケーションを作成する上で基本的なウインドウを雛型ウインドウと呼びます。
また、その基本ソースコードをスケルトン・プログラムと呼びます。
上記に紹介してるソース・ファイルこそ雛型ウインドウを表示するためのスケルトン・プログラムです。

このスケルトン・プログラムは、ゲーム以外にも利用できるソースコードですが、
使うときには記号定数の SCREEN_STYLESCREEN_WIDTHSCREEN_HEIGHT などを修正する必要があるかもしれません。
また、funcCreateWindow 関数内で使ってる funcSetClientSize 関数を取り除くことで
CW_USEDEFAULT 定数で決められた既定のウインドウ・サイズが有効になります。

どの道、雛型ウインドウを表示するためのスケルトン・プログラムは一部を修正して使い回します。
それでは、これで第5章の「ウインドウのプロシージャ関数」についての説明は終わります。(つづく)

←前へ] [目次] [次へ→

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 第4章 ウインドウのサイズ | トップ | 第6章 キャラクタの作成 »
最新の画像もっと見る

コメントを投稿

サービス終了に伴い、10月1日にコメント投稿機能を終了させていただく予定です。

無料で学べる講座」カテゴリの最新記事