ウインドウを開く

ただ開いて,10秒後に消えます.メインループはありません.

0001: /*
0002:   openwin-win32.c
0003:   gcc openwin-win32.c -mwindows
0004:   bcc32 -W openwin-win32.c 
0005: */
0006: 
0007: #include <windows.h>
0008: 
0009: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
0010:         LPSTR lpCmdLine, int nCmdShow )
0011: {
0012:   HWND hWnd;
0013:   WNDCLASS wndClass;
0014:   static TCHAR szAppName[] = TEXT("OpenWindow");
0015: 
0016:   /* ウインドウクラスの設定 */
0017:   wndClass.style = 0;
0018:   wndClass.lpfnWndProc = DefWindowProc;
0019:   wndClass.cbClsExtra = 0;
0020:   wndClass.cbWndExtra = 0;
0021:   wndClass.hInstance = hInstance;
0022:   wndClass.hIcon = NULL;
0023:   wndClass.hCursor = NULL;
0024:   wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
0025:   wndClass.lpszMenuName = NULL;
0026:   wndClass.lpszClassName = szAppName;
0027: 
0028:   RegisterClass( &wndClass ); /* ウインドウクラスの登録 */
0029: 
0030:   hWnd = CreateWindow( /* ウインドウの作成 */ 
0031:           szAppName, /* 作成するウインドウのクラス名 */
0032:           TEXT("openwin-win32"), /* ウインドウタイトル */
0033:           WS_OVERLAPPEDWINDOW, /* ウインドウスタイル */
0034:           CW_USEDEFAULT, /* 左上頂点のX座標 */
0035:           CW_USEDEFAULT, /* 左上頂点のY座標 */
0036:           CW_USEDEFAULT, /* ウインドウの幅 */
0037:           CW_USEDEFAULT, /* ウインドウの高さ */
0038:           NULL, /* 親ウインドウのハンドル */
0039:           NULL, /* メニューのハンドル */
0040:           hInstance, /* 親モジュールのインスタンスハンドル */
0041:           NULL ); /* ウインドウへの引数 */
0042: 
0043:   ShowWindow( hWnd, nCmdShow ); /* ウインドウの表示 */
0044: 
0045:   Sleep( 10000 ); /* 表示を10秒間保持 */
0046:   
0047:   DestroyWindow( hWnd ); /* ウインドウの開放 */
0048: 
0049:   return 0;
0050: }

0003:   gcc openwin-win32.c -mwindows
0004:   bcc32 -W openwin-win32.c 

GCCでコンパイルする場合は,-mwindowsを指定し ます.また,BCCでコンパイルする場合は,-Wまた は-tWを指定します.BCCではこのオプションを一 番最初に指定した方がいいようです.最後につけた場合はmainを探しにいってエラーになってしまいました.

0007: #include <windows.h>

Windows プログラムの場合はヘッダファイルwindows.hをインクルードします.Windows 固有の型 などはこの中で宣言されています.

0009: int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
0010:         LPSTR lpCmdLine, int nCmdShow )

windows のプログラムはこのWinMainから始ま ります.

    int WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpCmdLine,
        int nCmdShow
    )

hInstanceは現在のアプリケーションのインスタンスをさすハンドルです。Windows ではデータのインスタンスを指し示すポインタをハンドルと呼びます。ここではHINSTANCEはインスタンスハンドル、後ででてくるHWNDはウインドウハンドルです。Windows での宣言はハンガリー記法に則っているので、先頭のHがハンドルであることを示しています。このハンドルはあらゆるデータ型において重要なものです。

hPrevInstanceは歴史的な経緯で残っているもので、現在は常にNULLとなっています。以前のWindowsは、同じプログラムが起動されていた場合は、そのリソースを共有していたのだそうです。メモリが高価だったんですね。その際にすでにあるインスタンスを参照するためのもので、現在はそのようにはなっていないので使われていません。

lpCmdLineはコマンドライン引数の文字列が入ります。通常のCプログラムと違い、ここでは引数ごとに分解されていません。また、ユニコード文字列が入っている場合があるので、GetCommandLineCommandLineToArgvWを使います。

nCmdShowにはウィンドウの初期表示状態指定が入 ります。マクロ定数が定められているので、詳しくはヘルプなどを参照してください。

0016:   /* ウインドウクラスの設定 */
0017:   wndClass.style = 0;
0018:   wndClass.lpfnWndProc = DefWindowProc;
0019:   wndClass.cbClsExtra = 0;
0020:   wndClass.cbWndExtra = 0;
0021:   wndClass.hInstance = NULL;
0022:   wndClass.hIcon = NULL;
0023:   wndClass.hCursor = NULL;
0024:   wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
0025:   wndClass.lpszMenuName = NULL;
0026:   wndClass.lpszClassName = szAppName;
0027: 
0028:   RegisterClass( &wndClass ); /* ウインドウクラスの登録 */

