Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Elk venster is lid van een bepaalde vensterklasse. De vensterklasse bepaalt de standaardvensterprocedure die een afzonderlijk venster gebruikt om de berichten te verwerken. Alle vensters die tot dezelfde klasse behoren, gebruiken dezelfde standaardvensterprocedure. Het systeem definieert bijvoorbeeld een vensterprocedure voor de klasse keuzelijst met invoervak (COMBOBOX); alle keuzelijsten met invoervak gebruiken die vensterprocedure.
Een toepassing registreert doorgaans ten minste één nieuwe vensterklasse en de bijbehorende vensterprocedure. Na het registreren van een klasse kan de toepassing veel vensters van die klasse maken, die allemaal dezelfde vensterprocedure gebruiken. Omdat dit betekent dat meerdere bronnen tegelijkertijd hetzelfde codefragment kunnen aanroepen, moet u voorzichtig zijn bij het wijzigen van gedeelde resources vanuit een vensterprocedure. Zie Vensterklassenvoor meer informatie.
Vensterprocedures voor dialoogvensters (dialoogvensterprocedures genoemd) hebben een vergelijkbare structuur en functioneren als normale vensterprocedures. Alle punten die verwijzen naar vensterprocedures in deze sectie zijn ook van toepassing op dialoogvensterprocedures. Zie dialoogvenstersvoor meer informatie.
In deze sectie worden de volgende onderwerpen besproken.
- structuur van een vensterprocedure
- standaardvensterprocedure
- subklasse van de vensterprocedure
- Vensterprocedure superklassen
Structuur van een vensterprocedure
Een vensterprocedure is een functie met vier parameters en retourneert een ondertekende waarde. De parameters bestaan uit een venstergreep, een UINT bericht-id en twee berichtparameters die zijn gedeclareerd met de WPARAM- en LPARAM gegevenstypen. Zie WindowProcvoor meer informatie.
Berichtparameters bevatten vaak informatie in zowel de lage volgorde als de woorden in hoge volgorde. Er zijn verschillende macro's die een toepassing kan gebruiken om informatie uit de berichtparameters te extraheren. Met de LOWORD- macro wordt bijvoorbeeld het woord met lage volgorde (bits 0 tot en met 15) uit een berichtparameter geëxtraheerd. Andere macro's zijn HIWORD-, LOBYTE-en HIBYTE-macro.
De interpretatie van de retourwaarde is afhankelijk van het specifieke bericht. Raadpleeg de beschrijving van elk bericht om de juiste retourwaarde te bepalen.
Omdat het mogelijk is om een vensterprocedure recursief aan te roepen, is het belangrijk om het aantal lokale variabelen dat wordt gebruikt, te minimaliseren. Bij het verwerken van afzonderlijke berichten moet een toepassing functies buiten de vensterprocedure aanroepen om overmatig gebruik van lokale variabelen te voorkomen, waardoor de stack mogelijk overloopt tijdens diepe recursie.
Standaardvensterprocedure
De standaardvensterprocedurefunctie, DefWindowProc definieert bepaald fundamenteel gedrag dat door alle vensters wordt gedeeld. De standaardvensterprocedure biedt de minimale functionaliteit voor een venster. Een door de toepassing gedefinieerde vensterprocedure moet berichten doorgeven die niet worden verwerkt naar de de functie DefWindowProc voor standaardverwerking.
Subklasse van vensterprocedure
Wanneer een toepassing een venster maakt, wijst het systeem een geheugenblok toe voor het opslaan van informatie die specifiek is voor het venster, inclusief het adres van de vensterprocedure waarmee berichten voor het venster worden verwerkt. Wanneer het systeem een bericht moet doorgeven aan het venster, wordt de vensterspecifieke informatie doorzocht naar het adres van de vensterprocedure en wordt het bericht doorgegeven aan die procedure.
Subklassen is een techniek waarmee een toepassing berichten kan onderscheppen en verwerken die naar een bepaald venster zijn verzonden of gepost voordat het venster deze kan verwerken. Door een venster te subklasseren, kan een toepassing het gedrag van het venster uitbreiden, wijzigen of bewaken. Een toepassing kan een venster dat hoort bij een globale klasse van het systeem subklasse, zoals een invoerveld of een lijstvak. Een toepassing kan bijvoorbeeld een bewerkingsbesturingselement subklassen geven om te voorkomen dat het besturingselement bepaalde tekens accepteert. U kunt echter geen venster of klasse subklassen die deel uitmaken van een andere applicatie. Alle subklassen moeten binnen hetzelfde proces worden uitgevoerd.
Een toepassing subklasseert een venster door het adres van de oorspronkelijke vensterprocedure te vervangen door het adres van een nieuwe vensterprocedure, die wordt genoemd de subklasseprocedure. Daarna ontvangt de subklasseprocedure alle berichten die naar het venster worden verzonden of gepost.
De subklasseprocedure kan drie acties ondernemen bij het ontvangen van een bericht: het bericht kan worden doorgegeven aan de oorspronkelijke vensterprocedure, het bericht wijzigen en doorgeven aan de oorspronkelijke vensterprocedure, of het bericht verwerken en niet doorgeven aan de oorspronkelijke vensterprocedure. Als de subklasseprocedure een bericht verwerkt, kan dit vóór, na of zowel vóór als na het bericht worden doorgegeven aan de oorspronkelijke vensterprocedure.
Het systeem biedt twee typen subklassen: exemplaar en globale. In exemplaarsubklassenvervangt een toepassing het vensterprocedureadres van één exemplaar van een venster. Een toepassing moet exemplaarsubklassen gebruiken om een bestaand venster te subklassen. In globale subklassevervangt een toepassing het adres van de vensterprocedure in de WNDCLASSEX structuur van een vensterklasse. Alle volgende vensters die met de klasse zijn gemaakt, hebben het adres van de subklasseprocedure, maar bestaande vensters van de klasse worden niet beïnvloed.
Instantiesubklassen
Een toepassing maakt een subklasse van een instantie van een venster met behulp van de SetWindowLongPtr functie. De toepassing geeft de vlag GWL_WNDPROC, de handle van het venster dat naar een subklasse moet worden omgezet, en het adres van de subklasseprocedure door aan SetWindowLongPtr. De subklasseprocedure kan zich in het uitvoerbare bestand of een DLL van de toepassing bevinden.
Wanneer de vlag GWL_WNDPROC is doorgegeven, retourneert SetWindowLongPtr het adres van de oorspronkelijke vensterprocedure van het venster. De toepassing moet dit adres opslaan en gebruiken bij volgende aanroepen van de CallWindowProc-functie om onderschepte berichten door te geven aan de oorspronkelijke vensterprocedure. De toepassing moet ook het oorspronkelijke adres van de vensterprocedure hebben om de subklasse uit het venster te verwijderen. Als u de subklasse wilt verwijderen, roept de toepassing SetWindowLongPtr opnieuw aan, waarbij het adres van de oorspronkelijke vensterprocedure wordt doorgegeven met de vlag GWL_WNDPROC en de ingang aan het venster.
Het systeem is eigenaar van de globale klassen van het systeem en aspecten van de besturingselementen kunnen veranderen van de ene versie van het systeem naar de volgende. Als de toepassing een venster moet subklassen hebben dat deel uitmaakt van een globale systeemklasse, moet de ontwikkelaar de toepassing mogelijk bijwerken wanneer er een nieuwe versie van het systeem wordt uitgebracht.
Omdat subklassen van exemplaren plaatsvinden nadat een venster is gemaakt, kunt u geen extra bytes toevoegen aan het venster. Toepassingen die een venster subklassen gebruiken, moeten de eigenschappenlijst van het venster gebruiken om gegevens op te slaan die nodig zijn voor een exemplaar van het subklassevenster. Zie Venstereigenschappenvoor meer informatie.
Wanneer een toepassing een subklassevenster classificeert, moeten de subklassen worden verwijderd in de omgekeerde volgorde die ze zijn uitgevoerd. Als de verwijderingsvolgorde niet wordt omgekeerd, kan er een onherstelbare systeemfout optreden.
Globale subklassen
Als u een vensterklasse globaal wilt subklassen, moet de toepassing een ingang hebben voor een venster van de klasse. De toepassing heeft ook de ingang nodig om de subklasse te verwijderen. Om de handle te verkrijgen, maakt een toepassing doorgaans een verborgen venster van de klasse die moet worden gesubklasseerd. Nadat de ingang is verkregen, roept de toepassing de SetClassLongPtr-functie aan, waarbij de ingang, de vlag GCL_WNDPROC en het adres van de subklasseprocedure worden opgegeven. SetClassLongPtr- retourneert het adres van de oorspronkelijke vensterprocedure voor de klasse.
Het oorspronkelijke adres van de vensterprocedure wordt gebruikt in globale subklassen op dezelfde manier als het wordt gebruikt in exemplaarsubklassen. De subklasseprocedure geeft berichten door aan de oorspronkelijke vensterprocedure door CallWindowProc-aan te roepen. De toepassing verwijdert de subklasse uit de vensterklasse door opnieuw SetClassLongPtr aan te roepen, met het adres van de oorspronkelijke vensterprocedure, de GCL_WNDPROC vlag, en de handle naar een venster van de klasse die wordt gesubklasseerd. Een toepassing die wereldwijd een besturingsklasse classeert, moet de subklasse verwijderen wanneer de toepassing wordt beëindigd; anders kan er een onherstelbare systeemfout optreden.
Globale subklassen hebben dezelfde beperkingen als subklassen van exemplaren, plus enkele aanvullende beperkingen. Een toepassing mag de extra bytes voor de klasse of de vensterinstantie niet gebruiken zonder precies te weten hoe de oorspronkelijke vensterprocedure deze gebruikt. Als de toepassing gegevens moet koppelen aan een venster, moet deze venstereigenschappen gebruiken.
Procedure voor vensters superclassing
Superclassing is een techniek waarmee een toepassing een nieuwe vensterklasse kan maken met de basisfunctionaliteit van de bestaande klasse, plus verbeteringen van de toepassing. Een superklasse is gebaseerd op een bestaande vensterklasse genaamd de basisklasse. Vaak is de basisklasse een globale systeemvensterklasse, zoals een besturingselement voor bewerken, maar dit kan elke vensterklasse zijn.
Een superklasse heeft een eigen vensterprocedure, de zogenaamde superklasseprocedure. De superklasseprocedure kan drie acties ondernemen bij het ontvangen van een bericht: het bericht kan worden doorgegeven aan de oorspronkelijke vensterprocedure, het bericht wijzigen en doorgeven aan de oorspronkelijke vensterprocedure, of het bericht verwerken en niet doorgeven aan de oorspronkelijke vensterprocedure. Als de superklasseprocedure een bericht verwerkt, kan dit vóór, na of zowel vóór als na het bericht worden doorgegeven aan de oorspronkelijke vensterprocedure.
In tegenstelling tot een subklasseprocedure kan een superklasseprocedure berichten voor het maken van vensters (WM_NCCREATE, WM_CREATEenzovoort) verwerken, maar moet deze ook worden doorgegeven aan de oorspronkelijke basisklassevensterprocedure, zodat de procedure voor het venster basisklasse de initialisatieprocedure kan uitvoeren.
Als u een vensterklasse wilt superklassen, roept een toepassing eerst de functie GetClassInfoEx aan om informatie over de basisklasse op te halen. GetClassInfoEx vult een WNDCLASSEX structuur met de waarden uit de WNDCLASSEX structuur van de basisklasse. Vervolgens kopieert de toepassing zijn eigen exemplaargreep in het hInstance-lid van de WNDCLASSEX structuur en kopieert de naam van de superklasse in het lpszClassName-lid. Als de basisklasse een menu heeft, moet de toepassing een nieuw menu met dezelfde menu-id's opgeven en de menunaam kopiëren naar de lpszMenuName lid. Als de superklasseprocedure het WM_COMMAND bericht verwerkt en het bericht niet doorgeeft aan de vensterprocedure van de basisklasse, hoeft het menu geen bijbehorende id's te hebben. GetClassInfoEx- retourneert de lpszMenuName, lpszClassNameof hInstance element van de WNDCLASSEX- structuur.
Een toepassing moet ook de lpfnWndProc- lid van de WNDCLASSEX- structuur instellen. De functie GetClassInfoEx vult dit lid met het adres van de oorspronkelijke vensterprocedure voor de klasse. De toepassing moet dit adres opslaan om berichten door te geven aan de oorspronkelijke vensterprocedure, en vervolgens het adres van de superklasseprocedure kopiëren naar het lid lpfnWndProc. De toepassing kan, indien nodig, andere leden van de WNDCLASSEX structuur wijzigen. Nadat de WNDCLASSEX structuur is ingevuld, registreert de toepassing de superklasse door het adres van de structuur door te geven aan de functie RegisterClassEx. De superklasse kan vervolgens worden gebruikt om vensters te maken.
Omdat het registreren van een nieuwe vensterklasse door superklassen mogelijk maakt om extra bytes toe te voegen, kan een toepassing zowel aan de extra klassebytes als aan de extra vensterbytes toevoegen. De superklasse mag niet de oorspronkelijke extra bytes voor de basisklasse of het venster gebruiken om dezelfde redenen dat een exemplaarsubklasse of een globale subklasse deze niet mag gebruiken. Als de toepassing extra bytes toevoegt voor eigen gebruik aan de klasse of vensterexemplaren, moet deze bovendien verwijzen naar de extra bytes relatief aan het aantal extra bytes dat door de oorspronkelijke basisklasse wordt gebruikt. Omdat het aantal bytes dat door de basisklasse wordt gebruikt, kan variëren van één versie van de basisklasse tot de volgende, kan de beginmarge voor de eigen extra bytes van de superklasse ook variëren van één versie van de basisklasse tot de volgende.