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


Tudnivalók az ablakeljárásokról

Minden ablak egy adott ablakosztály tagja. Az ablakosztály határozza meg az egyes ablakok által az üzenetek feldolgozásához használt alapértelmezett ablakeljárást. Az ugyanabba az osztályba tartozó összes ablak ugyanazt az alapértelmezett ablakeljárást használja. A rendszer például egy ablakeljárást határoz meg a kombinált listaosztályhoz (KOMBINÁLT LISTA); ezután az összes kombinált lista ezt az ablak eljárást használja.

Az alkalmazások általában legalább egy új ablakosztályt és annak kapcsolódó ablakeljárását regisztrálják. Az osztály regisztrálása után az alkalmazás számos ablakot hozhat létre az adott osztályból, amelyek mindegyike ugyanazt az ablakeljárást használja. Mivel ez azt jelenti, hogy egyszerre több forrás is meghívhatja ugyanazt a kódot, óvatosnak kell lennie a megosztott erőforrások ablakos eljárásból történő módosításakor. További információ: ablakosztályok.

A párbeszédpanelek ablakeljárásai (más néven párbeszédpanel-eljárások) hasonló szerkezettel rendelkeznek, és a szokásos ablakeljárásokhoz hasonlóan működnek. Az ebben a szakaszban szereplő ablakeljárásokra vonatkozó összes pont a párbeszédpaneles eljárásokra is vonatkozik. További információ: párbeszédpanelek.

Ez a szakasz a következő témaköröket ismerteti.

Az ablakeljárás felépítése

Az ablakeljárás olyan függvény, amely négy paraméterrel rendelkezik, és aláírt értéket ad vissza. A paraméterek egy ablakfogópontból, egy UINT üzenetazonosítóból, valamint két, WPARAM és LPARAM adattípussal deklarált üzenetparaméterből állnak. További információ: WindowProc.

Az üzenetparaméterek gyakran tartalmaznak információt az alacsony és a nagy sorrendű szavakban is. Az alkalmazás több makróval is kinyerhet információkat az üzenetparaméterekből. A LOWORD makró például kinyeri az alacsonyrendű szót (0–15. bit) egy üzenetparaméterből. Más makrók közé tartozik HIWORD, LOBYTEés HIBYTE makró.

A visszatérési érték értelmezése az adott üzenettől függ. A megfelelő visszatérési érték meghatározásához tekintse meg az egyes üzenetek leírását.

Mivel az ablakeljárások rekurzív módon hívhatóak meg, fontos minimalizálni az általa használt helyi változók számát. Az egyes üzenetek feldolgozásakor az alkalmazásnak az ablakeljáráson kívüli függvényeket kell meghívnia, hogy elkerülje a helyi változók túlzott használatát, ami a verem túlcsordulását okozhatja mély rekurzió során.

Alapértelmezett ablakeljárás

Az alapértelmezett ablakeljárási függvény, a DefWindowProc határozza meg az összes ablak által megosztott alapvető viselkedést. Az alapértelmezett ablakművelet biztosítja az ablak minimális funkcióit. Az alkalmazás által definiált ablakos eljárásnak át kell adnia azokat az üzeneteket, amelyeket nem dolgoz fel a DefWindowProc függvénynek az alapértelmezett feldolgozáshoz.

Ablakelrendezés alosztályozása

Amikor egy alkalmazás létrehoz egy ablakot, a rendszer lefoglal egy memóriablokkot az ablakra vonatkozó információk tárolásához, beleértve az ablak üzeneteit feldolgozó ablak eljárás címét is. Amikor a rendszernek üzenetet kell átadnia az ablaknak, megkeresi az ablakspecifikus információkat az ablakeljárás címére vonatkozóan, és átadja az üzenetet az adott eljárásnak.

alosztályozása olyan technika, amely lehetővé teszi, hogy az alkalmazás elfogja és feldolgozhassa az adott ablakban küldött vagy közzétett üzeneteket, mielőtt az ablaknak lehetősége nyílik arra, hogy feldolgozhassa őket. Egy ablak alosztályozásával az alkalmazás bővítheti, módosíthatja vagy figyelheti az ablak viselkedését. Az alkalmazások a globális rendszerosztályhoz tartozó ablakokat, például szerkesztési vezérlőt vagy listamezőt alosztályozzák. Egy alkalmazás például átsorolhat egy szerkesztési vezérlőt, hogy a vezérlő ne fogadjon el bizonyos karaktereket. Egy másik alkalmazáshoz tartozó ablakot vagy osztályt azonban nem lehet alosztályba sorolni. Minden alosztályozást ugyanazon a folyamaton belül kell végrehajtani.

