Diese "Typen" zeigen immer Überraschungen, z. B. wenn Sie sie haben LPCSTR p, q;und haben wollen const char *p, *q;. Können Sie sich weigern, sie zu benutzen?
ott--
9
Ein Gräuel.
Thomas Eding
2
64 - Bit - Portierung einer 32-Bit - Anwendung erfordert die Kenntnis solcher Terminologien
LPCTSTR= L Ong P ointer zu einem C onst
T CHAR STR ing (keine Sorge, ein langer Zeiger ist das gleiche wie ein Zeiger. Zwei Arten von Zeigern gibt unter 16-Bit - Fenstern waren.)
Hier ist die Tabelle:
LPSTR = char*
LPCSTR = const char*
LPWSTR = wchar_t*
LPCWSTR = const wchar_t*
LPTSTR= char* or wchar_t*abhängig von_UNICODE
LPCTSTR= const char* or const wchar_t*abhängig von_UNICODE
Jedes Mal, wenn ich diesen Typnamen sehe, habe ich das Gefühl, zusammenzucken. Es gibt nur etwas, das mich unwohl macht. (+1 BTW)
Donal Fellows
2
Wann sollte ich dann diese Art von Zeiger verwenden?
Florian Margaine
@FlorianMargaine Wenn Sie von einer API dazu aufgefordert werden. Verwenden Sie einfach die "richtigen" Typen bis dahin
James
1
seien sie gewarnt, hier gibt es viele vorbehalte zu beachten. wchar_t ist ein 16-Bit-Typ, der jedoch sowohl zum Speichern von UCS2- als auch von UTF-16-codierten Unicode-Zeichen verwendet werden kann. utf-16 kann mehrere wchar_t verwenden, um einen einzelnen Buchstaben zu kodieren. ucs2 unterstützt nur eine Teilmenge des Unicode-Zeichensatzes. Welche API-Funktionen Sie aufrufen müssen, hängt auch von der verwendeten Codierung ab.
Michael Shaw
2
Das Schlimmste ist DWORD, das früher ein 32-Bit-Doppelwort war, aber heute ist es ein 32-Bit-
Halbwort
6
Es ist nicht erforderlich, jemals einen der TCHAR-Typen zu verwenden.
Diese Typen, alle Strukturtypen, die sie verwenden, und alle zugehörigen Funktionen werden zur Kompilierungszeit einer ANSI- oder UNICODE-Version zugeordnet (basierend auf der Konfiguration Ihres Projekts). ANSI-Versionen haben normalerweise ein A am Ende des Namens und Unicode-Versionen ein W. Sie können diese explizit verwenden, wenn Sie dies vorziehen. MSDN merkt sich dies bei Bedarf. Beispielsweise werden hier die Funktionen MessageBoxIndirectA und MessageBoxIndirectW aufgelistet: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
Sofern Sie nicht auf Windows 9x abzielen, für das viele Unicode-Funktionen nicht implementiert waren, müssen Sie die ANSI-Versionen nicht verwenden. Wenn Sie auf Windows 9x abzielen, können Sie mit TCHAR eine Ansi- und Unicode-Binärdatei aus derselben Codebasis erstellen, sofern in Ihrem Code keine Annahmen darüber getroffen werden, ob es sich bei TCHAR um ein Zeichen oder ein Zeichen handelt.
Wenn Sie sich nicht für Windows 9x interessieren, empfehle ich, Ihr Projekt als Unicode zu konfigurieren und TCHAR als mit WCHAR identisch zu behandeln. Sie können die W-Funktionen und -Typen nach Belieben explizit verwenden, aber solange Sie nicht vorhaben, Ihr Projekt unter Windows 9x auszuführen, spielt es keine Rolle.
Ein Zeiger auf eine konstante nullterminierte Zeichenfolge mit 16-Bit-Unicode-Zeichen. Weitere Informationen finden Sie unter Von Schriftarten verwendete Zeichensätze.
Ich weiß, dass diese Frage vor einiger Zeit gestellt wurde und ich versuche nicht, die genaue ursprüngliche Frage direkt zu beantworten, aber da diese Frage eine anständige Bewertung hat, möchte ich hier ein wenig für zukünftige Leser hinzufügen. Dies hat insbesondere mit dem zu tun Win32APItypedefsund wie man sie versteht.
Wenn jemand im Zeitalter der 32-Bit-Computer von Windows 95 bis Windows 7-8 jemals Windows-Programmierungen durchgeführt hat, versteht er und weiß, dass die Win32APImit typedefsund mit einem Großteil seiner Funktionen und Strukturen gefüllt werden müssen verwendet verlassen sich stark auf sie.
Hier ist ein grundlegendes Windows-Programm zur Demonstration.
Dies ist kaum genug Code, um eine Windows-Anwendung zu rendern. Dies ist die Grundeinstellung der nackten minimalen Eigenschaften zu initialisieren ein Grundfenster zu machen und wie Sie es bereits geladen mit sehen können typedefsaus dem Win32api.
Lassen Sie es uns zusammenfassen, indem wir uns die WinMainund InitWindowsApp-Funktionen ansehen: Das Erste sind die Parameter der Funktionen HINSTANCEund PSTR:
WinMainakzeptiert ein einzelnes HINSTANCEObjekt, während InitWindowsAppzwei HINSTANCEObjekte ein PSTR-Objekt oder eine andere typedefZeichenfolge und ein Int.
Ich werde die InitWindowsAppFunktion hier verwenden, da sie eine Beschreibung des Objekts in beiden Funktionen enthält.
Das erste HINSTANCEist als ein H- andle zu einer INSTANZ definiert und dies ist dasjenige, das am häufigsten für die Anwendung verwendet wird. Der zweite ist ein anderer HANDLEzu einem früheren INSTANZ, der selten mehr verwendet wird. Es wurde zu Legacy-Zwecken aufbewahrt, um die WinMain()Funktionssignatur nicht ändern zu müssen, die viele bereits vorhandene Anwendungen im Prozess beschädigen würde. Der dritte Parameter ist ein P ointer zu einem STR ing.
Also müssen wir uns selbst fragen, was ist ein HANDLE? In den folgenden Win32APIDokumenten finden Sie Informationen zu Windows-Datentypen :
Ein Handle zu einem Objekt. Dieser Typ wird in WinNT.h wie folgt deklariert:
typedef PVOID HANDLE;
Jetzt haben wir noch einen typedef. Was ist ein PVOID? Nun, es sollte offensichtlich sein, aber lassen Sie uns das in der gleichen Tabelle nachschlagen ...
Ein Zeiger auf einen beliebigen Typ. Dies ist in WinNT.h deklariert
typedefvoid*PVOID;
A HANDLEwird verwendet, um viele Objekte in den folgenden Win32APIDingen zu deklarieren :
HKEY - Ein Handle für einen Registrierungsschlüssel. In WinDef.h deklariert
typdef HANDLE HKEY;
HKL - Ein Handle zu einer Gebietsschemabezeichnung. In WinDef.h deklariert
typdef HANDLE HKL;
HMENU - Ein Griff zu einem Menü. In WinDef.h deklariert
typdef HANDLE HMENU;
HPEN - Ein Griff zu einem Stift. In WinDef.h deklariert
typedef HANDLE HPEN;
HWND - Ein Griff an ein Fenster. In WinDef.h deklariert
typedef HANDLE HWND;
... und so weiter, wie HBRUSH, HCURSOR, HBITMAP, HDC, HDESK, usw.
Dies sind alles typedefs, typedefwas mit a, das a ist, deklariert wird, HANDLEund das HANDLEselbst wird als typedefvon a, PVOIDdas auch a ist, typedefzu a deklariert void pointer.
Wenn es also darum geht, LPCTSTRkönnen wir das in den gleichen Dokumenten finden:
Es ist definiert als LPCWSTRob UNICODEdefiniert ist oder LPCSTRnicht.
So hoffentlich wird dies als Leitfaden helfen , wie die Verwendungen zu verstehen , typedefsvor allem mit den Windows - Datentypen , die in der zu finden sind Win32API.
Viele der Handle-Typen sind stärker typisiert als nur HANDLEAliase, wenn Sie das STRICTMakro aktivieren . Welches ist der Standard in neuen Projekten, denke ich.
Sebastian Redl
@SebastianRedl Es könnte sein; Aber ich habe nicht versucht, zu viel über die API und die Strenge der stark typisierten Aspekte der Sprache zu erfahren. Es war eher eine Übersicht über die Win32-API und ihre Datentypen durch die Verwendung von typedefs ...
LPCSTR p, q;
und haben wollenconst char *p, *q;
. Können Sie sich weigern, sie zu benutzen?Antworten:
Zitiert Brian Kramer in den MSDN-Foren
quelle
Es ist nicht erforderlich, jemals einen der TCHAR-Typen zu verwenden.
Diese Typen, alle Strukturtypen, die sie verwenden, und alle zugehörigen Funktionen werden zur Kompilierungszeit einer ANSI- oder UNICODE-Version zugeordnet (basierend auf der Konfiguration Ihres Projekts). ANSI-Versionen haben normalerweise ein A am Ende des Namens und Unicode-Versionen ein W. Sie können diese explizit verwenden, wenn Sie dies vorziehen. MSDN merkt sich dies bei Bedarf. Beispielsweise werden hier die Funktionen MessageBoxIndirectA und MessageBoxIndirectW aufgelistet: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
Sofern Sie nicht auf Windows 9x abzielen, für das viele Unicode-Funktionen nicht implementiert waren, müssen Sie die ANSI-Versionen nicht verwenden. Wenn Sie auf Windows 9x abzielen, können Sie mit TCHAR eine Ansi- und Unicode-Binärdatei aus derselben Codebasis erstellen, sofern in Ihrem Code keine Annahmen darüber getroffen werden, ob es sich bei TCHAR um ein Zeichen oder ein Zeichen handelt.
Wenn Sie sich nicht für Windows 9x interessieren, empfehle ich, Ihr Projekt als Unicode zu konfigurieren und TCHAR als mit WCHAR identisch zu behandeln. Sie können die W-Funktionen und -Typen nach Belieben explizit verwenden, aber solange Sie nicht vorhaben, Ihr Projekt unter Windows 9x auszuführen, spielt es keine Rolle.
quelle
Diese Typen sind unter Windows-Datentypen in MSDN dokumentiert :
quelle
Ich weiß, dass diese Frage vor einiger Zeit gestellt wurde und ich versuche nicht, die genaue ursprüngliche Frage direkt zu beantworten, aber da diese Frage eine anständige Bewertung hat, möchte ich hier ein wenig für zukünftige Leser hinzufügen. Dies hat insbesondere mit dem zu tun
Win32
API
typedefs
und wie man sie versteht.Wenn jemand im Zeitalter der 32-Bit-Computer von Windows 95 bis Windows 7-8 jemals Windows-Programmierungen durchgeführt hat, versteht er und weiß, dass die
Win32
API
mittypedefs
und mit einem Großteil seiner Funktionen und Strukturen gefüllt werden müssen verwendet verlassen sich stark auf sie.Hier ist ein grundlegendes Windows-Programm zur Demonstration.
Dies ist kaum genug Code, um eine Windows-Anwendung zu rendern. Dies ist die Grundeinstellung der nackten minimalen Eigenschaften zu initialisieren ein Grundfenster zu machen und wie Sie es bereits geladen mit sehen können
typedefs
aus demWin32
api
.Lassen Sie es uns zusammenfassen, indem wir uns die
WinMain
undInitWindowsApp
-Funktionen ansehen: Das Erste sind die Parameter der FunktionenHINSTANCE
undPSTR
:WinMain
akzeptiert ein einzelnesHINSTANCE
Objekt, währendInitWindowsApp
zweiHINSTANCE
Objekte ein PSTR-Objekt oder eine anderetypedef
Zeichenfolge und ein Int.Ich werde die
InitWindowsApp
Funktion hier verwenden, da sie eine Beschreibung des Objekts in beiden Funktionen enthält.Das erste
HINSTANCE
ist als ein H- andle zu einer INSTANZ definiert und dies ist dasjenige, das am häufigsten für die Anwendung verwendet wird. Der zweite ist ein andererHANDLE
zu einem früheren INSTANZ, der selten mehr verwendet wird. Es wurde zu Legacy-Zwecken aufbewahrt, um dieWinMain()
Funktionssignatur nicht ändern zu müssen, die viele bereits vorhandene Anwendungen im Prozess beschädigen würde. Der dritte Parameter ist ein P ointer zu einem STR ing.Also müssen wir uns selbst fragen, was ist ein
HANDLE
? In den folgendenWin32
API
Dokumenten finden Sie Informationen zu Windows-Datentypen :Jetzt haben wir noch einen
typedef
. Was ist einPVOID
? Nun, es sollte offensichtlich sein, aber lassen Sie uns das in der gleichen Tabelle nachschlagen ...A
HANDLE
wird verwendet, um viele Objekte in den folgendenWin32
API
Dingen zu deklarieren :HKEY
- Ein Handle für einen Registrierungsschlüssel. In WinDef.h deklarierttypdef HANDLE HKEY;
HKL
- Ein Handle zu einer Gebietsschemabezeichnung. In WinDef.h deklarierttypdef HANDLE HKL;
HMENU
- Ein Griff zu einem Menü. In WinDef.h deklarierttypdef HANDLE HMENU;
HPEN
- Ein Griff zu einem Stift. In WinDef.h deklarierttypedef HANDLE HPEN;
HWND
- Ein Griff an ein Fenster. In WinDef.h deklarierttypedef HANDLE HWND;
HBRUSH
,HCURSOR
,HBITMAP
,HDC
,HDESK
, usw.Dies sind alles
typedefs
,typedef
was mit a, das a ist, deklariert wird,HANDLE
und dasHANDLE
selbst wird alstypedef
von a,PVOID
das auch a ist,typedef
zu a deklariertvoid pointer
.Wenn es also darum geht,
LPCTSTR
können wir das in den gleichen Dokumenten finden:So hoffentlich wird dies als Leitfaden helfen , wie die Verwendungen zu verstehen ,
typedefs
vor allem mit den Windows - Datentypen , die in der zu finden sindWin32
API
.quelle
HANDLE
Aliase, wenn Sie dasSTRICT
Makro aktivieren . Welches ist der Standard in neuen Projekten, denke ich.