次の方法で共有


ウィンドウ プロシージャの使用

このセクションでは、ウィンドウ プロシージャに関連付けられている次のタスクを実行する方法について説明します。

ウィンドウ プロシージャの設計

次の例は、一般的なウィンドウ プロシージャの構造を示しています。 ウィンドウ プロシージャは、switch ステートメントのメッセージ引数を使用し、個別の ケース ステートメントによって個々のメッセージを処理します。 各ケースは、各メッセージの特定の値を返していることに注意してください。 処理されないメッセージの場合、ウィンドウ プロシージャは DefWindowProc 関数を呼び出します。

LRESULT CALLBACK MainWndProc(
    HWND hwnd,        // handle to window
    UINT uMsg,        // message identifier
    WPARAM wParam,    // first message parameter
    LPARAM lParam)    // second message parameter
{ 
 
    switch (uMsg) 
    { 
        case WM_CREATE: 
            // Initialize the window. 
            return 0; 
 
        case WM_PAINT: 
            // Paint the window's client area. 
            return 0; 
 
        case WM_SIZE: 
            // Set the size and position of the window. 
            return 0; 
 
        case WM_DESTROY: 
            // Clean up window-specific data objects. 
            return 0; 
 
        // 
        // Process other messages. 
        // 
 
        default: 
            return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
} 

WM_NCCREATE メッセージは、ウィンドウが作成された直後に送信されますが、アプリケーションが FALSE 返すことによってこのメッセージに応答すると、CreateWindowEx関数失敗します。 WM_CREATE メッセージは、ウィンドウが既に作成された後に送信されます。

WM_DESTROY メッセージは、ウィンドウが破棄されるときに送信されます。 DestroyWindow 関数は、破棄されるウィンドウの子ウィンドウを破棄します。 WM_NCDESTROY メッセージは、ウィンドウが破棄される直前に送信されます。

少なくとも、ウィンドウ プロシージャは、WM_PAINT メッセージを処理してそれ自体を描画する必要があります。 通常は、マウスとキーボードのメッセージも処理する必要があります。 個々のメッセージの説明を参照して、ウィンドウ プロシージャがそれらを処理する必要があるかどうかを判断します。

アプリケーションは、メッセージの処理の一環として、DefWindowProc 関数を呼び出すことができます。 このような場合、アプリケーションは、DefWindowProc にメッセージ渡す前にメッセージ パラメーターを変更するか、独自の操作を実行した後に既定の処理を続行できます。

ダイアログ ボックス プロシージャは、WM_CREATE メッセージではなく WM_INITDIALOG メッセージを受け取り、未処理のメッセージを DefDlgProc 関数に渡しません。 それ以外の場合、ダイアログ ボックス プロシージャはウィンドウ プロシージャとまったく同じです。

Window プロシージャと Window クラスの関連付け

クラスを登録するときに、ウィンドウ プロシージャをウィンドウ クラスに関連付けます。 WNDCLASS 構造体にクラスに関する情報を入力する必要があり、lpfnWndProc メンバー ウィンドウ プロシージャのアドレスを指定する必要があります。 クラスを登録するには、の WNDCLASS 構造体のアドレスを RegisterClass 関数に渡します。 ウィンドウ クラスが登録されると、そのクラスで作成された新しいウィンドウごとに、ウィンドウ プロシージャが自動的に関連付けられます。

次の例は、前の例のウィンドウ プロシージャをウィンドウ クラスに関連付ける方法を示しています。

int APIENTRY WinMain( 
    HINSTANCE hinstance,  // handle to current instance 
    HINSTANCE hinstPrev,  // handle to previous instance 
    LPSTR lpCmdLine,      // address of command-line string 
    int nCmdShow)         // show-window type 
{ 
    WNDCLASS wc; 
 
    // Register the main window class. 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = (WNDPROC) MainWndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance = hinstance; 
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName =  "MainMenu"; 
    wc.lpszClassName = "MainWindowClass"; 
 
    if (!RegisterClass(&wc)) 
       return FALSE; 
 
    // 
    // Process other messages. 
    // 
 
} 

ウィンドウのサブクラス化

ウィンドウのインスタンスをサブクラス化するには、SetWindowLong 関数を呼び出し、ウィンドウへのハンドルを指定して、GWL_WNDPROC フラグとサブクラス プロシージャへのポインターをサブクラス化します。 SetWindowLong は、元のウィンドウ プロシージャへのポインターを返します。このポインターを使用して、元のプロシージャにメッセージを渡します。 サブクラス ウィンドウ プロシージャは、元のウィンドウ プロシージャを呼び出すために、CallWindowProc 関数を使用する必要があります。

手記

32 ビットバージョンと 64 ビット バージョンの両方の Windows と互換性のあるコードを記述するには、SetWindowLongPtr 関数を使用します。

 

次の例は、ダイアログ ボックスで編集コントロールのインスタンスをサブクラス化する方法を示しています。 サブクラス ウィンドウ プロシージャを使用すると、コントロールが入力フォーカスを持つたびに、Enter キーと TAB キーを含むすべてのキーボード入力をエディット コントロールで受け取ります。

WNDPROC wpOrigEditProc; 
 
LRESULT APIENTRY EditBoxProc(
    HWND hwndDlg, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    HWND hwndEdit; 
 
    switch(uMsg) 
    { 
        case WM_INITDIALOG: 
            // Retrieve the handle to the edit control. 
            hwndEdit = GetDlgItem(hwndDlg, ID_EDIT); 
 
            // Subclass the edit control. 
            wpOrigEditProc = (WNDPROC) SetWindowLong(hwndEdit, 
                GWL_WNDPROC, (LONG) EditSubclassProc); 
            // 
            // Continue the initialization procedure. 
            // 
            return TRUE; 
 
        case WM_DESTROY: 
            // Remove the subclass from the edit control. 
            SetWindowLong(hwndEdit, GWL_WNDPROC, 
                (LONG) wpOrigEditProc); 
            // 
            // Continue the cleanup procedure. 
            // 
            break; 
    } 
    return FALSE; 
        UNREFERENCED_PARAMETER(lParam); 
} 
 
// Subclass procedure 
LRESULT APIENTRY EditSubclassProc(
    HWND hwnd, 
    UINT uMsg, 
    WPARAM wParam, 
    LPARAM lParam) 
{ 
    if (uMsg == WM_GETDLGCODE) 
        return DLGC_WANTALLKEYS; 
 
    return CallWindowProc(wpOrigEditProc, hwnd, uMsg, 
        wParam, lParam); 
}