Az alkalmazás alosztályozza az ablakot úgy, hogy az ablak eredeti ablakeljárásának címét kicseréli egy új ablakeljárás címére, amelyet alosztály-eljárásnakneveznek. Ezt követően a szubosztály eljárás megkapja az ablakhoz érkező üzeneteket, amelyeket küldtek vagy feladtak.

Az alosztály eljárása három műveletet hajthat végre egy üzenet fogadásakor: átadhatja az üzenetet az eredeti ablakműveletnek, módosíthatja és átadhatja az eredeti ablak eljárásának, vagy feldolgozhatja az üzenetet, és nem továbbíthatja az eredeti ablakműveletnek. Ha az alosztály-eljárás feldolgoz egy üzenetet, akkor azt az üzenetet az eredeti ablakeljárásnak történő továbbítása előtt, után, vagy mind előtt és után is meg tudja tenni.

A rendszer kétféle alosztályozást biztosít: példány és globális. Az -példányok alosztályozása során az alkalmazás lecseréli az ablak egy példányának ablakeljárási címét. Egy alkalmazásnak példány-alosztályozást kell használnia egy meglévő ablak alosztályozásához. globális alosztályozásiesetén az alkalmazás lecseréli az ablakeljárás címét az ablakosztály WNDCLASSEX szerkezetében. Az osztálysal létrehozott összes további ablak rendelkezik az alosztály eljárásának címével, de az osztály meglévő ablakait nem érinti.

Példány alosztályozása

Az alkalmazások az SetWindowLongPtr függvény használatával alosztályozza az ablak egy példányát. Az alkalmazás átadja a GWL_WNDPROC jelzőt, az ablak fogópontját, amelyet alosztályozni kell, és az alosztályozó eljárás címét a SetWindowLongPtr . Az alosztályozati eljárás az alkalmazás végrehajtható fájljában vagy EGY DLL-ben is elhelyezhető.

A GWL_WNDPROC zászló átadásakor SetWindowLongPtr az ablak eredeti eljárásának címét adja vissza. Az alkalmazásnak mentenie kell ezt a címet a CallWindowProc függvény későbbi hívásai során, hogy az elfogott üzeneteket továbbíthassa az eredeti ablakeljárásnak. Az alkalmazásnak az eredeti ablakeljárási címmel is rendelkeznie kell az alosztály ablakból való eltávolításához. Az alosztály eltávolításának végrehajtásához az alkalmazás ismét meghívja a SetWindowLongPtr függvényt, átadva az eredeti ablakeljárás címét a GWL_WNDPROC jelzővel és az ablak fogantyúját.

A rendszer globális osztályait a rendszer birtokolja, és a vezérlők jellemzői a rendszer egyik verziójáról a következőre változhatnak. Ha az alkalmazásnak alá kell sorolnia egy globális rendszerosztályhoz tartozó ablakot, előfordulhat, hogy a fejlesztőnek frissítenie kell az alkalmazást a rendszer új verziójának kiadásakor.

Mivel a példányok alosztályozása egy ablak létrehozása után történik, nem adhat hozzá további bájtokat az ablakhoz. Azokat az alkalmazásokat, amelyek egy ablakot alosztályba sorolnak, az ablak tulajdonságlistájának használatával kell tárolniuk az alosztályozott ablak egy példányához szükséges adatokat. További információ: Ablak tulajdonságai.

Amikor egy alkalmazás alosztályoz egy alosztályozott ablakot, el kell távolítania az alosztályokat fordított sorrendben. Ha az eltávolítási sorrend nincs megfordítva, előfordulhat, hogy nem helyreállítható rendszerhiba lép fel.

Globális alosztályozás

Az ablakosztály globális alosztályba való besorolásához az alkalmazásnak rendelkeznie kell egy fogópontkal az osztály egy ablakához. Az alkalmazásnak a fogantyúra is szüksége van az alosztály eltávolításához. Ahhoz, hogy megkapja a fogantyút, az alkalmazás jellemzően létrehoz egy elrejtett ablakot a besorolt osztály alosztályozásához. A leíró beszerzése után az alkalmazás meghívja a SetClassLongPtr függvényt, megadva a leírót, a GCL_WNDPROC jelzőt és az alosztályozási eljárás címét. SetClassLongPtr az osztály eredeti ablakának címét adja vissza.

Az eredeti ablakeljárási cím a globális alosztályozásban ugyanúgy használatos, mint a példányok alosztályozásában. Az alosztályozó eljárás az üzeneteket az eredeti ablakműveletbe továbbítja CallWindowProcmeghívásával. Az alkalmazás eltávolítja az alosztályt az ablakosztályból úgy, hogy újra meghívja SetClassLongPtr, megadva az eredeti ablakeljárás címét, a GCL_WNDPROC jelzőt és a leírót az alosztályba tartozó osztály egy ablakára. Egy olyan alkalmazásnak, amely globálisan alásorol egy vezérlőosztályt, el kell távolítania az alosztályt az alkalmazás leállásakor; ellenkező esetben helyreállíthatatlan rendszerhiba léphet fel.

