Conventions de codage Windows
Si vous débutez avec la programmation Windows, il peut être déconcertant lorsque vous voyez un programme Windows pour la première fois. Le code est rempli de définitions de type étranges comme DWORD_PTR et LPRECT, et les variables ont des noms tels que hWnd et pwsz (appelé notation hongroise). Il est utile de prendre un moment pour découvrir certaines des conventions de codage Windows.
La grande majorité des API Windows se composent de fonctions ou d’interfaces COM (Component Object Model). Très peu d’API Windows sont fournies en tant que classes C++. (Une exception notable est GDI+, l’une des API graphiques 2D.)
Typedefs
Les en-têtes Windows contiennent un grand nombre de typedefs. La plupart d’entre eux sont définis dans le fichier d’en-tête WinDef.h. Voici quelques-uns que vous rencontrerez souvent.
Types d'entier
Type de données | Taille | Signé? |
---|---|---|
BYTE | 8 bits | Non signé |
DWORD | 32 bits | Non signé |
INT32 | 32 bits | Signé |
INT64 | 64 bits | Signé |
LONG | 32 bits | Signé |
LONGLONG | 64 bits | Signé |
UINT32 | 32 bits | Non signé |
UINT64 | 64 bits | Non signé |
ULONG | 32 bits | Non signé |
ULONGLONG | 64 bits | Non signé |
WORD | 16 bits | Non signé |
Comme vous pouvez le voir, il existe une certaine redondance dans ces typesdefs. Une partie de ce chevauchement est simplement due à l’historique des API Windows. Les types répertoriés ici ont une taille fixe, et les tailles sont les mêmes dans les applications 32 bits et 64. Par exemple, le type DWORD a toujours une largeur de 32 bits.
Type booléen
BOOL est un alias de type pour int, distinct du bool de C++ et d’autres types qui représentent une valeur booléenne . Le fichier WinDef.h
d’en-tête définit également deux valeurs à utiliser avec BOOL.
#define FALSE 0
#define TRUE 1
Malgré cette définition de TRUE, toutefois, la plupart des fonctions qui retournent un type BOOL peuvent retourner n’importe quelle valeur autre que zéro pour indiquer la vérité booléenne. Par conséquent, vous devez toujours écrire ceci :
// Right way.
if (SomeFunctionThatReturnsBoolean())
{
...
}
// or
if (SomeFunctionThatReturnsBoolean() != FALSE)
{
...
}
et pas ceci :
if (result == TRUE) // Wrong!
{
...
}
BOOL est un type entier et n’est pas interchangeable avec le bool de C++.
Types de pointeurs
Windows définit de nombreux types de données du pointeur de formulaire vers X. Ils ont généralement le préfixe P- ou LP- dans le nom. Par exemple, LPRECT est un pointeur vers un RECT, où RECT est une structure qui décrit un rectangle. Les déclarations de variable suivantes sont équivalentes.
RECT* rect; // Pointer to a RECT structure.
LPRECT rect; // The same
PRECT rect; // Also the same.
Sur les architectures 16 bits (Windows 16 bits), il existe 2 types de pointeurs, P pour « pointeur » et LP pour « pointeur long ». Des pointeurs longs (également appelés pointeurs lointains) étaient nécessaires pour traiter les plages de mémoire en dehors du segment actuel. Le préfixe LP a été conservé pour faciliter le portage du code 16 bits vers Windows 32 bits. Aujourd’hui, il n’y a aucune distinction, et ces types de pointeurs sont tous équivalents. Évitez d’utiliser ces préfixes ; ou si vous devez en utiliser un, utilisez P.
Types de précision de pointeur
Les types de données suivants ont toujours la taille d’un pointeur, c’est-à-dire une largeur de 32 bits dans les applications 32 bits et une largeur de 64 bits dans les applications 64 bits. La taille est déterminée au moment de la compilation. Lorsqu’une application 32 bits s’exécute sur Windows 64 bits, ces types de données ont toujours une largeur de 4 octets. (Une application 64 bits ne peut pas s’exécuter sur Windows 32 bits, donc la situation inverse ne se produit pas.)
- DWORD_PTR
- INT_PTR
- LONG_PTR
- ULONG_PTR
- UINT_PTR
Ces types sont utilisés dans les situations où un entier peut être converti en pointeur. Ils sont également utilisés pour définir des variables pour l’arithmétique du pointeur et pour définir des compteurs de boucles qui itèrent sur la plage complète d’octets dans les mémoires tampons. Plus généralement, ils apparaissent aux endroits où une valeur 32 bits existante a été étendue à 64 bits sur Windows 64 bits.
Notation hongroise
La notation hongroise est la pratique qui consiste à ajouter des préfixes aux noms des variables pour fournir des informations supplémentaires sur la variable. (L’inventeur de la notation, Charles Simonyi, était hongrois, d’où son nom).
Dans sa forme d’origine, la notation hongroise fournit des informations sémantiques sur une variable, vous indiquant l’utilisation prévue. Par exemple, i signifie un index, cb signifie une taille en octets (« nombre d’octets »), et rw et col signifient des numéros de ligne et de colonne. Ces préfixes sont conçus pour éviter l’utilisation accidentelle d’une variable dans un contexte incorrect. Par exemple, si vous avez vu l’expression rwPosition + cbTable
, vous savez qu’un numéro de ligne est ajouté à une taille, ce qui est presque certainement un bogue dans le code
Une forme plus courante de notation hongroise utilise des préfixes pour fournir des informations de type , par exemple , dw pour DWORD et w pour WORD.
Notes
Les instructions C++ Core découragent la notation de préfixe (par exemple, la notation hongroise). Consultez NL.5 : Éviter les informations de type d’encodage dans les noms. En interne, l’équipe Windows ne l’utilise plus. Mais son utilisation reste dans les exemples et la documentation.