窓を開く WinAPI Last update 1998.01.06
なにはともあれ、MFC は使わないで行こう!と、決めたからにはまずはAPIで窓を開かなければなりません。
さっそくですが、窓を開く手順です。基本的な流れは以下のようになります。

1.ウィンドウクラスを登録しWindowsに窓を作らせる
2.ループをまわして
3. Windowsからのメッセージを受け取りに行って
4.それに答える
5.最後にちゃんと後始末

とまぁ、これだけなのですが、それさえ出来れば立派なWindowsアプリケーションです。
でも、折角の(?)ゲームエンジンですから、Windowsからのメッセージを待って処理するってのも芸が無いですね。タイマーなんて不安定だしアイドル処理に時間を掛けるのもなんだし。
ってことで、ループのところにちょっとした細工を施します。これは一定周期で何かの処理をさせたいときには、とっても便利ですよ。3.のところが以下のようになります。

3.A Windowsからのメッセージを待つ
3.B その間に指定のタイミングで指定の関数を呼び出す

って感じになります。

そんなわけで、いかにサンプルコードを示します。一つの関数をあんまり大きくしたくないってのがあったりして、いきなり関数の数が5個になってしまいましたが。赤い文字のところがそれぞれの関数です。一応、これで窓を開かせることは出来ると思います。
また青い文字のところは細工した部分と変更・追加する部分(ほとんど、パラメーターとメッセージに答える部分)です。ある程度まとまったら、ダウンロードできるようにでもしたいと思いますが、とりあえず今は長いリストを見てください。

1.ウィンドウクラスを登録しWindowsに窓を作らせる InitWindow( )関数
2.ループをまわして WinMain内の While( 1 ){ }の所
3.A Windowsからのメッセージを待つ SysTask( )関数
3.B その間に指定のタイミングで指定の関数を呼び出す WinMain内のdo{ } while( )の所
4.それに答える WindProc( )関数
5.最後にちゃんと後始末 QuitWindow( )

#include <windows.h>

#define XSIZE 640
#define YSIZE 480
#define PROCTIME 50 // 周期的な処理を実行する時間間隔 1000分の1秒単位 // 50/1000 = 秒間 20回
char lpszAPPNAME[] = { "AppName" }; // アプリケーションの名前
BOOL bFullScreen = FALSE; // フルスクリーンにするか

////////////////////
// System Task
// Windows に対して処理時間を与える ?
BOOL
SysTask( void ){
  MSG msg;
  while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ){ // メッセージキューの確認
    if( !GetMessage( &msg, NULL, 0, 0 ) ) return FALSE ; // メッセージを取得
    TranslateMessage( &msg );
    DispatchMessage( &msg );
  }
  return TRUE;
}

////////////////////
// WinMain
// メイン
int PASCAL
WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow ){

  // Windowの作成と初期化
  if( hWnd = InitWindow( hInstance, nCmdShow , XSIZE, YSIZE ) == NULL ) return FALSE;

  
// アプリケーションの初期化処理(必要に応じて追加)処理

  // メインループ
  DWORD wait;
  while( 1 ){
    wait = GetTickCount( ); // ループ開始時間
    do{ // ループ時間待機
      if( !SysTask( ) ) { // システムタスク(メッセージを確認に行く)
        goto Abort;
      }
    }while( GetTickCount( ) < wait + PROCTIME ); // タイミングを見計らって
    
// 一定のタイミングで実行する処理をここに記載(細工)
  }

Abort:
  // 終了処理
  
// アプリケーションの終了処理(必要に応じて追加)
  return TRUE;
}

////////////////////
// InitWindow
// ウィンドウの作成
HWND
InitWindow( HINSTANCE hInstance, int nCmdShow, int iXsize, int iYsize ){
  WNDCLASS wndclass;
  BOOL bRegClass;
  HWND hWnd = NULL;

  // ウインドウクラスの生成
  wndclass.style = NULL; // ここに開きたい窓のスタイルを
  wndclass.lpfnWndProc = WndProc; // メッセージハンドラ関数
  wndclass.cbClsExtra = 0;
  wndclass.cbWndExtra = 0;
  wndclass.hInstance = hInstance;
  wndclass.hIcon = NULL; // 必要なら iconを
  wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
  wndclass.lpszMenuName = NULL;
  wndclass.lpszClassName = lpszAPPNAME;

  if(( bRegClass = RegisterClass( &wndclass )) == NULL) return NULL;

  DWORD dwStyle;
  if( bFullScreen ){
    dwStyle = WS_POPUP | WS_VISIBLE;
  }
  else{
    dwStyle = WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION;
  }
  hWnd = CreateWindowEx(
    0,
    lpszAPPNAME,
    lpszAPPNAME,
    dwStyle,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    iXsize + GetSystemMetrics( SM_CXBORDER ) * 2 ,
    iYsize + GetSystemMetrics( SM_CYBORDER ) * 2 + GetSystemMetrics( SM_CYCAPTION ),
    NULL,
    NULL,
    hInstance,
    NULL );

  if( !hWnd ) return NULL;

  ShowWindow( hWnd, nCmdShow );
  UpdateWindow( hWnd );
  SetFocus( hWnd );
  return hWnd;
}

////////////////////
// QuitWindow
// ウィンドウの破棄
void
QuitWindow( HWND hWnd ){
  DestroyWindow( hWnd );
}

////////////////////
// WndProc CallBack
// コールバック // メッセージハンドラー
HRESULT CALLBACK
WndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ){
  HDC hdc;
  PAINTSTRUCT ps;

  switch( iMessage ){
    case WM_PAINT:
      break;
    case WM_KEYDOWN:
      switch( wParam ){
        case VK_ESCAPE:
          PostMessage( hWnd, WM_CLOSE, 0, 0L );
          break;
        default:
          ;
      }
      break;
    case WM_RBUTTONUP: // 右ボタンで終了
      PostMessage( hWnd, WM_CLOSE, 0, 0L );
      break;
    case WM_CLOSE: // PostMessage(
      QuitWindow( hWnd );
      break;
    case WM_DESTROY:
      // DestroyWindow関数から呼び出される
      PostQuitMessage( 0 ); // メッセージループに対するアプリケーション終了通知
      break;
    default:
      ;
  }
  return DefWindowProc( hWnd, iMessage, wParam, lParam );
}
 

back to homemenutop