続いて、ウインドウクラスの設定です。どのようなウインドウにするかを決定します。 WNDCLASS構造体のメンバを初期化してRegisterClassでシステムに登録します。初期化が正しく行われていないと、RegisterClassに失敗してしまいます。

最低限指定しなければならないのは今回0NULLを指定しなかった3つのようです。

WNDCLASS.lpfnWndProcはウインドウプロシージャというのを指定するところで、メッセージを処理する関数を指定します。ここではシステムデフォルトのプロシージャであるDefWindowProcを指定しています。

WNDCLASS.backgroundは背景色です。ヘルプの指示どおりCOLOR_XXXXXを指定してもよかったのですが、ここでは背景色を白にするためにGetStockObjectで白色ブラシを指定しています。ここをNULLにしてもウインドウは作成されますが、枠だけで透明なウインドウになってしまいます。いずれの場合もHBRUSH型へのキャストが必要です。コンパイラのチェックが厳しい場合、キャストがないと怒られてしまいます。

WNDCLASS.lpszClassNameが最も重要なもので、このクラスに名前をつけます。クラス名はウインドウを識別する上で重要で、ウインドウを開く際もこの名前で指定をします。

RegisterClassでウインドウクラスをシステムに登録します。ウインドウクラスはプログラムが終了すると削除されます。

0030:   hWnd = CreateWindow( /* ウインドウの作成 */ 
0031:           szAppName, /* 作成するウインドウのクラス名 */
0032:           TEXT("openwin-win32"), /* ウインドウタイトル */
0033:           WS_OVERLAPPEDWINDOW, /* ウインドウスタイル */
0034:           CW_USEDEFAULT, /* 左上頂点のX座標 */
0035:           CW_USEDEFAULT, /* 左上頂点のY座標 */
0036:           CW_USEDEFAULT, /* ウインドウの幅 */
0037:           CW_USEDEFAULT, /* ウインドウの高さ */
0038:           NULL, /* 親ウインドウのハンドル */
0039:           NULL, /* メニューのハンドル */
0040:           hInstance, /* 親モジュールのインスタンスハンドル */
0041:           NULL ); /* ウインドウへの引数 */

CreateWindowでウインドウのインスタンスを作成します。成功するとウインドウハンドルhWndが返ります。

    HWND CreateWindow(
        LPCTSTR lpClassName,
        LPCTSTR lpWindowName,
        DWORD dwStyle,
        int x,
        int y,
        int nWidth,
        int nHeight,
        HWND hWndParent,
        HMENU hMenu,
        HINSTANCE hInstance,
        LPVOID lpParam
    )

lpClassNameに作成したいウインドウクラスのクラス名を指定します。lpWindowNameは要するにタイトルバーに表示される文字列です。dwStyleにはウインドウスタイルを指定します。WS_XXXXXというマクロがありますので、これをOR(|)でつないで指定します。ここでは、オーバーラップ型のみを指定しています。

x, y, nWidth, nHeightは、ウインドウを表示する際の左上隅の座標と幅・高さです。ここではCW_USEDEFAULTの値を使用しています。

hWndParentは親ウインドウまたはオーナーウインドウを指定します。ここではNULLを指定しているので、自動的にルートウインドウがオーナーになります。

hMenuはメニューのハンドルを指定します。ここではメニューは使用しないのでNULLです。

hInstanceはウインドウを作るプログラムモジュールのインスタンスを指定します。しかし、これはWindows95系のみが有効で、NT系では無視されます。

lpParamにはプログラムに渡したいデータのポインタを指定できる。ここでは使用しないのでNULLです。

0043:   ShowWindow( hWnd, nCmdShow ); /* ウインドウの表示 */

    BOOL ShowWindow(
        HWND hWnd,
        int nCmdShow
    )

CreateWindowはインスタンスを生成するだけで、 まだ画面上には現れません。ShowWindowを呼ぶ ことで画面上に表示されます。hWndは表示したい ウインドウのハンドルを指定します。nCmdShowWinMainからの引数です。ショートカットなど のプロパティを見ると「実行時の大きさ」というのがありますが、この指定が引き渡されると考えてください。

0047:   DestroyWindow( hWnd ); /* ウインドウの開放 */

    BOOL DestroyWindow(
        HWND hWnd
    )

DestroyWindowが呼ばれるまではインスタンス は有効ですので、SW_HIDEなどを引数として呼び出すこ とで表示を制御することができます。hWndに開放したいウインドウのハンドルを指定します。

より多くのパラメータを指定できるDestroyWindowEx系の関数もあります。

Back to TOP