Menggunakan Prosedur Jendela

Bagian ini menjelaskan cara melakukan tugas berikut yang terkait dengan prosedur jendela.

Merancang Prosedur Jendela

Contoh berikut menunjukkan struktur prosedur jendela umum. Prosedur jendela menggunakan argumen pesan dalam pernyataan pengalih dengan pesan individual yang ditangani oleh pernyataan kasus terpisah. Perhatikan bahwa setiap kasus mengembalikan nilai tertentu untuk setiap pesan. Untuk pesan yang tidak diproses, prosedur jendela memanggil fungsi 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; 
} 

Pesan WM_NCCREATE dikirim tepat setelah jendela Anda dibuat, tetapi jika aplikasi merespons pesan ini dengan mengembalikan FALSE, fungsi CreateWindowEx gagal. Pesan WM_CREATE dikirim setelah jendela Anda dibuat.

Pesan WM_DESTROY dikirim ketika jendela Anda akan dihancurkan. Fungsi DestroyWindow mengurus menghancurkan jendela anak mana pun dari jendela yang dihancurkan. Pesan WM_NCDESTROY dikirim tepat sebelum jendela dihancurkan.

Setidaknya, prosedur jendela harus memproses pesan WM_PAINT untuk menggambar dirinya sendiri. Biasanya, ini juga harus menangani pesan mouse dan keyboard. Lihat deskripsi pesan individual untuk menentukan apakah prosedur jendela Anda harus menanganinya.

Aplikasi Anda dapat memanggil fungsi DefWindowProc sebagai bagian dari pemrosesan pesan. Dalam kasus seperti itu, aplikasi dapat memodifikasi parameter pesan sebelum meneruskan pesan ke DefWindowProc, atau dapat dilanjutkan dengan pemrosesan default setelah melakukan operasinya sendiri.

Prosedur kotak dialog menerima pesan WM_INITDIALOG alih-alih pesan WM_CREATE dan tidak meneruskan pesan yang tidak diolah ke fungsi DefDlgProc . Jika tidak, prosedur kotak dialog sama persis dengan prosedur jendela.

Mengaitkan Prosedur Jendela dengan Kelas Jendela

Anda mengaitkan prosedur jendela dengan kelas jendela saat mendaftarkan kelas. Anda harus mengisi struktur WNDCLASS dengan informasi tentang kelas , dan anggota lpfnWndProc harus menentukan alamat prosedur jendela. Untuk mendaftarkan kelas, teruskan alamat struktur WNDCLASS ke fungsi RegisterClass . Setelah kelas jendela terdaftar, prosedur jendela secara otomatis dikaitkan dengan setiap jendela baru yang dibuat dengan kelas tersebut.

Contoh berikut menunjukkan cara mengaitkan prosedur jendela dalam contoh sebelumnya dengan kelas jendela.

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. 
    // 
 
} 

Subkelas Jendela

Untuk mensubkelas instans jendela, panggil fungsi SetWindowLong dan tentukan handel ke jendela untuk mensubkelas bendera GWL_WNDPROC dan penunjuk ke prosedur subkelas. SetWindowLong mengembalikan penunjuk ke prosedur jendela asli; gunakan penunjuk ini untuk meneruskan pesan ke prosedur asli. Prosedur jendela subkelas harus menggunakan fungsi CallWindowProc untuk memanggil prosedur jendela asli.

Catatan

Untuk menulis kode yang kompatibel dengan Windows versi 32-bit dan 64-bit, gunakan fungsi SetWindowLongPtr .

 

Contoh berikut menunjukkan cara mensubkelas instans kontrol edit dalam kotak dialog. Prosedur jendela subkelas memungkinkan kontrol edit menerima semua input keyboard, termasuk tombol ENTER dan TAB, setiap kali kontrol memiliki fokus input.

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); 
}