Megosztás:


Alosztályozási vezérlők

Ha egy vezérlő szinte mindent megtesz, amire szüksége van, de még néhány funkcióra van szüksége, az alosztályozással módosíthatja vagy hozzáadhatja az eredeti vezérlőt. Az alosztályok rendelkezhetnek egy meglévő osztály összes funkcióval, valamint minden további funkcióval, amelyet meg szeretne adni.

Ez a dokumentum az alosztályok létrehozásának módját ismerteti, és az alábbi témaköröket tartalmazza.

Alosztályozási vezérlők a 6-os verzió ComCtl32.dll előtt

Egy vezérlőt alosztályba helyezhet, és a felhasználói adatokat egy vezérlőn belül tárolhatja. Ezt akkor teheti meg, ha a ComCtl32.dll 6-os verzió előtti verzióit használja. A ComCtl32.dllkorábbi verzióival rendelkező alosztályok létrehozása bizonyos hátrányokkal jár.

Egy új vezérlő létrehozásához a legjobb, ha a Windows egyik gyakori vezérlőjével kezdi, és kiterjeszti egy adott igénynek megfelelően. Egy vezérlő kibővítéséhez hozzon létre egy vezérlőt, és cserélje le a meglévő ablakeljárását egy újra. Az új eljárás elfogja a vezérlő üzeneteit, és vagy cselekszik rajtuk, vagy átadja őket az alapértelmezett feldolgozás eredeti eljárásának. A SetWindowLong vagy SetWindowLongPtr függvénnyel cserélje le a vezérlő WNDPROC-ját. Az alábbi kódminta bemutatja, hogyan lehet lecserélni a WNDPROC-t.

OldWndProc = (WNDPROC)SetWindowLongPtr (hButton,
GWLP_WNDPROC, (LONG_PTR)NewWndProc);

Felhasználói adatok tárolása

Előfordulhat, hogy a felhasználói adatokat külön ablakban szeretné tárolni. Ezeket az adatokat az új ablakos eljárás felhasználhatja annak meghatározására, hogyan rajzolhatja meg a vezérlőt, vagy hol küldhet bizonyos üzeneteket. Az adatok használatával például egy C++ osztálymutatót tárolhat a vezérlőt képviselő osztályhoz. Az alábbi kódminta bemutatja, hogyan használható SetProp az adatok ablakkal való tárolására.

SetProp (hwnd, TEXT("MyData"), (HANDLE)pMyData);

A régi alosztályozási módszer hátrányai

Az alábbi lista rámutat a vezérlőelemek alosztályozására korábban ismertetett módszer használatának néhány hátrányára.

  • Az ablakos eljárás csak egyszer cserélhető le.
  • A létrehozás után nehéz eltávolítani egy alosztályt.
  • A privát adatok ablakokkal való társítása nem hatékony.
  • Ha egy alosztálylánc következő eljárását szeretné meghívni, nem tudja átalakítani és meghívni a régi ablak eljárást, hanem a CallWindowProc függvénnyel kell meghívnia.

Alosztályozási vezérlők ComCtl32.dll 6-os verzióval

Jegyzet

A ComCtl32.dll 6-os verzió csak Unicode. A ComCtl32.dll 6-os verzió által támogatott közös vezérlőket nem szabad ANSI-ablakműveletekkel alásorolni (vagy átsorolni).

 

ComCtl32.dll 6-os verzió négy olyan függvényt tartalmaz, amelyek megkönnyítik az alosztályok létrehozását, és kiküszöbölik a korábban tárgyalt hátrányokat. Az új függvények több referenciaadat-készlettel rendelkező felügyeletet foglalnak magában, ezért a fejlesztő a programozási funkciókra összpontosíthat, nem pedig az alosztályok kezelésére. Az alosztályozási függvények a következők:

SetWindowSubclass

Ez a függvény először egy ablak alosztályára szolgál. Minden alosztályt egyedileg azonosít a pfnSubclass címe és a uIdSubclass. Mindkettő a SetWindowSubclass függvény paramétere. Több alosztály is használhatja ugyanazt az alosztály-eljárást, és az azonosító azonosítja az egyes hívásokat. A referenciaadatok módosításához további hívásokat kezdeményezhet a SetWindowSubclass-re. A fontos előnye, hogy minden alosztálypéldány saját referenciaadatokkal rendelkezik.

Az alosztály-eljárás deklarálása kissé eltér a szokásos ablakos eljárástól, mivel két további adatrészletet is tartalmaznia kell: az alosztály azonosítóját és a referenciaadatokat. A következő függvénydeklaráció utolsó két paramétere ezt mutatja.

LRESULT CALLBACK MyWndProc (HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass,
DWORD_PTR dwRefData);

Minden alkalommal, amikor az új ablak eljárás üzenetet kap, mellékosztály-azonosítót és referenciaadatokat tartalmaz.

Jegyzet

Az eljárásnak átadott összes sztring Unicode-sztring, még akkor is, ha a Unicode nincs megadva előfeldolgozó-definícióként.

 

Az alábbi példa egy alosztályozott vezérlőelem ablakeljárásának vázát mutatja be.

LRESULT CALLBACK OwnerDrawButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam,
                               LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    switch (uMsg)
    {
    case WM_PAINT:
        .
        .
        .
        return TRUE;
    // Other cases...
    } 
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

Az ablakeljárás a párbeszédpanel WM_INITDIALOG kezelőjében található vezérlőelemhez csatolható az alábbi példában látható módon.

case WM_INITDIALOG:
{
    HWND button = GetDlgItem(hDlg, IDC_OWNERDRAWBUTTON);
    SetWindowSubclass(button, OwnerDrawButtonProc, 0, 0);
    return TRUE;
}

GetWindowSubclass

Ez a függvény egy alosztály adatait lekérdezi. A GetWindowSubclass használatával például hozzáférhet a referenciaadatokhoz.

RemoveWindowSubclass

Ez a függvény eltávolítja az alosztályokat. RemoveWindowSubclass a SetWindowSubclass kombinációjával lehetővé teszi az alosztályok dinamikus hozzáadását és eltávolítását.

DefSubclassProc

A DefSubclassProc függvény meghívja az alosztálylánc következő kezelőját. A függvény a megfelelő azonosítót és referenciaadatokat is lekéri, és átadja az adatokat a következő ablak eljárásának.