ホーム 
   
Windows API Primer 
    
    
    Windows 3.1   / Borland Turbo C++ 
    
    Win16 API を始めるための Windows 3.1 と Borland Turbo C++ のインストールと設定方法は、Environment Windows 3.1  をご覧ください。
    
    ウィンドウ 
    
    Windows APIでウィンドウを表示するには、独自のウィンドウクラスを作成して、そのウィンドウクラスをシステム(Windows OS)に登録します。そして、その登録されたウィンドウクラスからウィンドウを作成して表示します。
    
    
    ウィンドウクラスを作成する。 
    
    作成したウィンドウクラスをシステム(Windows OS)に登録する。 
    
    システム(Windows OS)に登録されたウィンドウクラスからウィンドウを作成して表示する。 
     
    
    イベントループ 
    
    GUI アプリケーションは、終了メッセージを受け取るまで、イベントループなどと呼ばれる無限ループで起動し続けます。
    
    このような無限ループをプログラミング用語ではイベントループやメインループと言いますが、Windows APIでは、メッセージループとも言います。
    
    window.c 
    
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int     PASCAL   WinMain(HINSTANCE hInstance,
               HINSTANCE hPrevInstance,
               LPSTR     lpCmdLine,
               int       nCmdShow)
{
    WNDCLASS wc;
    HWND     hwnd;
    MSG      msg;
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = NULL;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "WINDOW";
    RegisterClass(&wc);
    hwnd             = CreateWindow("WINDOW",
                                    "Window",
                                    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                                    CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
                                    NULL, NULL, hInstance, NULL);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }
    
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    
    return DefWindowProc(hwnd, msg, wParam, lParam);
}
    
    
    実行結果 
    
     
    
    
    コード説明 
    
    
    windows.h 
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
    
    int PASCAL WinMain
    HINSTANCE hInstance 
    HINSTACE hPrevInstance 
    LPSTR lpCmdLine 
    int nCmdShow 
      
    
    WinMain 関数の冒頭で設定されている各変数の型の意味は次のようになります。
    
    WNDCLASS 
    ウィンドウクラスの各設定値を格納する構造体です。 
    HWND 
    ウィンドウのハンドルが入る型です。プログラミングおいてハンドル(hundle)とは、データやコードの場所が変わる場合に、必ずその場所を追跡するポインターのポインターですが、Windows API ではデータやコードを識別するためのユニーク(一意)な整数値です。Hやhで始まる型やメンバーはハンドルです。 
    MSG 
    アプリケーションやシステムは色々なイベントを発します。そのイベントは、メッセージとして、この MSG 構造体に格納されます。イベントをきっかけに、アプリケーションの処理や振る舞いが決まる仕組みのことをイベント駆動(イベントドリブン、event driven)と言います。 
     
     
    
    ウィンドウクラス構造体のメンバーの意味は次のようになります。
    
    style 
    ここには通常、ウィンドウが水平方向に変更された時に再描画することを意味するCS_HREDRAW定数と、ウィンドウが垂直方向に変更された場合に再描画することを意味するCS_VREDRAW定数を | でつなげて設定します。CS はクラススタイルの略だと思えば覚えやすいでしょう。 
    lpfnWndProc 
    Windows APIでは、ウィンドウがイベント(メッセージ)を発した場合に、それを処理する関数を決めておかなければなりません。ここでは自作関数の WndProc を設定しています。Windows API で使われるメンバー名などの識別子には一定の接頭辞(プリフィックス、prefix)がつきます。l はロング、p はポインター、fn は関数(ファンクション、function)を表しています。 
  cbClsExtra と cbWndExtra 
  ここには、ウィンドウに追加で格納するデータ領域を設定しますが、通常は使わないので 0 を設定します。 
  hInstance 
  このウィンドウを使うアプリケーションを指定します。hInstance は、メイン関数の引数で指定された、このアプリケーションを表すハンドルです。 
  hIcon 
  アイコンを指定します。 NULL を指定した場合は標準のアイコンが設定されます。 
  hCursor 
  カーソルの形を指定します。LoadCursor(NULL, IDC_ARROW) で矢印カーソルを指定できます。 
  hbrBackground 
  ウィンドウの背景色を設定します。HBRUSHは、塗り潰しの情報が入ったハンドルです。ここでは WHITE_BRUSH(白色)を取得しています。 
  lpszMenuName 
  ウィンドウで使われるメニューを識別する文字列が入ります。メニューを使わない場合は NULL を指定します。sz は、終了文字 \0 で終わる文字列を意味しています。 
  lpszClassName 
  このウィンドウクラスの名前を設定します。後ほど、このウィンドウクラスからウィンドウを作成する場合に、この名前を使います。 
      
    
    RegisterClass関数でウィンドウクラスをシステム (Windows OS) に登録します。引数には登録したいウィンドウクラスのポインターを指定します。 
    
    CreateWindow関数でウィンドウを作成します。引数は次のとおりです。
    
    第1引数に、どのウィンドウクラスからウィンドウを作るかを、そのウィンドウクラスの名前で指定します。 
    第2引数に、そのウィンドウのタイトルバーに表示する文字列を指定します。 
	第3引数に、作成するウィンドウの種類や状態を定数で指定します。WS_OVERLAPPEDWINDOWは他のウィンドウと重なり合うことを許可します。WS_VISIBLEは、ウィンドウを可視状態にします。通常作成されたウィンドウのデフォルトは不可視になっています。
	WS はウィンドウスタイルを略していると思えば覚えやすいでしょう。 
	第4引数に、ウィンドウが表示される位置を、デスクトップのX座標で指定します。CW_USEDEFAULTを指定するとシステムが適当な位置を選んでくれます。 
	第5引数に、ウィンドウが表示される位置を、デスクトップのY座標で指定します。CW_USEDEFAULTを指定するとシステムが適当な位置を選んでくれます。 
    第6引数に、ウィンドウの横幅を指定します。ここでもCW_USEDEFAULTを使うことができます。 
    第7引数に、ウィンドウの縦幅を指定します。ここでもCW_USEDEFAULTを使うことができます。 
    第8引数に、親ウィンドウを指定します。親ウィンドウのないメインウィンドウを作成したい場合は、NULL を指定します。 
    第9引数に、メニューを指定します。メニューを使わない場合は、NULL を指定します。 
    第10引数に、そのウィンドウを使用するアプリケーションのハンドルを指定します。 
	第11引数は、ウィンドウ作成時に発生するイベントにデータを渡す手段として使用するそうですが、実際の使い方がわかりません。通常は、NULL で良いみたいです。 
     
     
    
    while 文でメッセージループを始めます。 
    
    GetMessage関数は、ウィンドウが発するイベント(メッセージ)を取得すします。引数は次のとおりです。
    
    第1引数に、用意しておいた MSG 構造体のポインタを指定します。ここに取得したメッセージが格納されます。 
    第2引数に、メッセージを取得したいウィンドウを指定します。NULLを指定すると、そのアプリケーションのすべてのウィンドウからメッセージを取得します。 
    第3引数に、取得するメッセージの最小値を指定します。最小値を限定したくない場合は 0 を指定します。 
    第4引数に、取得するメッセージの最大値を指定します。最大値を限定したくない場合は 0 を指定します。 
      
    
    DispatchMessage 関数でメッセージをとりにいきます。 
    
    この位置によく TranslateMessage という関数を見かけます。TranslateMessage はアプリケーションで文字入力を扱う場合に必要です。文字入力を受け付けない場合は不要です。 
    
    return msg.wParam; 
    
    LRESULT CALLBACK WndProc
    第1引数に、メッセージを送ってくるウィンドウのハンドルを指定します。 
    第2引数に、MSG構造体のmessageメンバーを指定します。messageメンバーはメッセージの種類を表す正数値です。 
    第3引数に、MSG構造体のwParamメンバーを指定します。wParamメンバーは、メッセージに付随する追加のデータが格納されている16bit整数値です。 
    第4引数に、MSG構造体のlParamメンバーを指定します。lParamメンバーは、メッセージに付随する追加のデータが格納されている32bit整数値です。 
      
    
    WndProc 関数の中では、msg の整数値を利用して switch 文でメッセージを選別します。 
    
    case WM_DESTROY: 
    
    PostQuitMessage は、アプリケーションを終了させるメッセージです。引数の 0 は、終了時に返されるコードです。 
    
    return DefWindowProc(hwnd, msg, wParam, lParam); 
    
    Win16 API プログラミングでは、ソースコードの最後に空行を1行入れておかないと(つまり最後に改行を入れておかないと)コンパイル時に警告が出ます。 
     
	
     
Posted: Jul. 17, 2020
Update: Jul. 18, 2020