アークピットのホームページに戻る

WinAPIトピックのトップページに戻る

APIトピックの各章に移動する

ダウンロードのページに移動する
ダウンロードができ
ない場合の対処法
 

ページ移動

2-1-2. WinMain関数とその仕様

WinMain関数

 Windowsのプログラムは、WinMain関数で始まります。C言語のmain関数と同じと考えても結構です。DLLファイルなどの例外はありますが、通常のアプリケーションは、必ずこの関数が含まれます。
INT  APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine, INT nCmdShow)
{
        :
        :
    return msg.wParam;
    UNREFERENCED_PARAMETER(hPrevInstance);
}
 初めての人は、この文だけ見ても、なじみない型や宣言の羅列で戸惑うかも知れません。しかしこれらは、Windowsのプログラミングの文化です。それには、慣れるよりしかたありません。1つづつ説明しますので、あきらめないでください。

 INTはintです。WIN32では32ビットの整数を返すのが決まりです。int,char などのC言語の自然な型は使いません。windows.h で宣言され直した、型を通常使用します。これらは、すべて大文字で表現します。APIENTRYは、__stdcall ですので、「通常のAPI仕様だよ」と言う意味しかありません。システムがコールする関数は、勝手に関数のタイプを決める訳にはいきません。ちゃんと決められた仕様で宣言する必要があります。この他には、CALLBACK,DLGPROC などの宣言もあります。

 WinMain関数は、WM_QUITメッセージを受け取って正常に終了した場合は、 メッセージのwParamパラメータに格納されている終了コードを返します。メッセージループに入る前に関数の実行が強制終了された場合は、 NULLを返します。

 WIN32では、hPrevInstance パラメータは使用しません。しかし旧版との互換性のために渡されます。通常は問題ないのですが、C言語の文法検査のレベルを上げると、パラメータを使用しないとワーニングエラーになります。UNREFERENCED_PARAMETER は未使用を宣言しエラーにならなくします。

HINSTANCE とハンドル

 WinMain関数は、HINSTANCE 型のパラメータが2つあります。まず、HINSTANCE の H はハンドルを示します。このハンドルを理解するのが、Windowsプログラミングの第1歩です。HWND,HPEN,HGLOBAL などハンドルは多数あります。HINSTANCE,HWND,HPEN,HGLOBAL 等は、すべて HANDLE と宣言されます。要するにこれらの実体は、まったく同一です。ハンドルとは、何らかの「要素」を識別するための手段です。単なる一意な番号と思っても、そう間違っていません。C言語のファイルを識別する FILE の考え方と同じです。HINSTANCE,HWND,HPEN,HGLOBAL は、それぞれ、プログラム・ウィンドウ・ペン・メモリブロックを指します。ハンドルはシステムが管理します。ユーザは、それの作成・使用・破棄をシステムに要求します。作成でハンドルを得て、使用する場合に、ハンドルでそれを識別します。そして破棄でハンドルが解除されます。例えば、HWNDの場合は、CreateWindow 関数で作成されます。そして、MoveWindow,CloseWindow などの数々の操作関数で使用し、DestroyWindow で破棄されます。つまりハンドルは、作成されてから、破棄されるまで有効です。なお、HANDLE の実体は、void * なので、作成に失敗してエラーが起こった場合の返り値などの様に、エラーや不定の場合は、NULL で示します。

 それでは、HINSTANCE です。最初の hInstance は、このプログラム(インスタンス)を識別する番号です。これはシステムがプログラムを実行した時点で作成します。そして、hPrevInstance は、アプリケーションの以前のインスタンスを識別しますが、WIN32アプリケーションの場合、 このパラメータは常にNULLです。Windows v3.1 との互換のためのいパラメータでWIN32では意味がありません。

lpCmdLine とコマンドラインパラメータ

 lpCmdLine は、文字列のポインタで、このアプリケーションを起動するときのパラメータの文字列です。MS-DOS プロンプトから実行する場合や、ショートカット、さらに関連付けのアプリケーションの起動でパラメータを設定します。

ApBooks /2 FileName[Enter]

 上記では、lpCmdLine = "/2 FileName" となります。しかしC言語の argv,argc の様に、区切りごとに書式化されている訳ではありません。単なる文字列ですので注意してください。上記の書式を判断するサンプルを以下に記します。
INT  APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine, INT nCmdShow)
{
    if (lpCmdLine != NULL && *lpCmdLine)
    {
        if (*lpCmdLine == '/')
        {
            ++lpCmdLine;
            switch((TCHAR)CharUpper((LPSTR)*lpCmdLine++))
            {
                case '1': nReVer = 1; break;
                case '2': nReVer = 2; break;
            }
            while(*lpCmdLine == ' ') ++lpCmdLine;
        }
        if (*lpCmdLine != '\0')
        {
            LoadDataFile(lpCmdLine); // ファイルロード
        }
    }
        :
        :
}

nCmdShow とウィンドウの状態

 nCmdShow は、起動時のウィンドウの状態を指示します。ウィンドウの状態とは、通常・最大化・最小化を示します。Windowsでは、ショートカットでアプリケーションを起動する場合は、上記の3つのどの状態にするか指定できます。デスクトップ上のショートカットを右クリックして、「プロパティ」を実行すれば、[ショートカット]タブの、「実行時の大きさ」でウィンドウの起動時の状態を設定します。これに対応して nCmdShow が与えられます。

 起動時のウィンドウの状態は、普通 nCmdShow パラメータの状態がもっとも優先されます。しかしこれを無視することもあります。基本的には、前回の終了時のウィンドウ状態を、再現する例が多いでしょう。

 これに関して良くあるのは、最小化して、終了した場合、次回の起動でも最小化から始まります。しかし起動し直したので、復元のデータがありません。よって、最小化の状態を変更することができなくなります。

ページ移動