cos'è LPCTSTRe- LPCTSTRlike (ad esempio HDC) e cosa rappresenta?
LPCSTR p, q;e volevi avere const char *p, *q;. Puoi rifiutarti di usarli?
cos'è LPCTSTRe- LPCTSTRlike (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_UNICODELPCTSTR= 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:
LPCTSTRUn
LPCWSTRifUNICODEè definito, unLPCSTRaltrimenti. 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
LPCWSTRUn 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;
HDCUn 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 typedefse 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 typedefsda Win32 api.
Analizziamolo guardando le funzioni WinMaine InitWindowsApp: la prima cosa sono i parametri delle funzioni HINSTANCEe PSTR:
WinMainaccetta un singolo HINSTANCEoggetto mentre InitWindowsAppaccetta due HINSTANCEoggetti un oggetto PSTR o qualche altra typedefstringa e un int.
Userò la InitWindowsAppfunzione 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 HANDLEdi 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 APIdocumenti 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 APIcose 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 typedefsciò che viene dichiarato usando a typedefche è a HANDLEe lo HANDLEstesso viene dichiarato come typedefda a PVOIDche è anche typedefa a void pointer.
Quindi, quando si tratta di LPCTSTRpossiamo trovarlo negli stessi documenti:
È definito come un
LPCWSTRifUNICODEdefinito oLPCSTRaltrimenti.
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
Quindi, si spera, questo aiuterà come guida su come comprendere gli usi typedefssoprattutto con i tipi di dati di Windows che si possono trovare in Win32 API.
HANDLEalias se si attiva la STRICTmacro. Qual è l'impostazione predefinita nei nuovi progetti, credo.