Over vensterklassen
Elke vensterklasse heeft een bijbehorende vensterprocedure die wordt gedeeld door alle vensters van dezelfde klasse. De vensterprocedure verwerkt berichten voor alle vensters van die klasse en bepaalt daarom hun gedrag en uiterlijk. Zie Vensterproceduresvoor meer informatie.
Een proces moet een vensterklasse registreren voordat er een venster van die klasse kan worden gemaakt. Als u een vensterklasse registreert, worden een vensterprocedure, klassestijlen en andere klassekenmerken gekoppeld aan een klassenaam. Wanneer een proces een klassenaam opgeeft in de CreateWindow- of functie CreateWindowEx, maakt het systeem een venster met de vensterprocedure, stijlen en andere kenmerken die aan die klassenaam zijn gekoppeld.
In deze sectie worden de volgende onderwerpen besproken.
- typen vensterklassen
- hoe het systeem een vensterklasse zoekt
- een vensterklasse registreren
- elementen van een vensterklasse
Typen vensterklassen
Er zijn drie typen vensterklassen:
Deze typen verschillen in bereik en wanneer en hoe ze worden geregistreerd en vernietigd.
Systeemklassen
Een systeemklasse is een vensterklasse die door het systeem is geregistreerd. Veel systeemklassen zijn beschikbaar voor alle processen die moeten worden gebruikt, terwijl andere alleen intern door het systeem worden gebruikt. Omdat het systeem deze klassen registreert, kan een proces ze niet vernietigen.
Het systeem registreert de systeemklassen voor een proces de eerste keer dat een van de threads een gebruiker of een GDI-functie (Windows Graphics Device Interface) aanroept.
Elke toepassing ontvangt een eigen kopie van de systeemklassen. Alle 16-bits Windows-toepassingen in dezelfde VDM delen systeemklassen, net zoals bij 16-bits Windows.
In de volgende tabel worden de systeemklassen beschreven die beschikbaar zijn voor gebruik door alle processen.
Klas | Beschrijving |
---|---|
Knoop | De klas voor een knop. |
Keuzelijst met invoervak | De klasse voor een keuzelijst met invoervak. |
Bewerken | De klasse voor een besturingselement bewerken. |
Keuzelijst | De klasse voor een keuzelijst. |
MDIClient | De klasse voor een MDI-clientvenster. |
Schuifbalk | De klasse voor een schuifbalk. |
Statisch | De klasse voor een statisch besturingselement. |
In de volgende tabel worden de systeemklassen beschreven die alleen beschikbaar zijn voor gebruik door het systeem. Ze worden hier ter volledigheid vermeld.
Klas | Beschrijving |
---|---|
ComboLBox | De klasse voor de keuzelijst in een keuzelijst met invoervak. |
DDEMLEvent | De klasse voor DDEML-gebeurtenissen (Dynamic Data Exchange Management Library). |
Bericht | De klasse voor een venster met alleen berichten. |
#32768 | De klas voor een menu. |
#32769 | De klasse voor het bureaubladvenster. |
#32770 | De klasse voor een dialoogvenster. |
#32771 | De klasse voor het taakwisselvenster. |
#32772 | De klasse voor pictogramtitels. |
Globale klassen van toepassingen
Een toepassingsklasse is een vensterklasse die is geregistreerd door een uitvoerbaar bestand of DLL dat beschikbaar is voor alle andere modules in het proces. Uw .dll kan bijvoorbeeld de functie RegisterClassEx aanroepen om een vensterklasse te registreren waarmee een aangepast besturingselement wordt gedefinieerd als een globale toepassingsklasse, zodat een proces dat de .dll laadt exemplaren van het aangepaste besturingselement kan maken.
Als u een klasse wilt maken die in elk proces kan worden gebruikt, maakt u de vensterklasse in een .dll en laadt u de .dll in elk proces. Als u de .dll in elk proces wilt laden, voegt u de naam toe aan de AppInit_DLLs waarde in de volgende registersleutel:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows
Wanneer een proces wordt gestart, laadt het systeem de opgegeven .dll in de context van het zojuist gestarte proces voordat de invoerpuntfunctie wordt aangeroepen. De .dll moet de klasse registreren tijdens de initialisatieprocedure en de stijl CS_GLOBALCLASS opgeven. Zie Klassestijlenvoor meer informatie.
Gebruik de functie UnregisterClass om een globale toepassingsklasse te verwijderen en de bijbehorende opslag vrij te maken.
Lokale toepassingsklassen
Een lokale toepassingsklasse is een vensterklasse die door een uitvoerbaar bestand of .dll wordt geregistreerd voor exclusief gebruik. Hoewel u een willekeurig aantal lokale klassen kunt registreren, is het gebruikelijk om slechts één te registreren. Deze vensterklasse ondersteunt de vensterprocedure van het hoofdvenster van de toepassing.
Het systeem vernietigt een lokale klasse wanneer de module die deze heeft geregistreerd, wordt gesloten. Een toepassing kan ook de functie UnregisterClass gebruiken om een lokale klasse te verwijderen en de bijbehorende opslag vrij te maken.
Hoe het systeem een vensterklasse zoekt
Het systeem onderhoudt een lijst met structuren voor elk van de drie typen vensterklassen. Wanneer een toepassing de functie CreateWindow of CreateWindowEx aanroept om een venster met een opgegeven klasse te maken, gebruikt het systeem de volgende procedure om de klasse te zoeken.
- Zoek in de lijst met lokale toepassingsklassen naar een klasse met de opgegeven naam waarvan de exemplaaringang overeenkomt met de instantiehandgreep van de module. (Verschillende modules kunnen dezelfde naam gebruiken om lokale klassen in hetzelfde proces te registreren.)
- Als de naam zich niet in de lokale klassenlijst van de toepassing bevindt, zoekt u in de lijst met globale klassen van toepassingen.
- Als de naam zich niet in de algemene klassenlijst van de toepassing bevindt, zoekt u in de lijst met systeemklassen.
Alle vensters die door de toepassing zijn gemaakt, gebruiken deze procedure, inclusief vensters die door het systeem namens de toepassing zijn gemaakt, zoals dialoogvensters. Het is mogelijk om systeemklassen te overschrijven zonder dat dit van invloed is op andere toepassingen. Dat wil gezegd, een toepassing kan een lokale toepassingsklasse met dezelfde naam als een systeemklasse registreren. Dit vervangt de systeemklasse in de context van de toepassing, maar voorkomt niet dat andere toepassingen de systeemklasse gebruiken.
Een vensterklasse registreren
Een vensterklasse definieert de kenmerken van een venster, zoals de stijl, het pictogram, de cursor, het menu en de vensterprocedure. De eerste stap bij het registreren van een vensterklasse is het invullen van een WNDCLASSEX structuur met de vensterklassegegevens. Zie Elementen van een vensterklassevoor meer informatie. Geef vervolgens de structuur door aan de functie RegisterClassEx. Zie Vensterklassen gebruikenvoor meer informatie.
Als u een globale klasse van een toepassing wilt registreren, geeft u de CS_GLOBALCLASS stijl op in de stijl lid van de WNDCLASSEX- structuur. Geef bij het registreren van een lokale klasse van een toepassing niet de stijl CS_GLOBALCLASS op.
Als u de vensterklasse registreert met behulp van de ANSI-versie van RegisterClassEx, RegisterClassExA, vraagt de toepassing dat het systeem tekstparameters van berichten doorgeeft aan de vensters van de gemaakte klasse met behulp van de ANSI-tekenset; als u de klasse registreert met behulp van de Unicode-versie van RegisterClassEx, RegisterClassExW, vraagt de toepassing aan dat het systeem tekstparameters van berichten doorgeeft aan de vensters van de gemaakte klasse met behulp van de Unicode-tekenset. Met de functie IsWindowUnicode kunnen toepassingen query's uitvoeren op de aard van elk venster. Zie Conventies voor functieprototypesvoor meer informatie over ANSI- en Unicode-functies.
Het uitvoerbare bestand of dll-bestand dat de klasse heeft geregistreerd, is de eigenaar van de klasse. Het systeem bepaalt het eigendom van de klasse van de hInstance lid van de WNDCLASSEX structuur die wordt doorgegeven aan de RegisterClassEx- functie wanneer de klasse is geregistreerd. Voor DLL's moet het hInstance- lid de ingang zijn voor het .dll exemplaar.
De klasse wordt niet vernietigd wanneer de .dll die eigenaar is van de klasse wordt uitgeladen. Als het systeem daarom de vensterprocedure aanroept voor een venster van die klasse, veroorzaakt dit een schending van de toegang, omdat de .dll met de vensterprocedure niet meer in het geheugen is. Het proces moet alle vensters vernietigen die de klasse gebruiken voordat de .dll wordt uitgepakt en de UnregisterClass-functie aanroepen.
Elementen van een vensterklasse
De elementen van een vensterklasse definiëren het standaardgedrag van vensters die behoren tot de klasse. De toepassing die een vensterklasse registreert, wijst elementen toe aan de klasse door de juiste leden in te stellen in een WNDCLASSEX- structuur en de structuur door te geven aan de RegisterClassEx--functie. De functies GetClassInfoEx en GetClassLong halen informatie over een bepaalde vensterklasse op. De functie SetClassLong wijzigt elementen van een lokale of globale klasse die de toepassing al heeft geregistreerd.
Hoewel een volledige vensterklasse uit veel elementen bestaat, vereist het systeem alleen dat een toepassing een klassenaam, het adres van de vensterprocedure en een instantiehandgreep levert. Gebruik de andere elementen om standaardkenmerken te definiëren voor vensters van de klasse, zoals de vorm van de cursor en de inhoud van het menu voor het venster. U moet ongebruikte leden van de WNDCLASSEX-structuur initialiseren tot nul of NULL-. De vensterklasse-elementen worden weergegeven in de volgende tabel.
Element | Doel |
---|---|
klassenaam | Onderscheidt de klasse van andere geregistreerde klassen. |
adres van vensterprocedure | Wijs de functie aan die alle berichten verwerkt die naar vensters in de klasse worden verzonden en definieert het gedrag van het venster. |
instantie- | Identificeert de toepassing of .dll die de klasse heeft geregistreerd. |
klassecursor | Hiermee definieert u de muiscursor die het systeem weergeeft voor een venster van de klasse. |
klassepictogrammen | Hiermee definieert u het grote pictogram en het kleine pictogram. |
klasachtergrondborstel | Definieert de kleur en het patroon dat het clientgebied vult wanneer het venster wordt geopend of geschilderd. |
menu Klas | Hiermee geeft u het standaardmenu voor vensters die geen menu expliciet definiëren. |
klassestijlen | Definieert hoe u het venster bijwerkt nadat u het hebt verplaatst of het formaat ervan hebt gewijzigd, hoe u dubbelklikt op de muis, hoe u ruimte toewijst voor de apparaatcontext en andere aspecten van het venster. |
extra klassegeheugen | Hiermee geeft u de hoeveelheid extra geheugen in bytes op die het systeem moet reserveren voor de klasse. Alle vensters in de klasse delen het extra geheugen en kunnen deze gebruiken voor elk toepassingsgedefinieerde doel. Het systeem initialiseert dit geheugen naar nul. |
extra venstergeheugen | Hiermee geeft u de hoeveelheid extra geheugen, in bytes, dat het systeem moet reserveren voor elk venster dat deel uitmaakt van de klasse. Het extra geheugen kan worden gebruikt voor elk toepassingsgedefinieerde doel. Het systeem initialiseert dit geheugen naar nul. |
Klassenaam
Elke vensterklasse heeft een Klassenaam nodig om de ene klasse te onderscheiden van een andere klasse. Wijs een klassenaam toe door de lpszClassName- lid van de WNDCLASSEX-structuur in te stellen op het adres van een null-beëindigde tekenreeks waarmee de naam wordt opgegeven. Omdat vensterklassen specifiek zijn, moeten namen van vensterklassen alleen uniek zijn binnen hetzelfde proces. Omdat klassenamen ruimte in de privé atomtabel van het systeem innemen, moet u ook tekenreeksen voor klassenamen zo kort mogelijk houden.
De functie GetClassName haalt de naam op van de klasse waartoe een bepaald venster behoort.
Adres van vensterprocedure
Elke klasse heeft een adres voor vensterprocedure nodig om het toegangspunt van de vensterprocedure te definiëren die wordt gebruikt voor het verwerken van alle berichten voor vensters in de klasse. Het systeem geeft berichten door aan de procedure wanneer het venster taken moet uitvoeren, zoals het schilderen van het clientgebied of het reageren op invoer van de gebruiker. Een proces wijst een vensterprocedure toe aan een klasse door het adres ervan te kopiëren naar de lpfnWndProc lid van de WNDCLASSEX structuur. Zie Vensterproceduresvoor meer informatie.
Exemplaarhandgreep
Elke vensterklasse vereist een instantiehandgreep om de toepassing te identificeren of .dll die de klasse heeft geregistreerd. Voor het systeem zijn exemplaren nodig om alle modules bij te houden. Het systeem wijst een ingang toe aan elke kopie van een actief uitvoerbaar bestand of .dll.
Het systeem geeft een exemplaargreep door aan de invoerpuntfunctie van elk uitvoerbaar bestand (zie WinMain) en .dll (zie DllMain-). Het uitvoerbare bestand of .dll wijst deze instantiehandgreep toe aan de klasse door deze te kopiëren naar de hInstance lid van de WNDCLASSEX--structuur.
Klascursor
De klassecursor definieert de vorm van de cursor wanneer deze zich in het clientgebied van een venster in de klasse bevindt. De cursor wordt automatisch ingesteld op de opgegeven shape wanneer de cursor het clientgebied van het venster binnenkomt en ervoor zorgt dat deze shape behouden blijft terwijl deze zich in het clientgebied bevindt. Als u een cursorshape wilt toewijzen aan een vensterklasse, laadt u een vooraf gedefinieerde cursorshape met behulp van de functie LoadCursor en wijst u de geretourneerde cursorgreep toe aan de hCursor lid van de WNDCLASSEX- structuur. U kunt ook een aangepaste cursorresource opgeven en de functie LoadCursor gebruiken om deze te laden vanuit de resources van de toepassing.
Voor het systeem is geen klassecursor vereist. Als een toepassing de hCursor lid van de WNDCLASSEX-structuur instelt op NULL-, wordt er geen klassecursor gedefinieerd. In het systeem wordt ervan uitgegaan dat het venster de cursorshape instelt telkens wanneer de cursor naar het venster wordt verplaatst. Een venster kan de cursorshape instellen door de functie SetCursor- aan te roepen wanneer het venster het WM_MOUSEMOVE bericht ontvangt. Zie Cursorsvoor meer informatie over cursors.
Klassepictogrammen
Een klassepictogram is een afbeelding die het systeem gebruikt om een venster van een bepaalde klasse weer te geven. Een toepassing kan twee klassepictogrammen hebben: één groot en één klein. Het systeem geeft het grote klassepictogram van een venster weer in het venster taakschakelaar dat wordt weergegeven wanneer de gebruiker op Alt+Tab drukt en in de grote pictogramweergaven van de taakbalk en verkenner. Het kleine klaspictogram wordt weergegeven op de titelbalk van een venster en in de kleine pictogramweergaven van de taakbalk en Verkenner.
Als u een groot en klein pictogram wilt toewijzen aan een vensterklasse, geeft u de grepen op van de pictogrammen in de hIcon en hIconSm leden van de WNDCLASSEX structuur. De pictogramdimensies moeten voldoen aan de vereiste dimensies voor grote en kleine klassepictogrammen. Voor een pictogram van een grote klasse kunt u de vereiste dimensies bepalen door de SM_CXICON en SM_CYICON waarden op te geven in een aanroep van de functie GetSystemMetrics. Geef voor een klein klaspictogram de waarden SM_CXSMICON en SM_CYSMICON op. Zie Pictogrammenvoor meer informatie.
Als een toepassing de hIcon en hIconSm leden van de WNDCLASSEX- structuur instelt op NULL-, gebruikt het systeem het standaardtoepassingspictogram als de grote en kleine klassepictogrammen voor de vensterklasse. Als u een groot klaspictogram opgeeft, maar niet een klein pictogram, maakt het systeem een klein klassepictogram op basis van de grote. Als u echter een klein klassepictogram opgeeft, maar geen groot pictogram, gebruikt het systeem het standaardtoepassingspictogram als het pictogram van de grote klasse en het opgegeven pictogram als het pictogram voor kleine klassen.
U kunt het grote of kleine klaspictogram voor een bepaald venster overschrijven met behulp van het WM_SETICON bericht. U kunt het huidige pictogram voor grote of kleine klassen ophalen met behulp van het WM_GETICON bericht.
Klasachtergrondborstel
Een klasachtergrondborstel bereidt het clientgebied van een venster voor op volgende tekening door de toepassing. Het systeem gebruikt de kwast om het clientgebied te vullen met een effen kleur of patroon, waardoor alle vorige afbeeldingen van die locatie worden verwijderd, ongeacht of ze deel uitmaken van het venster of niet. Het systeem meldt een venster dat de achtergrond moet worden geschilderd door het WM_ERASEBKGND bericht naar het venster te verzenden. Zie Brushesvoor meer informatie.
Als u een achtergrondborstel wilt toewijzen aan een klasse, maakt u een borstel met behulp van de juiste GDI-functies en wijst u de geretourneerde borstelgreep toe aan de hbrBackground lid van de WNDCLASSEX structuur.
In plaats van een penseel te maken, kan een toepassing de hbrBackground lid instellen op een van de standaardsysteemkleurwaarden. Zie SetSysColorsvoor een lijst met standaardsysteemkleurwaarden.
Als u een standaardsysteemkleur wilt gebruiken, moet de toepassing de waarde van de achtergrondkleur met één verhogen. Bijvoorbeeld, COLOR_BACKGROUND + 1 is de achtergrondkleur van het systeem. U kunt ook de GetSysColorBrush functie gebruiken om een handgreep op te halen naar een borstel die overeenkomt met een standaardsysteemkleur en vervolgens de greep op te geven in de hbrBackground lid van de WNDCLASSEX structuur.
Het systeem vereist niet dat een vensterklasse een klasachtergrondborstel heeft. Als deze parameter is ingesteld op NULL-, moet het venster een eigen achtergrond schilderen wanneer het bericht WM_ERASEBKGND wordt ontvangen.
Menu Klas
Een klasmenu definieert het standaardmenu dat door de vensters in de klas moet worden gebruikt als er geen expliciet menu wordt gegeven wanneer de vensters worden gemaakt. Een menu is een lijst met opdrachten waaruit een gebruiker acties kan kiezen voor de toepassing die moet worden uitgevoerd.
U kunt een menu aan een klasse toewijzen door de lpszMenuName lid van de WNDCLASSEX-structuur in te stellen op het adres van een null-beëindigde tekenreeks waarmee de resourcenaam van het menu wordt opgegeven. In het menu wordt ervan uitgegaan dat het een resource in de opgegeven toepassing is. Het systeem laadt het menu automatisch wanneer dit nodig is. Als de menuresource wordt geïdentificeerd door een geheel getal en niet door een naam, kan de toepassing de lpszMenuName lid instellen op dat gehele getal door de macro MAKEINTRESOURCE- toe te passen voordat de waarde wordt toegewezen.
Voor het systeem is geen klasmenu vereist. Als een toepassing de lpszMenuName lid van de WNDCLASSEX structuur instelt op NULL-, hebben vensters in de klasse geen menubalken. Zelfs als er geen klasmenu wordt gegeven, kan een toepassing nog steeds een menubalk voor een venster definiëren wanneer het venster wordt gemaakt.
Als er een menu wordt gegeven voor een klas en er een onderliggend venster van die klasse wordt gemaakt, wordt het menu genegeerd. Zie Menu'svoor meer informatie.
Klasstijlen
De klassestijlen definiëren extra elementen van de vensterklasse. Twee of meer stijlen kunnen worden gecombineerd met behulp van de operator bitwise OR (|). Als u een stijl wilt toewijzen aan een vensterklasse, wijst u de stijl toe aan de stijl lid van de WNDCLASSEX-structuur. Zie Vensterklassestijlenvoor een lijst met klasstijlen.
Klassen en apparaatcontexten
Een apparaatcontext is een speciale set waarden die toepassingen gebruiken voor het tekenen in het clientgebied van hun vensters. Het systeem vereist een apparaatcontext voor elk venster op de weergave, maar biedt enige flexibiliteit in de manier waarop het systeem die apparaatcontext opslaat en behandelt.
Als er geen stijl voor apparaatcontext expliciet wordt gegeven, gaat het systeem ervan uit dat elk venster gebruikmaakt van een apparaatcontext die wordt opgehaald uit een groep contexten die door het systeem worden onderhouden. In dergelijke gevallen moet elk venster de apparaatcontext ophalen en initialiseren voordat het schilderen wordt uitgevoerd en deze na het schilderen vrij maken.
Om te voorkomen dat een apparaatcontext telkens wordt opgehaald wanneer deze binnen een venster moet worden geschilderd, kan een toepassing de CS_OWNDC stijl voor de vensterklasse opgeven. Met deze klassestijl wordt het systeem om een privéapparaatcontext te maken, dat wil gezegd een unieke apparaatcontext toewijzen voor elk venster in de klasse. De toepassing hoeft de context slechts eenmaal op te halen en vervolgens te gebruiken voor alle volgende schilderijen.
Extra klassegeheugen
Het systeem onderhoudt een WNDCLASSEX structuur intern voor elke vensterklasse in het systeem. Wanneer een toepassing een vensterklasse registreert, kan het systeem een aantal extra bytes geheugen toewijzen en toevoegen aan het einde van de WNDCLASSEX structuur. Dit geheugen wordt extra klassegeheugen genoemd en wordt gedeeld door alle vensters van de klasse. Gebruik het extra klassegeheugen om informatie over de klasse op te slaan.
Omdat er extra geheugen wordt toegewezen vanuit de lokale heap van het systeem, moet een toepassing spaarzaam extra klassegeheugen gebruiken. De RegisterClassEx--functie mislukt als de gevraagde hoeveelheid extra klassegeheugen groter is dan 40 bytes. Als een toepassing meer dan 40 bytes nodig heeft, moet deze zijn eigen geheugen toewijzen en een aanwijzer opslaan in het geheugen van de extra klasse.
De functies SetClassWord en SetClassLong kopiëren een waarde naar het extra klassegeheugen. Als u een waarde wilt ophalen uit het extra klassegeheugen, gebruikt u de functies GetClassWord en GetClassLong. De cbClsExtra lid van de WNDCLASSEX structuur geeft de hoeveelheid extra klassegeheugen aan die moet worden toegewezen. Een toepassing die geen extra klassegeheugen gebruikt, moet de cbClsExtra lid initialiseren tot nul.
Extra venstergeheugen
Het systeem onderhoudt een interne gegevensstructuur voor elk venster. Bij het registreren van een vensterklasse kan een toepassing een aantal extra bytes geheugen opgeven, extra venstergeheugengenoemd. Bij het maken van een venster van de klasse wijst het systeem de opgegeven hoeveelheid extra venstergeheugen toe aan het einde van de structuur van het venster en voegt deze toe. Een toepassing kan dit geheugen gebruiken om vensterspecifieke gegevens op te slaan.
Omdat er extra geheugen wordt toegewezen vanuit de lokale heap van het systeem, moet een toepassing spaarzaam extra venstergeheugen gebruiken. De RegisterClassEx--functie mislukt als de hoeveelheid aangevraagd extra venstergeheugen groter is dan 40 bytes. Als een toepassing meer dan 40 bytes nodig heeft, moet deze zijn eigen geheugen toewijzen en een aanwijzer opslaan in het extra venstergeheugen.
De functie SetWindowLong kopieert een waarde naar het extra geheugen. De functie GetWindowLong haalt een waarde op uit het extra geheugen. De cbWndExtra lid van de WNDCLASSEX structuur geeft de hoeveelheid extra venstergeheugen aan die moet worden toegewezen. Een toepassing die geen gebruik maakt van het geheugen, moet cbWndExtra- tot nul initialiseren.