A globális alosztályozásra ugyanazok a korlátozások vonatkoznak, mint a példányok alosztályozására, valamint néhány további korlátozásra. Az alkalmazások nem használhatják az extra bájtokat sem az osztályhoz, sem az ablakpéldányhoz anélkül, hogy pontosan tudnák, hogy az eredeti ablakeljárás hogyan használja őket. Ha az alkalmazásnak adatokat kell társítania egy ablakhoz, akkor az ablaktulajdonságokat kell használnia.

Ablakeljárás szuperosztályozása

superclassing egy olyan technika, amellyel az alkalmazás létrehozhat egy új ablakosztályt a meglévő osztály alapvető funkcióival, valamint az alkalmazás által biztosított fejlesztésekkel. A szuperosztály egy alaposztálynevű meglévő ablakosztályon alapul. Az alaposztály gyakran globális rendszerszintű ablakosztály, például szerkesztési vezérlő, de bármely ablakosztály lehet.

Egy szuperosztálynak van saját ablakeljárása, amelyet szuperosztály-eljárásnak neveznek. A szuperosztályos eljárás három műveletet hajthat végre az üzenet fogadásakor: Átadhatja az üzenetet az eredeti ablak eljárásának, módosíthatja és átadhatja az eredeti ablak eljárásának, vagy feldolgozhatja az üzenetet, és nem továbbíthatja az eredeti ablakműveletnek. Ha a szuperklasszikus eljárás feldolgoz egy üzenetet, azt az üzenet előtt, után vagy azt követően is megteheti, hogy az üzenetet átadja az eredeti ablakműveletnek.

Az alosztály-eljárástól eltérően a szuperosztályozó eljárás képes feldolgozni az ablaklétrehozási üzeneteket (WM_NCCREATE, WM_CREATEstb.), de át kell adnia őket az eredeti alaposztályablak-eljárásnak is, hogy az alaposztályablak-eljárás végrehajthassa az inicializálási eljárást.

Az ablakosztályok felülosztályozásához az alkalmazás először meghívja a GetClassInfoEx függvényt az alaposztály adatainak lekéréséhez. GetClassInfoEx egy WNDCLASSEX struktúrát tölt ki az alaposztály WNDCLASSEX struktúrájának értékeivel. Ezután az alkalmazás átmásolja a saját példányleíróját a hInstanceWNDCLASSEX struktúrájának tagjába, és a szuperosztály nevét a lpszClassName tagba másolja. Ha az alaposztály rendelkezik menüvel, az alkalmazásnak meg kell adnia egy új menüt ugyanazokkal a menüazonosítókkal, és át kell másolnia a menü nevét az lpszMenuName tagba. Ha a szuperosztály-eljárás feldolgozza a WM_COMMAND üzenetet, és nem továbbítja azt az alaposztály ablakos eljárásának, a menünek nem kell megfelelő azonosítókkal rendelkeznie. GetClassInfoEx nem adja vissza a(z) lpszMenuName, lpszClassName, vagy hInstance tagját a WNDCLASSEX struktúrának.

Az alkalmazásnak meg kell adnia az WNDCLASSEX struktúrájának lpfnWndProc tagját is. A GetClassInfoEx függvény kitölti ezt a tagot az osztály eredeti ablak eljárásának címével. Az alkalmazásnak mentenie kell ezt a címet, hogy üzeneteket továbbítson az eredeti ablakeljárásnak, majd másolja a szuperosztályozott eljárás címét az lpfnWndProc tagba. Az alkalmazás szükség esetén módosíthatja a WNDCLASSEX struktúrájának bármely más tagját. Miután kitöltötte a WNDCLASSEX struktúrát, az alkalmazás regisztrálja a szuperosztályt úgy, hogy átadja a struktúra címét a RegisterClassEx függvénynek. A szuperosztály ezután használható az ablakok létrehozására.

Mivel a szuperosztályozás regisztrál egy új ablakosztályt, az alkalmazás hozzáadhatja az extra osztálybájtokat és az extra ablakbájtokat is. Az ősosztály nem használhatja az alaposztály vagy az ablak eredeti extra bájtjait ugyanazokért az okokért, amiért egy példány alosztálya vagy egy globális alosztály nem használhatja őket. Ha az alkalmazás további bájtokat ad hozzá a használathoz az osztályhoz vagy az ablakpéldányhoz, akkor az eredeti alaposztály által használt további bájtok számához képest a további bájtokra kell hivatkoznia. Mivel az alaposztály által használt bájtok száma az alaposztály egyik verziójától a következőig változhat, a szuperosztály saját extra bájtjainak kezdő eltolása az alaposztály egyik verziójától a következőig is változhat.