Partager via


À propos des classes de fenêtre

Chaque classe de fenêtre dispose d'une procédure de fenêtre associée, partagée par toutes les fenêtres de la même classe. La procédure de fenêtre traite les messages pour toutes les fenêtres de cette classe et contrôle ainsi leur comportement et leur apparence. Pour plus d’informations, consultez Window Procedures.

Un processus doit inscrire une classe de fenêtre avant de pouvoir créer une fenêtre de cette classe. L’inscription d’une classe de fenêtre associe une procédure de fenêtre, des styles de classe et d’autres attributs de classe à un nom de classe. Lorsqu’un processus spécifie un nom de classe dans la fonction CreateWindow ou CreateWindowEx, le système crée une fenêtre avec la procédure de fenêtre, les styles et d’autres attributs associés à ce nom de classe.

Cette section décrit les rubriques suivantes.

Types de classes de fenêtre

Il existe trois types de classes de fenêtre :

Ces types diffèrent dans l’étendue et dans le moment et la façon dont ils sont inscrits et détruits.

Classes système

Une classe système est une classe de fenêtre inscrite par le système. De nombreuses classes système sont disponibles pour tous les processus à utiliser, tandis que d’autres sont utilisées uniquement en interne par le système. Étant donné que le système inscrit ces classes, un processus ne peut pas les détruire.

Le système inscrit les classes système pour un processus la première fois qu’un de ses threads appelle une fonction de l’interface utilisateur ou de l’interface de périphérique graphique Windows (GDI).

Chaque application reçoit sa propre copie des classes système. Toutes les applications Windows 16 bits dans le même VDM partagent les classes système, tout comme sur Windows 16 bits.

Le tableau suivant décrit les classes système disponibles pour une utilisation par tous les processus.

classe Descriptif
Button Classe d’un bouton.
ComboBox Classe d’une zone de liste déroulante.
Modifier Classe d’un contrôle d’édition.
Boîte de liste Classe d’une zone de liste.
MDIClient Classe d’une fenêtre cliente MDI.
ScrollBar Classe d’une barre de défilement.
Statique Classe d’un contrôle statique.

 

Le tableau suivant décrit les classes système disponibles uniquement pour une utilisation par le système. Ils sont répertoriés ici pour des raisons d’exhaustivité.

classe Descriptif
ComboLBox Classe pour la zone de liste contenue dans une zone de liste déroulante.
DDEMLEvent Classe pour les événements DDEML (Dynamic Data Exchange Management Library).
Message Classe d’une fenêtre uniquement pour messages.
#32768 Classe d’un menu.
#32769 Classe de la fenêtre de bureau.
#32770 Classe d’une boîte de dialogue.
#32771 Classe de la fenêtre du commutateur de tâches.
#32772 Classe des titres d’icône.

 

Les classes globales d'application

Une classe globale d’application est une classe de fenêtre inscrite par un exécutable ou une DLL qui est disponible pour tous les autres modules du processus. Par exemple, votre .dll peut appeler la fonction RegisterClassEx pour inscrire une classe de fenêtre qui définit un contrôle personnalisé en tant que classe globale d’application afin qu’un processus qui charge le .dll puisse créer des instances du contrôle personnalisé.

Pour créer une classe qui peut être utilisée dans chaque processus, créez la classe de fenêtre dans un .dll et chargez le .dll dans chaque processus. Pour charger le .dll dans chaque processus, ajoutez son nom à la valeur AppInit_DLLs dans la clé de Registre suivante :

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows

Chaque fois qu’un processus démarre, le système charge la .dll spécifiée dans le contexte du processus nouvellement démarré avant d’appeler sa fonction de point d’entrée. Le .dll doit inscrire la classe pendant sa procédure d’initialisation et spécifier le style de CS_GLOBALCLASS . Pour plus d’informations, consultez Styles de classe.

Pour supprimer une classe globale d’application et libérer le stockage associé, utilisez la fonction UnregisterClass .

Classes locales d'application

Une classe locale d’application est n’importe quelle classe de fenêtre qu’un exécutable ou .dll inscrit pour son utilisation exclusive. Bien que vous puissiez inscrire n’importe quel nombre de classes locales, il est courant d’en inscrire un seul. Cette classe de fenêtre prend en charge la procédure de fenêtre de la fenêtre principale de l’application.

Le système détruit une classe locale lorsque le module qui l’a inscrit ferme. Une application peut également utiliser la fonction UnregisterClass pour supprimer une classe locale et libérer le stockage associé.

Comment le système localise une classe de fenêtre

Le système gère une liste de structures pour chacun des trois types de classes de fenêtre. Lorsqu’une application appelle la fonction CreateWindow ou CreateWindowEx pour créer une fenêtre avec une classe spécifiée, le système utilise la procédure suivante pour localiser la classe.

  1. Recherchez la liste des classes locales d’application pour une classe portant le nom spécifié dont le handle d’instance correspond au handle d’instance du module. (Plusieurs modules peuvent utiliser le même nom pour inscrire des classes locales dans le même processus.)
  2. Si le nom n’est pas dans la liste des classes locales de l’application, recherchez la liste des classes globales d’application.
  3. Si le nom n’est pas dans la liste des classes globales de l’application, recherchez la liste des classes système.

Toutes les fenêtres créées par l’application utilisent cette procédure, y compris les fenêtres créées par le système au nom de l’application, telles que les boîtes de dialogue. Il est possible de remplacer les classes système sans affecter d’autres applications. Autrement dit, une application peut inscrire une classe locale d’application portant le même nom qu’une classe système. Cela remplace la classe système dans le contexte de l’application, mais n’empêche pas d’autres applications d’utiliser la classe système.

Enregistrement d'une classe de fenêtre

Une classe de fenêtre définit les attributs d’une fenêtre, tels que son style, son icône, son curseur, son menu et sa procédure de fenêtre. La première étape de l’inscription d’une classe de fenêtre consiste à renseigner une structure WNDCLASSEX avec les informations de classe de fenêtre. Pour plus d’informations, consultez Éléments d’une classe De fenêtre. Ensuite, passez la structure à la fonction RegisterClassEx . Pour plus d’informations, consultez Utilisation des classes de fenêtre.

Pour inscrire une classe globale d’application, spécifiez le style CS_GLOBALCLASS dans le membre de style de la structure WNDCLASSEX . Lors de l’inscription d’une classe locale d’application, ne spécifiez pas le style CS_GLOBALCLASS .

Si vous inscrivez la classe de fenêtre à l’aide de la version ANSI de RegisterClassEx, RegisterClassExA, l’application demande que le système passe les paramètres de texte des messages aux fenêtres de la classe créée à l’aide du jeu de caractères ANSI ; si vous inscrivez la classe à l’aide de la version Unicode de RegisterClassEx, RegisterClassExW, l’application demande que le système passe les paramètres de texte des messages aux fenêtres de la classe créée à l’aide du jeu de caractères Unicode. La fonction IsWindowUnicode permet aux applications d’interroger la nature de chaque fenêtre. Pour plus d’informations sur les fonctions ANSI et Unicode, consultez Conventions pour les prototypes de fonction.

L’exécutable ou la DLL qui a inscrit la classe est le propriétaire de la classe. Le système détermine la propriété de classe du membre hInstance de la structure WNDCLASSEX passée à la fonction RegisterClassEx lorsque la classe est inscrite. Pour les DLL, le membre hInstance doit être le handle de l’instance .dll.

La classe n'est pas détruite lorsque le fichier .dll qui la contient est déchargé. Par conséquent, si le système appelle la procédure de fenêtre pour une fenêtre de cette classe, cela entraîne une violation d’accès, car la .dll contenant la procédure de fenêtre n’est plus en mémoire. Le processus doit détruire toutes les fenêtres à l’aide de la classe avant que le .dll soit déchargé et appeler la fonction UnregisterClass .

Éléments d’une classe Window

Les éléments d’une classe de fenêtre définissent le comportement par défaut des fenêtres appartenant à la classe. L’application qui inscrit une classe de fenêtre affecte des éléments à la classe en définissant les membres appropriés dans une structure WNDCLASSEX et en passant la structure à la fonction RegisterClassEx . Les fonctions GetClassInfoEx et GetClassLong récupèrent des informations sur une classe de fenêtre donnée. La fonction SetClassLong modifie les éléments d’une classe locale ou globale que l’application a déjà inscrite.

Bien qu’une classe de fenêtre complète se compose de nombreux éléments, le système exige uniquement qu’une application fournisse un nom de classe, l’adresse de procédure de fenêtre et un handle d’instance. Utilisez les autres éléments pour définir des attributs par défaut pour les fenêtres de la classe, tels que la forme du curseur et le contenu du menu de la fenêtre. Vous devez initialiser les membres inutilisés de la structure WNDCLASSEX sur zéro ou NULL. Les éléments de classe de fenêtre sont comme indiqué dans le tableau suivant.

Élément Objectif
Nom de la classe Distingue la classe d’autres classes inscrites.
Adresse de procédure de fenêtre Pointeur vers la fonction qui traite tous les messages envoyés aux fenêtres de la classe et définit le comportement de la fenêtre.
Handle d’instance Identifie l'application ou le fichier .dll qui a enregistré la classe.
Curseur de classe Définit le curseur de la souris que le système affiche pour une fenêtre de la classe.
Icônes de classe Définit l’icône volumineuse et la petite icône.
Pinceau d'arrière-plan de classe Définit la couleur et le motif qui remplissent la zone client lorsque la fenêtre est ouverte ou peinte.
Menu des Classes Spécifie le menu par défaut pour les fenêtres qui ne définissent pas explicitement un menu.
Styles de classe Définit comment mettre à jour la fenêtre après le déplacement ou le redimensionnement, comment traiter les double-clics de la souris, comment allouer de l’espace pour le contexte de l’appareil et d’autres aspects de la fenêtre.
Mémoire de classe supplémentaire Spécifie la quantité de mémoire supplémentaire, en octets, que le système doit réserver pour la classe. Toutes les fenêtres de la classe partagent la mémoire supplémentaire et peuvent l’utiliser à des fins définies par l’application. Le système initialise cette mémoire à zéro.
Mémoire de fenêtre supplémentaire Spécifie la quantité de mémoire supplémentaire, en octets, que le système doit réserver pour chaque fenêtre appartenant à la classe. La mémoire supplémentaire peut être utilisée à des fins définies par l’application. Le système initialise cette mémoire à zéro.

 

Nom de la classe

Chaque classe de fenêtre a besoin d’un nom de classe pour distinguer une classe d’une autre. Attribuez un nom de classe en définissant le membre lpszClassName de la structure WNDCLASSEX à l’adresse d’une chaîne terminée par null qui spécifie le nom. Étant donné que les classes de fenêtre sont spécifiques au processus, les noms de classes de fenêtre doivent être uniques uniquement dans le même processus. En outre, étant donné que les noms de classes occupent de l’espace dans la table atom privée du système, vous devez conserver les chaînes de noms de classe aussi courtes que possible.

La fonction GetClassName récupère le nom de la classe à laquelle appartient une fenêtre donnée.

Adresse de procédure de fenêtre

Chaque classe a besoin d’une adresse de procédure fenêtre pour définir le point d’entrée de la procédure de fenêtre utilisée pour traiter tous les messages pour les fenêtres de la classe. Le système transmet des messages à la procédure lorsqu’il nécessite que la fenêtre exécute des tâches, telles que la peinture de sa zone cliente ou la réponse à l’entrée de l’utilisateur. Un processus affecte une procédure de fenêtre à une classe en copiant son adresse dans le membre lpfnWndProc de la structure WNDCLASSEX . Pour plus d’informations, consultez Window Procedures.

Gestionnaire d'instance

Chaque classe de fenêtre nécessite un handle d’instance pour identifier l’application ou .dll qui a inscrit la classe. Le système nécessite des handles d’instance pour effectuer le suivi de tous les modules. Le système attribue un descripteur à chaque copie d'un fichier exécutable ou .dll en cours d'exécution.

Le système transmet un handle d’instance à la fonction de point d’entrée de chaque exécutable (voir WinMain) et .dll (voir DllMain). L’exécutable ou .dll affecte ce handle d’instance à la classe en le copiant vers le membre hInstance de la structure WNDCLASSEX .

Curseur de classe

Le curseur de classe définit la forme du curseur lorsqu’il se trouve dans la zone cliente d’une fenêtre de la classe. Le système définit automatiquement le curseur sur la forme donnée lorsque le curseur entre dans la zone cliente de la fenêtre et garantit qu’il conserve cette forme pendant qu’elle reste dans la zone cliente. Pour affecter une forme de curseur à une classe de fenêtre, chargez une forme de curseur prédéfinie à l’aide de la fonction LoadCursor , puis affectez la poignée de curseur retournée au membre hCursor de la structure WNDCLASSEX . Vous pouvez également fournir une ressource de curseur personnalisée et utiliser la fonction LoadCursor pour la charger à partir des ressources de l’application.

Le système ne nécessite pas de curseur de classe. Si une application définit le membre hCursor de la structure WNDCLASSEX sur NULL, aucun curseur de classe n’est défini. Le système part du principe que la fenêtre définit la forme du curseur chaque fois que le curseur se déplace dans la fenêtre. Une fenêtre peut définir la forme du curseur en appelant la fonction SetCursor chaque fois que la fenêtre reçoit le message WM_MOUSEMOVE . Pour plus d’informations sur les curseurs, consultez Curseurs.

Icône de classe

Une icône de classe est une image que le système utilise pour représenter une fenêtre d’une classe particulière. Une application peut avoir deux icônes de classe : une grande et une petite. Le système affiche l’icône de classe volumineuse d’une fenêtre dans la fenêtre de commutateur de tâches qui s’affiche lorsque l’utilisateur appuie sur Alt+Tab et dans les grandes vues d’icônes de la barre des tâches et de l’Explorateur. L’icône petite classe s’affiche dans la barre de titre d’une fenêtre et dans les petites vues d’icône de la barre des tâches et de l’Explorateur.

Pour affecter une icône volumineuse et petite à une classe de fenêtre, spécifiez les poignées des icônes dans les membres hIcon et hIconSm de la structure WNDCLASSEX . Les dimensions d’icône doivent être conformes aux dimensions requises pour les icônes de grande et petite classe. Pour une icône de classe volumineuse, vous pouvez déterminer les dimensions requises en spécifiant les valeurs SM_CXICON et SM_CYICON dans un appel à la fonction GetSystemMetrics . Pour une petite icône de classe, spécifiez les valeurs SM_CXSMICON et SM_CYSMICON . Pour plus d’informations, consultez Icônes.

Si une application définit les membres hIcon ethIconSm de la structure WNDCLASSEX sur NULL, le système utilise l’icône d’application par défaut comme icônes de grande et petite classe pour la classe de fenêtre. Si vous spécifiez une icône de classe volumineuse, mais pas une petite, le système crée une petite icône de classe basée sur la grande. Toutefois, si vous spécifiez une petite icône de classe, mais pas une grande, le système utilise l’icône d’application par défaut comme icône de classe de grande taille et l’icône spécifiée comme icône de petite classe.

Vous pouvez remplacer l’icône de grande ou petite classe pour une fenêtre particulière à l’aide du message WM_SETICON . Vous pouvez récupérer l’icône de grande ou petite classe actuelle à l’aide du message WM_GETICON .

Pinceau d'arrière-plan de classe

Un pinceau d'arrière-plan de classe prépare la zone client d'une fenêtre pour le dessin ultérieur par l'application. Le système utilise le pinceau pour remplir la zone cliente avec une couleur ou un motif unie, supprimant ainsi toutes les images précédentes de cet emplacement, qu’elles appartiennent ou non à la fenêtre. Le système avertit une fenêtre que son arrière-plan doit être peint en envoyant le message WM_ERASEBKGND à la fenêtre. Pour plus d’informations, consultez Pinceaux.

Pour affecter un pinceau d’arrière-plan à une classe, créez un pinceau à l’aide des fonctions GDI appropriées et affectez la poignée de pinceau retournée au membre hbrBackground de la structure WNDCLASSEX .

Au lieu de créer un pinceau, une application peut définir le membre hbrBackground sur l’une des valeurs de couleur système standard. Pour obtenir la liste des valeurs de couleur système standard, consultez SetSysColors.

Pour utiliser une couleur système standard, l’application doit augmenter la valeur de couleur d’arrière-plan par un. Par exemple, COLOR_BACKGROUND + 1 est la couleur d’arrière-plan système. Vous pouvez également utiliser la fonction GetSysColorBrush pour récupérer un descripteur vers un pinceau correspondant à une couleur système standard, puis spécifier le descripteur dans le membre hbrBackground de la structure WNDCLASSEX.

Le système ne nécessite pas qu’une classe de fenêtre ait un pinceau d’arrière-plan de classe. Si ce paramètre est défini sur NULL, la fenêtre doit peindre son propre arrière-plan chaque fois qu’elle reçoit le message WM_ERASEBKGND.

Menu de classe

Un menu de classe définit le menu par défaut à utiliser par les fenêtres de la classe si aucun menu explicite n’est donné lorsque les fenêtres sont créées. Un menu est une liste de commandes à partir desquelles un utilisateur peut choisir des actions pour que l’application s’exécute.

Vous pouvez affecter un menu à une classe en définissant le membre lpszMenuName de la structure WNDCLASSEX à l’adresse d’une chaîne terminée par null qui spécifie le nom de la ressource du menu. Le menu est supposé être une ressource dans l’application donnée. Le système charge automatiquement le menu quand il est nécessaire. Si la ressource de menu est identifiée par un entier et non par un nom, l’application peut définir le membre lpszMenuName sur cet entier en appliquant la macro MAKEINTRESOURCE avant d’affecter la valeur.

Le système ne nécessite pas de menu de classe. Si une application définit le membre lpszMenuName de la structure WNDCLASSEX sur NULL, les fenêtres de la classe n’ont aucune barre de menus. Même si aucun menu de classe n’est donné, une application peut toujours définir une barre de menus pour une fenêtre lorsqu’elle crée la fenêtre.

Si un menu est fourni pour une classe et qu’une fenêtre enfant de cette classe est créée, le menu est ignoré. Pour plus d’informations, consultez Menus.

Styles de la classe

Les styles de classe définissent des éléments supplémentaires de la classe de fenêtre. Deux styles ou plus peuvent être combinés à l’aide de l’opérateur OR (|) au niveau du bit. Pour affecter un style à une classe de fenêtre, affectez le style au membre de style de la structure WNDCLASSEX . Pour obtenir la liste des styles de classe, consultez Styles de classe de fenêtre.

Classes et contextes d’appareil

Un contexte d’appareil est un ensemble spécial de valeurs que les applications utilisent pour dessiner dans la zone cliente de leurs fenêtres. Le système nécessite un contexte d’appareil pour chaque fenêtre de l’affichage, mais permet une certaine flexibilité dans la façon dont le système stocke et traite ce contexte d’appareil.

Si aucun style de contexte d’appareil n’est explicitement donné, le système suppose que chaque fenêtre utilise un contexte d’appareil récupéré à partir d’un pool de contextes gérés par le système. Dans ce cas, chaque fenêtre doit récupérer et initialiser le contexte de l’appareil avant la peinture et la libérer après la peinture.

Pour éviter de récupérer un contexte d’appareil chaque fois qu’il doit peindre à l’intérieur d’une fenêtre, une application peut spécifier le style CS_OWNDC pour la classe de fenêtre. Ce style de classe dirige le système pour créer un contexte d’appareil privé, autrement dit, pour allouer un contexte d’appareil unique pour chaque fenêtre de la classe. L’application n’a besoin que de récupérer le contexte une seule fois, puis de l’utiliser pour toutes les peintures suivantes.

Mémoire de classe supplémentaire

Le système gère une structure WNDCLASSEX en interne pour chaque classe de fenêtre du système. Lorsqu’une application inscrit une classe de fenêtre, elle peut diriger le système pour allouer et ajouter un certain nombre d’octets supplémentaires de mémoire à la fin de la structure WNDCLASSEX . Cette mémoire est appelée mémoire de classe supplémentaire et partagée par toutes les fenêtres appartenant à la classe. Utilisez la mémoire de classe supplémentaire pour stocker toutes les informations relatives à la classe.

Étant donné que la mémoire supplémentaire est allouée à partir du tas local du système, il est recommandé d'utiliser la mémoire de classe supplémentaire avec parcimonie. La fonction RegisterClassEx échoue si la quantité de mémoire de classe supplémentaire demandée est supérieure à 40 octets. Si une application nécessite plus de 40 octets, elle doit allouer sa propre mémoire et stocker un pointeur vers la mémoire de la classe supplémentaire.

Les fonctions SetClassWord et SetClassLong copient une valeur dans la mémoire de classe supplémentaire. Pour récupérer une valeur à partir de la mémoire de classe supplémentaire, utilisez les fonctions GetClassWord et GetClassLong . Le membre cbClsExtra de la structure WNDCLASSEX spécifie la quantité de mémoire de classe supplémentaire à allouer. Une application qui n’utilise pas de mémoire de classe supplémentaire doit initialiser le membre cbClsExtra sur zéro.

Mémoire de fenêtre supplémentaire

Le système gère une structure de données interne pour chaque fenêtre. Lors de l’inscription d’une classe de fenêtre, une application peut spécifier un certain nombre d’octets supplémentaires de mémoire, appelés mémoire de fenêtre supplémentaire. Lors de la création d’une fenêtre de la classe, le système alloue et ajoute la quantité spécifiée de mémoire de fenêtre supplémentaire à la fin de la structure de la fenêtre. Une application peut utiliser cette mémoire pour stocker des données spécifiques à la fenêtre.

Étant donné que la mémoire supplémentaire est allouée à partir du tas local du système, il est recommandé d'utiliser la mémoire de fenêtre supplémentaire avec parcimonie. La fonction RegisterClassEx échoue si la quantité de mémoire de fenêtre supplémentaire demandée est supérieure à 40 octets. Si une application nécessite plus de 40 octets, elle doit allouer sa propre mémoire et stocker un pointeur vers la mémoire dans la mémoire supplémentaire de la fenêtre.

La fonction SetWindowLong copie une valeur dans la mémoire supplémentaire. La fonction GetWindowLong récupère une valeur à partir de la mémoire supplémentaire. Le membre cbWndExtra de la structure WNDCLASSEX spécifie la quantité de mémoire de fenêtre supplémentaire à allouer. Une application qui n’utilise pas la mémoire doit initialiser cbWndExtra sur zéro.