Megosztás a következőn keresztül:


Ablakeljárások használata

Ez a szakasz az ablakeljárásokkal kapcsolatos alábbi feladatokat ismerteti.

Ablakeljárás tervezése

Az alábbi példa egy tipikus ablakeljárás struktúráját mutatja be. Az ablakeljárás egy switch utasításban használja az üzenet argumentumot, ahol az egyes üzeneteket külön case utasítások kezelik. Figyelje meg, hogy minden eset egy adott értéket ad vissza az egyes üzenetekhez. A nem feldolgozott üzenetek esetében az ablakeljárás meghívja a DefWindowProc függvényt.

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

A WM_NCCREATE üzenetet az ablak létrehozása után küldi el a rendszer, de ha egy alkalmazás HAMISvisszaadásával válaszol erre az üzenetre, CreateWindowEx függvény meghiúsul. A WM_CREATE üzenet az ablak létrehozása után lesz elküldve.

A WM_DESTROY üzenet akkor lesz elküldve, ha az ablak hamarosan megsemmisül. A DestroyWindow függvény gondoskodik az éppen megsemmisített ablak gyermekablakainak kiiktatásáról. A WM_NCDESTROY üzenet éppen az ablak megsemmisítése előtt lesz elküldve.

Legalább egy ablak eljárásnak fel kell dolgoznia a WM_PAINT üzenetet, hogy kirajzolja magát. Általában az egér- és billentyűzetüzeneteket is kezelnie kell. Az egyes üzenetek leírásával megállapíthatja, hogy az ablakkezelési eljárásnak kell-e kezelnie azokat.

Az alkalmazás meghívhatja a DefWindowProc függvényt egy üzenet feldolgozása részeként. Ilyen esetben az alkalmazás módosíthatja az üzenet paramétereit, mielőtt továbbítaná az üzenetet DefWindowProc, vagy folytathatja az alapértelmezett feldolgozást a saját műveleteinek végrehajtása után.

A párbeszédpanel-eljárások WM_CREATE üzenet helyett WM_INITDIALOG üzenetet kapnak, és nem adnak át feldolgozatlan üzeneteket a DefDlgProc függvénynek. Ellenkező esetben a párbeszédpanel-eljárás pontosan megegyezik az ablakeljárással.

Ablakelrendezés társítása ablakosztályhoz

Az osztály regisztrálásakor az ablakeljárást egy ablakosztályhoz társítja. Be kell töltenie egy WNDCLASS struktúrát az osztály adataival, és az lpfnWndProc tagnak az ablakeljárás címét kell megadnia. Az osztály regisztrálásához adja át WNDCLASS struktúra címét a RegisterClass függvénynek. Az ablakosztály regisztrálása után a rendszer automatikusan társítja az ablakeljárást az adott osztályhoz létrehozott minden új ablakhoz.

Az alábbi példa bemutatja, hogyan társíthatja az ablakeljárást az előző példában egy ablakosztályhoz.

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

Ablak alosztályozása

Ablakpéldány alosztályozásához hívja meg a SetWindowLong függvényt, és adja meg az ablak fogópontját, a GWL_WNDPROC jelzőt, valamint az alosztályozó eljárásra mutató mutatót. SetWindowLong egy mutatót ad vissza az eredeti ablakeljáráshoz; ezzel a mutatóval üzeneteket adhat át az eredeti eljárásnak. Az alosztályablak eljárásának az CallWindowProc függvénnyel kell meghívnia az eredeti ablakeljárást.

Jegyzet

A Windows 32 bites és 64 bites verzióival kompatibilis kód írásához használja a SetWindowLongPtr függvényt.

 

Az alábbi példa bemutatja, hogyan lehet egy szerkesztő vezérlő példányának alosztályát létrehozni egy párbeszédpanelen. Az alosztály ablakának eljárása lehetővé teszi, hogy a szerkesztési vezérlő minden billentyűzetbemenetet fogadjon, beleértve az ENTER és a TAB billentyűket is, amikor a vezérlő fókusza van.

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