Windowsプログラミング--ウィンドウとメッセージ


Windowsプログラミングを行う場合、オブジェクト向けのプログラミングを行うことになります.オブジェクト向けでは、オブジェクトはコードとデータの組み合わせであり、ウィンドウもオブジェクトです.
ユーザーの目には、ウィンドウは画面上のオブジェクトであり、キーボードやマウスを使用して直接対話することができます.
ユーザは、ウィンドウへの入力を「メッセージ」としてウィンドウに渡し、ウィンドウもメッセージを介して他のウィンドウと通信する.
ウィンドウの作成は簡単そうに見えますが、CreateWindow関数を呼び出せばいいです.
ただし、ウィンドウを作成する前に、ウィンドウクラスを登録する必要があります.ウィンドウ・クラスは、ウィンドウ・メッセージを処理するウィンドウ・プロシージャを決定します.複数のウィンドウは、ウィンドウクラスに基づいて同時に作成できます.登録ウィンドウクラスはRegisterClass関数を呼び出す必要があります.この関数には、WNDCLASSタイプの構造へのポインタというパラメータが1つしかありません.次に、この構造を見てみましょう.
まずASCIIバージョンです.
typedef struct tagWNDCLASSA{ 
    UINT       style; 
    WNDPROC    lpfnWndProc; 
    int        cbClsExtra; 
    int        cbWndExtra; 
    HINSTANCE  hInstance; 
    HICON      hIcon; 
    HCURSOR    hCursor; 
    HBRUSH     hbrBackground; 
    LPCSTR    lpszMenuName; 
    LPCSTR    lpszClassName; 
} WNDCLASS, *PWNDCLASS; 

次はUnicodeバージョンです.
typedef struct tagWNDCLASSW{ 
    UINT       style; 
    WNDPROC    lpfnWndProc; 
    int        cbClsExtra; 
    int        cbWndExtra; 
    HINSTANCE  hInstance; 
    HICON      hIcon; 
    HCURSOR    hCursor; 
    HBRUSH     hbrBackground; 
    LPCWSTR    lpszMenuName; 
    LPCWSTR    lpszClassName; 
} WNDCLASS, *PWNDCLASS; 

最後の2つのフィールドだけが異なり、Unicodeはワイド文字の定数文字列として定義されていることがわかります.
WNDCLASSで最も重要な2つのフィールドは、2番目のlpfnWndProcと最後のlpszClassNameです.2番目のフィールドは、ウィンドウクラスのすべてのウィンドウに基づくウィンドウプロシージャのアドレスです.最後のフィールドはウィンドウクラスの名前です.
次に作成します.
hwnd = CreateWindow(szAppName,                 //      
                    TEXT("The Hello Program"), //    
                    WS_OVERLAPPEDWINDOW,       //    
                    CW_USEDEFAULT,             //  x  
                    CW_USEDEFAULT,             //  y  
                    CW_USEDEFAULT,             //  x    
                    CW_USEDEFAULT,             //  y    
                    NULL,                      //     
                    NULL,                      //      
                    hInstance,                 //      
                    NULL);                     //    

作成したら、ウィンドウの表示になります.すなわち、関数ShowWindow(hwnd,iCmdShow);最初のパラメータはCreateWindowが作成したウィンドウのハンドルです.2番目のパラメータは、WinMain関数が受け入れるiCmdShow値です.
次に、UpdateWindow(hwnd)を呼び出して、ウィンドウのクライアント領域の再描画を行います.
UpdateWindowの後、新しいウィンドウが画面に完全に表示されます.
この場合、このプログラムは、ユーザからのキーボード入力とマウス入力を受信できる必要がある.どうやってやったの?Windowsは、現在実行中のWindowsプログラムごとにメッセージキューを維持します.入力時間が発生すると、Windowsはこれらのイベントを自動的に「メッセージ」に変換し、アプリケーションのメッセージキューに配置します.アプリケーションは次のコードでループします.
while(GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);//               
    DispatchMessage(&msg);// msg     Windows            
}

ここでmsgは構造変数であり、以下のように定義される.
typedef struct tagMSG {
  HWND   hwnd; 
  UINT   message; 
  WPARAM wParam; 
  LPARAM lParam; 
  DWORD  time; 
  POINT  pt; 
} MSG, *PMSG; 

控訴構造のPOINTは別の構造です.
typedef struct tagPOINT { 
  LONG x; 
  LONG y; 
} POINT, *PPOINT; 

次に、本当に興味深いことを説明します.ウィンドウ・プロシージャ1つのwindowsプログラムには複数のウィンドウ・プロシージャが含まれますが、1つのウィンドウ・プロシージャは常にRegisterClassを呼び出して登録された特定のウィンドウ・クラスに関連付けられています.ウィンドウ・プロシージャは、常に次のように定義されます.
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

ウィンドウプロセス関数の4つのパラメータはMSG構造の4つのフィールドに1つずつ対応している.1番目のパラメータ:メッセージを受信するウィンドウを表すハンドル2番目のパラメータ:メッセージ識別子の最後の2つのパラメータ:32ビットのメッセージパラメータ
最後にメッセージ処理です.
switch(message)
{
case WM_CREATE:
     [  WM_CREATE  ]
     return 0;
case WM_PAINT:
     [  WM_PAINT  ]
     return 0;

 case WM_DESTROY:
     [  WM_DESTROY  ]
     return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);