Was ist LPCTSTR
und LPCTSTR
wie (zum Beispiel HDC
) und wofür steht es?
LPCSTR p, q;
und haben wollen const char *p, *q;
. Können Sie sich weigern, sie zu benutzen?
Was ist LPCTSTR
und LPCTSTR
wie (zum Beispiel HDC
) und wofür steht es?
LPCSTR p, q;
und haben wollen const char *p, *q;
. Können Sie sich weigern, sie zu benutzen?
Antworten:
Zitiert Brian Kramer in den MSDN-Foren
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
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.
Diese Typen sind unter Windows-Datentypen in MSDN dokumentiert :
LPCTSTR
Ein
LPCWSTR
WennUNICODE
ist definiert, einLPCSTR
Anderes. Weitere Informationen finden Sie unter Windows-Datentypen für Zeichenfolgen.Dieser Typ wird in WinNT.h wie folgt deklariert:
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTR
Ein Zeiger auf eine konstante nullterminierte Zeichenfolge mit 16-Bit-Unicode-Zeichen. Weitere Informationen finden Sie unter Von Schriftarten verwendete Zeichensätze.
Dieser Typ wird in WinNT.h wie folgt deklariert:
typedef CONST WCHAR *LPCWSTR;
HDC
Ein Handle zu einem Gerätekontext (DC).
Dieser Typ wird in WinDef.h wie folgt deklariert:
typedef HANDLE HDC;
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
mit typedefs
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.
#include <Windows.h>
HWND ghMainWnd = 0;
bool InitWindowsApp( HINSTANCE, int show );
LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
int run();
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int show ) {
if ( !InitWindowsApp( hInstance, showCmd ) ) {
return 0;
}
return run();
}
LRESULT CALLBACK WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
switch( msg ) {
case WM_KEYDOWN: {
if ( wParam == VK_ESCAPE ) {
DestroyWindow( ghMainWnd );
}
return 0;
}
case WM_DESTROY: {
PostQuitMessage(0);
return 0;
}
default: {
return DefWindowProc( hWnd, msg, wParam, lParam );
}
}
}
bool InitWindowsApp( HINSTANCE hInstance, int nCmdShow ) {
WNDCLASSEX wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = NULL;
wc.cbWndExtra = NULL;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.lpszMenuName = NULL;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszClassName = L"Basic Window";
wc.cbSize = sizeof( WNDCLASSEX);
if ( !RegisterClassEx( &wc ) ) {
MessageBox( NULL, L"Register Class FAILED", NULL, NULL );
return false;
}
ghMainWnd = CreateWindow(
L"Basic Window",
L"Win32Basic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL, NULL,
hInstance,
NULL );
if ( ghMainWnd == 0 ) {
MessageBox( NULL, L"Window failed to create", L"Error", MB_OK );
return false;
}
ShowWindow( ghMainWnd, nCmdShow );
UpdateWindow( ghMainWnd );
return true;
}
int run() {
MSG msg = {0};
BOOL bReturn = 1;
while( (bReturn = GetMessage( &msg, NULL, NULL, NULL)) != 0 ) {
if ( bReturn == -1 ) {
MessageBox( NULL, L"GetMessage FAILED", L"Error", MB_OK );
break;
} else {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
return (int)msg.wParam;
}
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 dem Win32
api
.
Lassen Sie es uns zusammenfassen, indem wir uns die WinMain
und InitWindowsApp
-Funktionen ansehen: Das Erste sind die Parameter der Funktionen HINSTANCE
und PSTR
:
WinMain
akzeptiert ein einzelnes HINSTANCE
Objekt, während InitWindowsApp
zwei HINSTANCE
Objekte ein PSTR-Objekt oder eine andere typedef
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 anderer HANDLE
zu 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 Win32
API
Dokumenten 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
typedef void *PVOID;
A HANDLE
wird verwendet, um viele Objekte in den folgenden Win32
API
Dingen 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;
HBRUSH
, HCURSOR
, HBITMAP
, HDC
, HDESK
, usw.Dies sind alles typedefs
, typedef
was mit a, das a ist, deklariert wird, HANDLE
und das HANDLE
selbst wird als typedef
von a, PVOID
das auch a ist, typedef
zu a deklariert void pointer
.
Wenn es also darum geht, LPCTSTR
können wir das in den gleichen Dokumenten finden:
Es ist definiert als
LPCWSTR
obUNICODE
definiert ist oderLPCSTR
nicht.
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
So hoffentlich wird dies als Leitfaden helfen , wie die Verwendungen zu verstehen , typedefs
vor allem mit den Windows - Datentypen , die in der zu finden sind Win32
API
.
HANDLE
Aliase, wenn Sie das STRICT
Makro aktivieren . Welches ist der Standard in neuen Projekten, denke ich.