cos'è LPCTSTR
e- LPCTSTR
like (ad esempio HDC
) e cosa rappresenta?
LPCSTR p, q;
e volevi avere const char *p, *q;
. Puoi rifiutarti di usarli?
cos'è LPCTSTR
e- LPCTSTR
like (ad esempio HDC
) e cosa rappresenta?
LPCSTR p, q;
e volevi avere const char *p, *q;
. Puoi rifiutarti di usarli?
Risposte:
Citando Brian Kramer sui forum MSDN
LPCTSTR
= L ong P intervallo a una C sulla T CHAR STR ing (Non preoccuparti, un puntatore lungo è uguale a un puntatore. C'erano due tipi di puntatori sotto finestre a 16 bit.)Ecco la tabella:
LPSTR
=char*
LPCSTR
=const char*
LPWSTR
=wchar_t*
LPCWSTR
=const wchar_t*
LPTSTR
= achar* or wchar_t*
seconda di_UNICODE
LPCTSTR
= aconst char* or const wchar_t*
seconda di_UNICODE
Non è necessario mai utilizzare nessuno dei tipi relativi a TCHAR.
Quei tipi, tutti i tipi di struttura che li utilizzano e tutte le funzioni correlate vengono mappati in fase di compilazione su una versione ANSI o UNICODE (in base alla configurazione del progetto). Le versioni ANSI in genere hanno una A aggiunta alla fine del nome e le versioni unicode aggiungono una W. Puoi usarle esplicitamente se preferisci. MSDN lo noterà quando necessario, ad esempio elenca una funzione MessageBoxIndirectA e MessageBoxIndirectW qui: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
A meno che non si stia prendendo di mira Windows 9x, che mancava di implementazioni di molte funzioni Unicode, non è necessario utilizzare le versioni ANSI. Se hai come target Windows 9x, puoi utilizzare TCHAR per creare un binario ansi e unicode dalla stessa base di codice, purché il tuo codice non faccia ipotesi sul fatto che TCHAR sia un carattere o un wchar.
Se non ti interessa Windows 9x, ti consiglio di configurare il tuo progetto come Unicode e di considerare TCHAR identico a WCHAR. Se lo preferisci, puoi utilizzare esplicitamente le funzioni e i tipi W, ma finché non prevedi di eseguire il tuo progetto su Windows 9x, non importa.
Questi tipi sono documentati in Tipi di dati di Windows su MSDN:
LPCTSTR
Un
LPCWSTR
ifUNICODE
è definito, unLPCSTR
altrimenti. Per ulteriori informazioni, consultare Tipi di dati di Windows per stringhe.Questo tipo è dichiarato in WinNT.h come segue:
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTR
Un puntatore a una stringa costante terminata con null di caratteri Unicode a 16 bit. Per ulteriori informazioni, vedere Set di caratteri utilizzati dai caratteri.
Questo tipo è dichiarato in WinNT.h come segue:
typedef CONST WCHAR *LPCWSTR;
HDC
Un handle per un contesto di dispositivo (DC).
Questo tipo è dichiarato in WinDef.h come segue:
typedef HANDLE HDC;
So che questa domanda è stata posta qualche tempo fa e non sto cercando di rispondere direttamente alla domanda originale esatta, ma poiché questo particolare Q / A ha una valutazione decente, vorrei aggiungere un po 'qui per i futuri lettori. Questo ha a che fare più specificamente conWin32
API
typedefs
e come capirli.
Se qualcuno ha mai fatto alcuna programmazione Windows durante l'era delle macchine a 32 bit da Windows 95 a Windows 7-8, capisce e sa che Win32
API
è caricato typedefs
e che la maggior parte delle sue funzioni e strutture che devono essere riempite e usato fa molto affidamento su di loro.
Ecco un programma Windows di base da dare come dimostrazione.
#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;
}
Questo codice è a malapena sufficiente per il rendering di un'applicazione Windows. Questa è la configurazione di base per inizializzare le proprietà minimali nude per il rendering di una finestra di base e, come puoi vedere, è già caricata typedefs
da Win32
api
.
Analizziamolo guardando le funzioni WinMain
e InitWindowsApp
: la prima cosa sono i parametri delle funzioni HINSTANCE
e PSTR
:
WinMain
accetta un singolo HINSTANCE
oggetto mentre InitWindowsApp
accetta due HINSTANCE
oggetti un oggetto PSTR o qualche altra typedef
stringa e un int.
Userò la InitWindowsApp
funzione qui poiché fornirà una descrizione dell'oggetto in entrambe le funzioni.
Il primo HINSTANCE
è definito come H andle di un ISTANZA e questo è quello più comunemente usato per l'applicazione. Il secondo è un altro HANDLE
di un ISTANZA precedente che viene raramente utilizzato più. È stato mantenuto per scopi legacy al fine di non dover cambiare la WinMain()
firma della funzione che avrebbe rotto molte applicazioni già esistenti nel processo. Il terzo parametro è un P ointer ad uno STR ing.
Quindi dobbiamo chiederci che cos'è un HANDLE
? Se guardiamo nei Win32
API
documenti trovati qui: Tipi di dati di Windows , possiamo facilmente cercarlo e vedere che è definito come:
Una maniglia per un oggetto. Questo tipo è dichiarato in WinNT.h come segue:
typedef PVOID HANDLE;
Ora ne abbiamo un altro typedef
. Che cos'è un PVOID
? Beh, dovrebbe essere ovvio, ma cerchiamo di cercarlo nella stessa tabella ...
Un puntatore a qualsiasi tipo. Questo è dichiarato in WinNT.h
typedef void *PVOID;
A HANDLE
è usato per dichiarare molti oggetti in Win32
API
cose come:
HKEY
- Un handle per una chiave di registro. Dichiarato in WinDef.h
typdef HANDLE HKEY;
HKL
- Un handle per un identificatore locale. Dichiarato in WinDef.h
typdef HANDLE HKL;
HMENU
- Una maniglia per un menu. Dichiarato in WinDef.h
typdef HANDLE HMENU;
HPEN
- Una maniglia per una penna. Dichiarato in WinDef.h
typedef HANDLE HPEN;
HWND
- Una maniglia per una finestra. Dichiarato in WinDef.h
typedef HANDLE HWND;
HBRUSH
, HCURSOR
, HBITMAP
, HDC
, HDESK
, etc.Questi sono tutto typedefs
ciò che viene dichiarato usando a typedef
che è a HANDLE
e lo HANDLE
stesso viene dichiarato come typedef
da a PVOID
che è anche typedef
a a void pointer
.
Quindi, quando si tratta di LPCTSTR
possiamo trovarlo negli stessi documenti:
È definito come un
LPCWSTR
ifUNICODE
definito oLPCSTR
altrimenti.
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
Quindi, si spera, questo aiuterà come guida su come comprendere gli usi typedefs
soprattutto con i tipi di dati di Windows che si possono trovare in Win32
API
.
HANDLE
alias se si attiva la STRICT
macro. Qual è l'impostazione predefinita nei nuovi progetti, credo.