Ces "types" présentent toujours des surprises, par exemple lorsque vous le LPCSTR p, q;souhaitez et que vous le souhaitez const char *p, *q;. Pouvez-vous refuser de les utiliser?
ott--
9
Une abomination.
Thomas Eding
2
Le portage 64 bits d'une application 32 bits nécessite la connaissance de telles terminologies
LPCTSTR= L de P de ointer à un C onst
T CHAR STR ING (Ne vous inquiétez pas, un pointeur longue est la même que celle d' un pointeur. Il y avait deux saveurs de pointeurs sous Windows 16 bits.)
Voici la table:
LPSTR = char*
LPCSTR = const char*
LPWSTR = wchar_t*
LPCWSTR = const wchar_t*
LPTSTR= en char* or wchar_t*fonction de_UNICODE
LPCTSTR= en const char* or const wchar_t*fonction de_UNICODE
À chaque fois que je vois ce nom, j'ai envie de trembler. Il y a juste quelque chose à ce sujet qui me rend mal à l'aise. (+1 BTW)
Donal Fellows
2
Quand devrais-je utiliser ce type de pointeur alors?
Florian Margaine
@ FlorianMargaine Quand une API vous le dit. Il suffit d’utiliser les types appropriés jusqu’alors
James
1
Soyez averti, il y a beaucoup de mises en garde à prendre en compte ici. wchar_t est un type 16 bits, mais peut être utilisé pour stocker les caractères unicode codés ucs2 et utf-16. utf-16 peut utiliser plusieurs wchar_t pour coder une seule lettre, ucs2 ne prenant en charge qu'un sous-ensemble du jeu de caractères unicode. Les fonctions de l'API à appeler dépendent également de l'encodage utilisé.
Michael Shaw
2
Le pire est DWORD, qui était un mot double 32 bits, mais de nos jours est un demi-mot 32 bits :-)
gnasher729
6
Il n'est pas nécessaire d'utiliser l'un des types liés à TCHAR.
Ces types, tous les types de structure qui les utilisent et toutes les fonctions associées sont mappés au moment de la compilation vers une version ANSI ou UNICODE (en fonction de la configuration de votre projet). Les versions ANSI ont généralement un A ajouté à la fin du nom et les versions unicode ajoutent un W. Vous pouvez les utiliser explicitement si vous préférez. MSDN le notera si nécessaire. Par exemple, il répertorie les fonctions MessageBoxIndirectA et MessageBoxIndirectW ici: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
Si vous ne ciblez pas Windows 9x, qui manquait d'implémentations de nombreuses fonctions unicode, vous n'avez pas besoin d'utiliser les versions ANSI. Si vous ciblez Windows 9x, vous pouvez utiliser TCHAR pour créer un binaire ansi et unicode à partir de la même base de code, à condition que votre code ne présume pas que TCHAR est un caractère ou une valeur.
Si vous ne vous souciez pas de Windows 9x, je vous recommande de configurer votre projet en tant qu'unicode et de traiter TCHAR comme identique à WCHAR. Vous pouvez utiliser explicitement les fonctions et les types W si vous préférez, mais tant que vous ne prévoyez pas d'exécuter votre projet sous Windows 9x, cela n'a pas vraiment d'importance.
Un pointeur sur une chaîne de caractères Unicode 16 bits à terminaison null constante. Pour plus d'informations, voir Jeux de caractères utilisés par les polices.
Je sais que cette question a été posée il y a un certain temps et que je n'essaie pas de répondre directement à la question d'origine, mais comme cette question / réponse a une note décente, j'aimerais ajouter un peu ici aux futurs lecteurs. Cela concerne plus spécifiquement le Win32APItypedefset comment les comprendre.
Si quelqu'un a déjà fait une programmation Windows pendant l'ère des machines 32 bits à partir de Windows 95 à Windows et jusqu'à 7-8 qu'ils comprennent et savent que l' Win32APIest chargé avec typedefset que la majorité de leurs fonctions et structures qui doivent être remplies et utilisé dépend fortement d'eux.
Voici un programme Windows de base à donner en démonstration.
C'est à peine assez de code pour rendre une application Windows. Il s’agit de la configuration la plus élémentaire pour initialiser les propriétés minimales nues afin de rendre une fenêtre de base et, comme vous pouvez le constater, elle est déjà chargée typedefsdepuis le Win32api.
Décomposons en regardant les fonctions WinMainet InitWindowsApp: La première chose à faire sont les paramètres des fonctions HINSTANCEet PSTR:
WinMainaccepte un seul HINSTANCEobjet tandis que InitWindowsAppaccepte deux HINSTANCEobjets, un objet PSTR ou une autre typedefchaîne et un entier.
Je vais utiliser la InitWindowsAppfonction ici car elle donnera une description de l'objet dans les deux fonctions.
Le premier HINSTANCEest défini comme étant un H andle à un INSTANCE et ceci est celui qui est le plus couramment utilisé pour l'application. Le second est un autre exemple HANDLEd’ Instant INSTANCE, qui est rarement utilisé. Elle a été conservée pour des raisons d'héritage afin de ne pas avoir à changer la WinMain()signature de fonction qui casserait de nombreuses applications existantes dans le processus. Le troisième paramètre est un P ointer à un STR ing.
Nous devons donc nous demander ce qu'est un HANDLE? Si nous regardons dans la Win32APIdocumentation trouvée ici: Types de données Windows, nous pouvons facilement le rechercher et voir qu'il est défini comme suit:
Une poignée à un objet. Ce type est déclaré dans WinNT.h comme suit:
typedef PVOID HANDLE;
Maintenant nous en avons un autre typedef. Qu'est - ce qu'un PVOID? Cela devrait être évident, mais regardons cela dans le même tableau ...
Un pointeur sur n'importe quel type. Ceci est déclaré dans WinNT.h
typedefvoid*PVOID;
A HANDLEest utilisé pour déclarer de nombreux objets dans les Win32APIchoses telles que:
HKEY - un descripteur de clé de registre. Déclaré dans WinDef.h
typdef HANDLE HKEY;
HKL - Un identifiant pour un identifiant de locale. Déclaré dans WinDef.h
typdef HANDLE HKL;
HMENU - Une poignée pour un menu. Déclaré dans WinDef.h
typdef HANDLE HMENU;
HPEN - Une poignée à un stylo. Déclaré dans WinDef.h
typedef HANDLE HPEN;
HWND - Une poignée à une fenêtre. Déclaré dans WinDef.h
typedef HANDLE HWND;
... et ainsi de suite, comme HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, etc.
Ce sont tous ceux typedefsqui sont déclarés en utilisant a typedefqui est a HANDLEet le HANDLElui-même est déclaré en tant que typedefde a PVOIDqui est aussi a typedefà a void pointer.
Donc, quand on en vient à LPCTSTRtrouver ça dans les mêmes documents:
Il est défini comme un LPCWSTRif UNICODEest défini ou un LPCSTRautre.
De nombreux types de descripteurs sont plus fortement typés que le simple fait d'être des HANDLEalias si vous activez la STRICTmacro. Quel est le défaut dans les nouveaux projets, je pense.
Sebastian Redl
@SebastianRedl Cela pourrait être; mais je n'essayais pas d'entrer trop dans les détails de l'API ni dans la sévérité des aspects fortement typés du langage. Il s’agissait plutôt d’une vue d’ensemble de l’API Win32 et de ses types de données grâce à l’utilisation de typedefs ...
LPCSTR p, q;
souhaitez et que vous le souhaitezconst char *p, *q;
. Pouvez-vous refuser de les utiliser?Réponses:
Citation de Brian Kramer sur les forums MSDN
la source
Il n'est pas nécessaire d'utiliser l'un des types liés à TCHAR.
Ces types, tous les types de structure qui les utilisent et toutes les fonctions associées sont mappés au moment de la compilation vers une version ANSI ou UNICODE (en fonction de la configuration de votre projet). Les versions ANSI ont généralement un A ajouté à la fin du nom et les versions unicode ajoutent un W. Vous pouvez les utiliser explicitement si vous préférez. MSDN le notera si nécessaire. Par exemple, il répertorie les fonctions MessageBoxIndirectA et MessageBoxIndirectW ici: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
Si vous ne ciblez pas Windows 9x, qui manquait d'implémentations de nombreuses fonctions unicode, vous n'avez pas besoin d'utiliser les versions ANSI. Si vous ciblez Windows 9x, vous pouvez utiliser TCHAR pour créer un binaire ansi et unicode à partir de la même base de code, à condition que votre code ne présume pas que TCHAR est un caractère ou une valeur.
Si vous ne vous souciez pas de Windows 9x, je vous recommande de configurer votre projet en tant qu'unicode et de traiter TCHAR comme identique à WCHAR. Vous pouvez utiliser explicitement les fonctions et les types W si vous préférez, mais tant que vous ne prévoyez pas d'exécuter votre projet sous Windows 9x, cela n'a pas vraiment d'importance.
la source
Ces types sont documentés dans Types de données Windows sur MSDN:
la source
Je sais que cette question a été posée il y a un certain temps et que je n'essaie pas de répondre directement à la question d'origine, mais comme cette question / réponse a une note décente, j'aimerais ajouter un peu ici aux futurs lecteurs. Cela concerne plus spécifiquement le
Win32
API
typedefs
et comment les comprendre.Si quelqu'un a déjà fait une programmation Windows pendant l'ère des machines 32 bits à partir de Windows 95 à Windows et jusqu'à 7-8 qu'ils comprennent et savent que l'
Win32
API
est chargé avectypedefs
et que la majorité de leurs fonctions et structures qui doivent être remplies et utilisé dépend fortement d'eux.Voici un programme Windows de base à donner en démonstration.
C'est à peine assez de code pour rendre une application Windows. Il s’agit de la configuration la plus élémentaire pour initialiser les propriétés minimales nues afin de rendre une fenêtre de base et, comme vous pouvez le constater, elle est déjà chargée
typedefs
depuis leWin32
api
.Décomposons en regardant les fonctions
WinMain
etInitWindowsApp
: La première chose à faire sont les paramètres des fonctionsHINSTANCE
etPSTR
:WinMain
accepte un seulHINSTANCE
objet tandis queInitWindowsApp
accepte deuxHINSTANCE
objets, un objet PSTR ou une autretypedef
chaîne et un entier.Je vais utiliser la
InitWindowsApp
fonction ici car elle donnera une description de l'objet dans les deux fonctions.Le premier
HINSTANCE
est défini comme étant un H andle à un INSTANCE et ceci est celui qui est le plus couramment utilisé pour l'application. Le second est un autre exempleHANDLE
d’ Instant INSTANCE, qui est rarement utilisé. Elle a été conservée pour des raisons d'héritage afin de ne pas avoir à changer laWinMain()
signature de fonction qui casserait de nombreuses applications existantes dans le processus. Le troisième paramètre est un P ointer à un STR ing.Nous devons donc nous demander ce qu'est un
HANDLE
? Si nous regardons dans laWin32
API
documentation trouvée ici: Types de données Windows, nous pouvons facilement le rechercher et voir qu'il est défini comme suit:Maintenant nous en avons un autre
typedef
. Qu'est - ce qu'unPVOID
? Cela devrait être évident, mais regardons cela dans le même tableau ...A
HANDLE
est utilisé pour déclarer de nombreux objets dans lesWin32
API
choses telles que:HKEY
- un descripteur de clé de registre. Déclaré dans WinDef.htypdef HANDLE HKEY;
HKL
- Un identifiant pour un identifiant de locale. Déclaré dans WinDef.htypdef HANDLE HKL;
HMENU
- Une poignée pour un menu. Déclaré dans WinDef.htypdef HANDLE HMENU;
HPEN
- Une poignée à un stylo. Déclaré dans WinDef.htypedef HANDLE HPEN;
HWND
- Une poignée à une fenêtre. Déclaré dans WinDef.htypedef HANDLE HWND;
HBRUSH
,HCURSOR
,HBITMAP
,HDC
,HDESK
, etc.Ce sont tous ceux
typedefs
qui sont déclarés en utilisant atypedef
qui est aHANDLE
et leHANDLE
lui-même est déclaré en tant quetypedef
de aPVOID
qui est aussi atypedef
à avoid pointer
.Donc, quand on en vient à
LPCTSTR
trouver ça dans les mêmes documents:J'espère donc que cela vous aidera à comprendre comment utiliser
typedefs
les types de données Windows, en particulier, disponibles dans leWin32
API
.la source
HANDLE
alias si vous activez laSTRICT
macro. Quel est le défaut dans les nouveaux projets, je pense.