サーチ…


ウィンドウの作成

#define UNICODE
#define _UNICODE
#include <windows.h>
#include <tchar.h>
const TCHAR CLSNAME[] = TEXT("helloworldWClass");
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PTSTR cmdline,
                   int cmdshow)
{
    WNDCLASSEX wc = { };
    MSG msg;
    HWND hwnd;

    wc.cbSize        = sizeof (wc);
    wc.style         = 0;
    wc.lpfnWndProc   = winproc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInst;
    wc.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = CLSNAME;
    wc.hIconSm       = LoadIcon (NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc)) {
        MessageBox(NULL, TEXT("Could not register window class"), 
                  NULL, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindowEx(WS_EX_LEFT,
                          CLSNAME,
                          NULL,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          NULL,
                          NULL,
                          hInst,
                          NULL);
    if (!hwnd) {
        MessageBox(NULL, TEXT("Could not create window"), NULL, MB_ICONERROR);
        return 0;
    }

    ShowWindow(hwnd, cmdshow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
    return DefWindowProc(hwnd, wm, wp, lp);
}

まず最初にUNICODE_UNICODE 2つのマクロ定義があり_UNICODE 。これらのマクロは、プログラムでワイド文字列( char[n] )ではなく、ワイド文字列( wchar_t[n] )を理解できるようにします。その結果、すべての文字列リテラルはに包まれなければなりませんTEXT(マクロWin32の文字列のための一般的な文字の種類がある。 TCHARその定義かどうかに依存して、 UNICODE定義されている新しいヘッダが含まれています。 <tchar.h>含まれていますTCHAR宣言。

ウィンドウは、 ウィンドウクラスと呼ばれるもので構成されています 。アイコン、カーソルなどのインスタンス間で共有されるウィンドウに関する情報を記述します。ウィンドウクラスは、この例のCLSNAMEグローバル変数で指定されたウィンドウクラス名で識別されます。 WinMainの最初の行為は、ウィンドウクラス構造WNDCLASSEX wcです。メンバーは次のとおりです:

  • cbSize:構造体のサイズ(バイト単位)。
  • style:ウィンドウクラスのスタイル。これは今のところ0です。
  • lpfnWndProc:これはより重要なフィールドの1つです。 ウィンドウプロシージャのアドレスを格納します 。ウィンドウプロシージャは、このウィンドウクラスのインスタンスであるすべてのウィンドウのイベントを処理する関数です。
  • cbClsExtra:ウィンドウクラスに割り当てる余分なバイト数。ほとんどの場合、このメンバーは0です。
  • cbWndExtra:個々のウィンドウごとに割り当てる余分なバイト数。これをcbClsExtraと混同しないでください。これはすべてのインスタンスに共通です。これはしばしば0です。
  • hInstance:インスタンスハンドル。 WinMainhInst引数をこのフィールドに代入するだけです。
  • hIcon:ウィンドウクラスのアイコンハンドルです。 LoadIcon(NULL, IDI_APPLICATION)は、デフォルトのアプリケーションアイコンをロードします。
  • hCursor:ウィンドウクラスのカーソルハンドルです。 LoadCursor(NULL, IDC_ARROW)は、デフォルトのカーソルをロードします。
  • hbrBackground:背景ブラシのハンドル。 GetStockObject (WHITE_BRUSH)は、白いブラシのハンドルをGetStockObject (WHITE_BRUSH)ます。 GetStockObjectは汎用オブジェクトを返すので、戻り値はキャストする必要があります。
  • lpszMenuName:使用するメニューバーのリソース名。メニューバーが必要ない場合、このフィールドはNULLにすることができます。
  • lpszClassName:このウィンドウクラス構造を識別するクラス名。この例では、 CLSNAMEグローバル変数にウィンドウクラス名が格納されています。
  • hIconSm:小さなクラスのアイコンへのハンドルです。

この構造体が初期化されると、 RegisterClassEx関数が呼び出されます。これにより、ウィンドウクラスがWindowsに登録され、アプリケーションに通知されます。失敗すると0を返します。

ウィンドウクラスが登録されたので、 CreateWindowExを使用してウィンドウを表示できます。引数は次のとおりです。

  • stylesex:拡張されたウィンドウスタイル。デフォルト値はWS_EX_LEFTです。
  • clsname:クラス名
  • cap:ウィンドウタイトル、またはキャプション。この場合、ウィンドウのタイトルバーに表示されるキャプションです。
  • styles:ウィンドウのスタイル。このようなトップレベル(親)ウィンドウを作成する場合、渡すフラグはWS_OVERLAPPEDWINDOWです。
  • x:ウィンドウの左上隅のx座標。
  • y:ウィンドウの左上隅のy座標
  • cx:ウィンドウの幅
  • cy:ウィンドウの高さ
  • hwndParent:親ウィンドウへのハンドル。このウィンドウ自体は親ウィンドウなので、この引数はNULLです。
  • hMenuOrID:作成されるウィンドウが親ウィンドウの場合、この引数はウィンドウメニューのハンドルです。これをクラスメニューWNDCLASSEX::lpszClassNameと混同しないでください。クラスメニューは、同じクラス名を持つウィンドウのすべてのインスタンスに共通です。ただし、この引数はこのインスタンスに固有のものです。作成されるウィンドウが子ウィンドウである場合、これは子ウィンドウのIDです。この場合、メニューを持たない親ウィンドウを作成しているので、NULLが渡されます。
  • hInst:アプリケーションのインスタンスへのハンドル。
  • etc:ウィンドウのウィンドウプロシージャに渡される追加情報。余分な情報を送信しない場合は、NULLを渡します。

xまたはyまたはcxまたはcyCW_USEDEFAULT場合、その引数の値はWindowsによって決定されます。これがこの例で行われていることです。

CreateWindowExは、新しく作成されたウィンドウへのハンドルを返します。ウィンドウの作成に失敗した場合、 NULL返しNULL

ShowWindowを呼び出すと、ウィンドウが表示されます。この関数の最初の引数はウィンドウのハンドルです。 2番目の引数は、ウィンドウをどのように表示するかを示す表示スタイルです。ほとんどのアプリケーションは、 WinMain渡されたcmdshow引数を渡します。ウィンドウが表示されたら、 UpdateWindow呼び出してウィンドウを更新する必要があります。これにより、更新メッセージがウィンドウに送信されます。これが別のチュートリアルで何を意味するのかを学びます。

今すぐアプリケーションの中心になる:メッセージポンプ。これは、オペレーティングシステムによってこのアプリケーションに送信されたメッセージをポンピングし、メッセージをウィンドウプロシージャにディスパッチします。 GetMessage呼び出しは、アプリケーションが終了させるメッセージを受信するまで0以外の値を返します。この場合、0が返されます。私たちに関係する唯一の引数は、メッセージに関する情報で埋められるMSG構造体へのポインタです。他の引数はすべて0です。

メッセージループ内で、 TranslateMessageは仮想キーメッセージを文字メッセージに変換します。これの意味は、私たちにとって重要ではありません。これは、 MSG構造体へのポインタをとります。その直後の呼び出しであるDispatchMessage 、引数で指定されたメッセージをウィンドウのウィンドウプロシージャにDispatchMessageます。 WinMainが最後にしなければならないことは、ステータスコードを返すことです。 MSG構造体のwParamメンバにはこの戻り値が含まれているため、返されます。

しかし、これはWinMain関数のためのものです。もう一つの関数はウィンドウプロシージャであるwinprocです。 Windowsによって送信されたウィンドウのメッセージを処理します。 winprocの署名はwinprocです。

  • hwnd:メッセージが処理されているウィンドウへのハンドル。
  • wm:ウィンドウメッセージ識別子
  • wp:メッセージ情報の引数の1つ。これはwm引数に依存します
  • lp:メッセージ情報の引数の1つ。これはwm引数に依存します。この引数は通常、ポインタまたはハンドルを送信するために使用されます

この単純なプログラムでは、私たちは自分でメッセージを処理しません。しかし、それはWindowsもそうでないことを意味するわけではありません。このため、デフォルトのウィンドウ処理コードを含むDefWindowProc呼び出す必要があります。この関数は、すべてのウィンドウプロシージャの最後に呼び出さなければなりません。

ハンドルとは何ですか?

ハンドルは、一意のオブジェクトを表すデータ型です。それらはポインタですが、オペレーティングシステムによって維持される秘密のデータ構造になります。これらの構造の詳細は私たちに関係する必要はありません。ユーザーが行う必要があるのは、単にAPI呼び出しを使用してハンドルを作成/取得し、そのハンドルを使用する他のAPI呼び出しに渡すだけです。私たちが使用したハンドルの唯一のタイプは、 CreateWindowExによって返されたHWNDでした。

定数

この例では、いくつかの定数があります。これらはすべて大文字で始まり、2〜3文字の接頭辞で始まります。 (Windowsの種類もすべて大文字です)

  • IDI_APPLICATION:デフォルトのアプリケーションアイコンを含むリソース名。これは、 LoadIconまたはLoadImage (この例ではLoadIcon)で使用されます。
  • IDC_ARROW:デフォルトのアプリケーションカーソルを保持するリソース名。これは、 LoadIconまたはLoadImage (この例ではLoadIcon)で使用されます。
  • WHITE_BRUSH:ストックオブジェクトの名前。このストックオブジェクトは白いブラシです。
  • MB_ICONERROR:エラーアイコンを表示するためにMessageBox使用されるフラグです。
  • WS_EX_LEFT:デフォルトの拡張ウィンドウスタイル。これにより、ウィンドウは左揃えのプロパティになります。
  • WS_OVERLAPPEDWINDOW:ウインドウが、タイトルバー、サイズボックス、およびその他のトップレベルウィンドウに典型的な要素を持つ親ウインドウであることを示すウインドウスタイル。
  • CW_USEDEFAULT: CreateWindowExxycx 、またはcy引数で使用されます。 WindowsがCW_USEDEFAULTが渡された引数の有効な値を選択します。

Windowsの種類

Windows用にプログラミングするときは、組み込み型のエイリアスであるWin32型に慣れる必要があります。これらのタイプはすべて大文字です。このプログラムで使用されるエイリアスタイプは次のとおりです。

  • TCHAR:一般的な文字タイプ。 UNICODEが定義されている場合、これはwchar_tです。その他、それはcharです。
  • UINT:符号なし整数です。ウィンドウプロシージャなどの目的でメッセージ識別子を表すために使用されます。
  • WPARAM:Win16では、これはWORD引数( W接頭辞)でした。しかし、Win32の導入により、これは現在UINT_PTR 。これは、これらのWindowsエイリアスのポイントを示しています。彼らはプログラムを変更から保護するためにそこにいます。
  • LPARAM:これはLONG引数( LONG_PTRのWin64で)。
  • PTSTR: Pはポインタを意味します。 Tは一般的な文字を意味し、 STRは文字列を意味する。したがって、これはTCHAR文字列へのポインタです。その他の文字列型は次のとおりです。
    • LPTSTR:同じPTSTR
    • LPCTSTR: const TCHAR *意味する
    • PCTSTR:同じLPCTSTR
    • LPWSTR:ワイド文字列( wchar_t *
    • LPCWSTR: const wchar_t *意味するconst wchar_t *
    • PWSTR:同じLPWSTR
    • Win32のタイプは、特にWin16のアーティファクトである非常に多くの同義のタイプを理解するのが面倒です。
  • LRESULT:この型は、ウィンドウプロシージャの戻り値を表すために使用されます。これは通常LONG(したがってL )です。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow