2012年6月5日火曜日

Win32APIプログラミングの部分

DirectXによる描画を行わず、ただ単に空白のウインドウを出すだけならばDirectX関係の一切のコードは不要です。
ここではウインドウズの基本的なコードが何なのかを示すため、チュートリアル1からDirectXにかかわる部分を除いてみました。また、一部改行したりコメントを付けました。

#include <windows.h>
#include "resource.h"
//---------------------------------------
// Global Variables
//----------------------------------------
HWND g_hWnd = NULL;

//-----------------------------------------
// Forward declarations
//------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );

//------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
UNREFERENCED_PARAMETER( hPrevInstance );
UNREFERENCED_PARAMETER( lpCmdLine );

if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;



// Main message loop
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}

}

return ( int )msg.wParam;
}


//--------------------------------------------
// Register class and create window
//------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );//この構造体のサイズ
wcex.style = CS_HREDRAW | CS_VREDRAW;//ウインドウスタイル
wcex.lpfnWndProc = WndProc;//ウインドウプロシージャ
wcex.cbClsExtra = 0; //ウインドウクラスに付加したいメモリ
wcex.cbWndExtra = 0;//ウインドウに付加したいメモリ
wcex.hInstance = hInstance;//インスタンスハンドル
wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );//アイコン
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );//カーソル
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );//背景色
wcex.lpszMenuName = NULL;//メニュー
wcex.lpszClassName = L"TutorialWindowClass";//ウインドウクラスの名前
wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );//アイコン(小)
if( !RegisterClassEx( &wcex ) )
return E_FAIL;

// Create window
RECT rc = { 0, 0, 680, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow(
L"TutorialWindowClass", // ウインドウクラス名
L"Direct3D 11 Tutorial 1: Direct3D 11 Basics", // ウインドウタイトル
WS_OVERLAPPEDWINDOW, // ウインドウスタイル
CW_USEDEFAULT, // X座標の初期値
CW_USEDEFAULT, // Y座標の初期値
rc.right - rc.left, // 幅の初期値
rc.bottom - rc.top, // 高さの初期値
NULL, // 親ウインドウのハンドル
NULL, // ウインドウメニューのハンドル
hInstance, // インスタンスハンドル
NULL ); // 作成パラメータ
if( !g_hWnd )
return E_FAIL;

ShowWindow( g_hWnd, nCmdShow ); //ウインドウを表示する

return S_OK;
}


//--------------------------------------------
// Called every time the application receives a message
//--------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;

switch( message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;

case WM_DESTROY:
PostQuitMessage( 0 );
break;

default:
return DefWindowProc( hWnd, message, wParam, lParam );
}

return 0;
}


これを実行すると空白のウインドウが現れると思います。
これはいわゆるwin32APIによるプログラミングの部分なので詳しく知りたい場合はwin32APIwindowsプログラミングウインドウズAPIWindowsAPI等でググれば良いでしょう。MS公式の概要の説明もあります。

当サイトでも簡単に説明する・・・つもりが一連のチュートリアルに無関係な細かい部分まで書いてしまいました。まずはじめに大まかな話をするとコードは大きく3つの関数に分かれています。wWinMain()InitWindow()WndProc()の3つです。プログラムは最初にwWinMain()から始まります。その中で2つ目の関数InitWindow()が呼ばれます。この2つ目の関数InitWindow()の中でウインドウが作られます。最後の関数WndProc()はコード上の何処からも呼ばれていませんが、ウインドウをいじった時やマウス、キーが入力された時など、いわゆるイベント発生時にシステム側から自動的に呼ばれます。そこでアプリケーションにどのような動作をさせたいかを記述する事が出来ます。

以下のリンクでこれら3つの関数の中身を説明しようと思います。しかし3Dプログラミングとは関係ない内容が多いので、とりあえず普通のウインドウが出てくれればそれで良いよ・・・という人は読み飛ばすのもありでしょう。

wWinMain(エントリーポイント)

プログラムの入り口となる関数であり、内部でInitWindow()を呼び出してウインドウを構築し、その後メッセージループに入ります。

InitWindow(ウインドウの作成)

ウインドウクラスを登録してからウインドウを作ります。つまりWNDCLASSEX構造体をRegisterClassEx( &wcex )で登録してCreateWindow関数を呼びます。各パラメータの解説をしています。アイコンの差し替え方にも触れます。・・・普通のウインドウが作れれば良いという人にとってはかなり冗長な内容かも知れません。

WindProc(ウインドウプロシージャ)

ウインドウプロシージャの説明です。キーボードやマウスの処理、エスケープキーによるプログラムの終了の方法についても書いてみました。

0 件のコメント: