Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Chaque fenêtre est membre d’une classe de fenêtre particulière. La classe de fenêtre détermine la procédure de fenêtre par défaut utilisée par une fenêtre individuelle pour traiter ses messages. Toutes les fenêtres appartenant à la même classe utilisent la même procédure de fenêtre par défaut. Par exemple, le système définit une procédure de fenêtre pour la classe de zone de liste modifiable (COMBOBOX) ; toutes les zones de liste modifiable utilisent ensuite cette procédure de fenêtre.
Une application inscrit généralement au moins une nouvelle classe de fenêtre et sa procédure de fenêtre associée. Après avoir inscrit une classe, l’application peut créer de nombreuses fenêtres de cette classe, qui utilisent toutes la même procédure de fenêtre. Comme cela signifie que plusieurs sources peuvent appeler simultanément le même élément de code, vous devez être prudent lors de la modification des ressources partagées à partir d’une procédure de fenêtre. Pour plus d’informations, consultez Classes de Fenêtre.
Les procédures de fenêtre pour les boîtes de dialogue (appelées procédures de boîte de dialogue) ont une structure et une fonction similaires à celles des procédures de fenêtre normales. Tous les points faisant référence aux procédures de fenêtre de cette section s’appliquent également aux procédures de boîte de dialogue. Pour plus d’informations, consultez Boîtes de dialogue.
Cette section décrit les rubriques suivantes.
- Structure d’une procédure de fenêtre
- Procédure de fenêtre par défaut
- Sous-classage de procédure de fenêtre
- Superclassement de procédure de fenêtre
Structure d’une procédure de fenêtre
Une procédure de fenêtre est une fonction qui a quatre paramètres et retourne une valeur signée. Les paramètres se composent d’un handle de fenêtre, d’un identificateur de message UINT et de deux paramètres de message déclarés avec les types de données WPARAM et LPARAM . Pour plus d’informations, consultez WindowProc.
Les paramètres de message contiennent souvent des informations dans leurs mots de bas ordre et de classement élevé. Il existe plusieurs macros qu’une application peut utiliser pour extraire des informations des paramètres de message. La macro LOWORD , par exemple, extrait le mot de bas ordre (bits 0 à 15) à partir d’un paramètre de message. D’autres macros incluent HIWORD, LOBYTE et la macro HIBYTE.
L’interprétation de la valeur de retour dépend du message particulier. Consultez la description de chaque message pour déterminer la valeur de retour appropriée.
Étant donné qu’il est possible d’appeler une procédure de fenêtre de manière récursive, il est important de réduire le nombre de variables locales qu’elle utilise. Lors du traitement des messages individuels, une application doit appeler des fonctions en dehors de la procédure de fenêtre pour éviter l’utilisation excessive de variables locales, ce qui peut entraîner le dépassement de capacité de la pile pendant la récursivité profonde.
Procédure de fenêtre par défaut
La fonction de procédure de fenêtre par défaut, DefWindowProc définit un comportement fondamental partagé par toutes les fenêtres. La procédure de fenêtre par défaut fournit les fonctionnalités minimales d’une fenêtre. Une procédure de fenêtre définie par l’application doit transmettre les messages qu’elle ne traite pas à la fonction DefWindowProc pour le traitement par défaut.
Sous-classement de procédure de fenêtre
Lorsqu’une application crée une fenêtre, le système alloue un bloc de mémoire pour stocker des informations spécifiques à la fenêtre, y compris l’adresse de la procédure de fenêtre qui traite les messages de la fenêtre. Lorsque le système doit passer un message à la fenêtre, il recherche l’adresse de la procédure de fenêtre et transmet le message à cette procédure.
La sous-classe est une technique qui permet à une application d’intercepter et de traiter les messages envoyés ou publiés dans une fenêtre particulière avant que la fenêtre ait la possibilité de les traiter. En subclassant une fenêtre, une application peut augmenter, modifier ou surveiller le comportement de la fenêtre. Une application peut sous-classer une fenêtre appartenant à une classe globale système, telle qu’un contrôle d’édition ou une zone de liste. Par exemple, une application peut sous-classer un contrôle d’édition pour empêcher le contrôle d’accepter certains caractères. Toutefois, vous ne pouvez pas sous-classer une fenêtre ou une classe qui appartient à une autre application. Le sous-classement doit être réalisé dans le même processus.
Une application sous-classe une fenêtre en remplaçant l'adresse de la procédure de fenêtre d'origine par l'adresse d'une nouvelle procédure de fenêtre, appelée procédure de sous-classement. Par la suite, la procédure de sous-classe reçoit tous les messages envoyés ou publiés dans la fenêtre.
La procédure de sous-classe peut effectuer trois actions lors de la réception d’un message : elle peut passer le message à la procédure de fenêtre d’origine, modifier le message et le transmettre à la procédure de fenêtre d’origine, ou traiter le message et ne pas le transmettre à la procédure de fenêtre d’origine. Si la procédure de sous-classe traite un message, elle peut le faire avant, après, ou à la fois avant et après l'avoir passé à la procédure de fenêtre d'origine.
Le système fournit deux types de sous-classe : instance et global. Dans la sous-classe d’instance, une application remplace l’adresse de procédure de fenêtre d’une seule instance d’une fenêtre. Une application doit utiliser la sous-classe d’instance pour sous-classer une fenêtre existante. Dans la sous-classe globale, une application remplace l’adresse de la procédure de fenêtre dans la structure WNDCLASSEX d’une classe de fenêtre. Toutes les fenêtres suivantes créées avec la classe ont l’adresse de la procédure de sous-classe, mais les fenêtres existantes de la classe ne sont pas affectées.
Sous-classe d’instance
Une application sous-classe une instance de fenêtre en utilisant la fonction SetWindowLongPtr . L’application transmet l’indicateur GWL_WNDPROC, le handle de la fenêtre à sous-classer, et l’adresse de la procédure de sous-classe à SetWindowLongPtr. La procédure de sous-classe peut résider dans l’exécutable de l’application ou dans une DLL.
Lorsque vous avez passé l’indicateur GWL_WNDPROC , SetWindowLongPtr retourne l’adresse de la procédure de fenêtre d’origine de la fenêtre. L’application doit enregistrer cette adresse, en l’utilisant dans les appels suivants à la fonction CallWindowProc , pour transmettre des messages interceptés à la procédure de fenêtre d’origine. L’application doit également avoir l’adresse de procédure de fenêtre d’origine pour supprimer la sous-classe de la fenêtre. Pour supprimer la sous-classe, l'application appelle de nouveau SetWindowLongPtr, en fournissant l’adresse de la procédure de fenêtre d’origine avec l’indicateur GWL_WNDPROC et le handle de la fenêtre.
Le système possède les classes globales système et les aspects des contrôles peuvent passer d’une version du système à l’autre. Si l’application doit sous-classer une fenêtre appartenant à une classe globale système, le développeur peut avoir besoin de mettre à jour l’application lorsqu’une nouvelle version du système est publiée.
Étant donné que la sous-classe d’instance se produit après la création d’une fenêtre, vous ne pouvez pas ajouter d’octets supplémentaires à la fenêtre. Les applications qui sous-classent une fenêtre doivent utiliser la liste de propriétés de la fenêtre pour stocker les données nécessaires pour une instance de la fenêtre sous-classe. Pour plus d’informations, consultez Propriétés de la fenêtre.
Lorsqu'une application sous-classe une fenêtre déjà sous-classée, elle doit supprimer les sous-classes dans l'ordre inverse de celui dans lequel elles ont été effectuées. Si l’ordre de suppression n’est pas inversé, une erreur système irrécupérable peut se produire.
Sous-classification globale
Pour subclasser globalement une classe de fenêtre, l’application doit avoir un handle vers une fenêtre de la classe. L’application a également besoin du handle pour supprimer la sous-classe. Pour obtenir le handle, une application crée généralement une fenêtre masquée du classement au sous-classement. Après avoir obtenu le handle, l’application appelle la fonction SetClassLongPtr , en spécifiant le handle, l’indicateur GCL_WNDPROC et l’adresse de la procédure de sous-classe. SetClassLongPtr retourne l’adresse de la procédure de fenêtre d’origine pour la classe.
L’adresse de procédure de fenêtre d’origine est utilisée dans la sous-classe globale de la même façon qu’elle est utilisée dans la sous-classe d’instance. La procédure de sous-classe transmet les messages à la procédure de fenêtre d’origine en appelant CallWindowProc. L’application supprime la sous-classe de la classe de fenêtre en appelant à nouveau SetClassLongPtr , en spécifiant l’adresse de la procédure de fenêtre d’origine, l’indicateur GCL_WNDPROC et le handle vers une fenêtre de la classe en cours de sous-classe. Une application qui sous-classe globalement une classe de contrôle doit supprimer la sous-classe lorsque l’application se termine ; sinon, une erreur système irrécupérable peut se produire.
La sous-classe globale présente les mêmes limitations que la sous-classe d’instance, ainsi que certaines restrictions supplémentaires. Une application ne doit pas utiliser les octets supplémentaires pour la classe ou l’instance de fenêtre sans savoir exactement comment la procédure de fenêtre d’origine les utilise. Si l’application doit associer des données à une fenêtre, elle doit utiliser les propriétés de fenêtre.
Superclassement de procédure de fenêtre
Superclassement est une technique qui permet à une application de créer une classe de fenêtre avec les fonctionnalités de base de la classe existante, ainsi que les améliorations fournies par l’application. Une superclasse est basée sur une classe de fenêtre existante appelée classe de base. Souvent, la classe de base est une classe de fenêtre globale système telle qu’un contrôle d’édition, mais il peut s’agir de n’importe quelle classe de fenêtre.
Une superclasse a sa propre procédure de fenêtre, appelée procédure de superclasse. La procédure de superclasse peut effectuer trois actions lors de la réception d’un message : elle peut transmettre le message à la procédure de fenêtre d’origine, modifier le message et le transmettre à la procédure de fenêtre d’origine, ou traiter le message et ne pas le transmettre à la procédure de fenêtre d’origine. Si la procédure de superclassement traite un message, elle peut le faire avant, après ou après, avant et après qu’elle passe le message à la procédure de fenêtre d’origine.
Contrairement à une procédure de sous-classe, une procédure de superclasse peut traiter les messages de création de fenêtre (WM_NCCREATE, WM_CREATE, et ainsi de suite), mais elle doit également les transmettre à la procédure de fenêtre de classe de base d’origine afin que la procédure de fenêtre de classe de base puisse effectuer sa procédure d’initialisation.
Pour superclasser une classe de fenêtre, une application appelle d’abord la fonction GetClassInfoEx pour récupérer des informations sur la classe de base. GetClassInfoEx remplit une structure WNDCLASSEX avec les valeurs de la structure WNDCLASSEX de la classe de base. Ensuite, l’application copie son propre handle d’instance dans le membre hInstance de la structure WNDCLASSEX et copie le nom de la superclasse dans le membre lpszClassName . Si la classe de base possède un menu, l’application doit fournir un nouveau menu avec les mêmes identificateurs de menu et copier le nom du menu dans le membre lpszMenuName . Si la procédure de superclasse traite le message WM_COMMAND et ne la transmet pas à la procédure de fenêtre de la classe de base, le menu n’a pas besoin d’identificateurs correspondants. GetClassInfoEx ne retourne pas le lpszMenuName, lpszClassName ou le membre hInstance de la structure WNDCLASSEX .
Une application doit également définir le membre lpfnWndProc de la structure WNDCLASSEX . La fonction GetClassInfoEx remplit ce membre avec l’adresse de la procédure de fenêtre d’origine pour la classe. L’application doit enregistrer cette adresse pour transmettre des messages à la procédure de fenêtre d’origine, puis copier l’adresse de la procédure de superclasse dans le membre lpfnWndProc . L’application peut, si nécessaire, modifier tous les autres membres de la structure WNDCLASSEX . Une fois la structure WNDCLASSEX remplie, l’application inscrit la superclasse en passant l’adresse de la structure à la fonction RegisterClassEx . La superclasse peut ensuite être utilisée pour créer des fenêtres.
Étant donné que le superclassement inscrit une nouvelle classe de fenêtre, une application peut ajouter à la fois les octets de classe supplémentaires et les octets de fenêtre supplémentaires. La superclasse ne doit pas utiliser les octets supplémentaires d’origine pour la classe de base ou la fenêtre pour les mêmes raisons qu’une sous-classe d’instance ou une sous-classe globale ne doit pas les utiliser. En outre, si l’application ajoute des octets supplémentaires pour son utilisation à la classe ou à l’instance de fenêtre, elle doit référencer les octets supplémentaires par rapport au nombre d’octets supplémentaires utilisés par la classe de base d’origine. Étant donné que le nombre d’octets utilisés par la classe de base peut varier d’une version de la classe de base à la suivante, le décalage de départ pour les propres octets supplémentaires de la superclasse peut également varier d’une version de la classe de base à la suivante.