¿Qué es LPCTSTR
y LPCTSTR
como (por ejemplo HDC
) y qué significa?
LPCSTR p, q;
y lo que quería tener const char *p, *q;
. ¿Se puede negar a usarlos?
¿Qué es LPCTSTR
y LPCTSTR
como (por ejemplo HDC
) y qué significa?
LPCSTR p, q;
y lo que quería tener const char *p, *q;
. ¿Se puede negar a usarlos?
Respuestas:
Citando a Brian Kramer en los foros de MSDN
LPCTSTR
= L ong P ointer a una C onst T CHAR STR ing (No se preocupe, un puntero largo es lo mismo que un puntero. Había dos tipos de punteros debajo de ventanas de 16 bits).Aquí está la tabla:
LPSTR
=char*
LPCSTR
=const char*
LPWSTR
=wchar_t*
LPCWSTR
=const wchar_t*
LPTSTR
=char* or wchar_t*
dependiendo de_UNICODE
LPCTSTR
=const char* or const wchar_t*
dependiendo de_UNICODE
No hay necesidad de usar ninguno de los tipos relacionados con TCHAR.
Esos tipos, todos los tipos de estructura que los usan y todas las funciones relacionadas se asignan en tiempo de compilación a una versión ANSI o UNICODE (según la configuración de su proyecto). Las versiones ANSI generalmente tienen una A añadida al final del nombre, y las versiones Unicode agregan una W. Puede usarlas explícitamente si lo prefiere. MSDN lo notará cuando sea necesario, por ejemplo, enumera una función MessageBoxIndirectA y MessageBoxIndirectW aquí: http://msdn.microsoft.com/en-us/library/windows/desktop/ms645511(v=vs.85).aspx
A menos que esté apuntando a Windows 9x, que carecía de implementaciones de muchas funciones unicode, no hay necesidad de usar las versiones ANSI. Si está apuntando a Windows 9x, puede usar TCHAR para construir un binario ansi y unicode desde la misma base de código, siempre que su código no haga suposiciones sobre si TCHAR es char o wchar.
Si no le importa Windows 9x, le recomiendo configurar su proyecto como unicode y tratar TCHAR como idéntico a WCHAR. Puede usar explícitamente las funciones y tipos W si lo prefiere, pero siempre que no planee ejecutar su proyecto en Windows 9x, realmente no importa.
Estos tipos se documentan en Tipos de datos de Windows en MSDN:
LPCTSTR
Un
LPCWSTR
ifUNICODE
está definido, un loLPCSTR
contrario. Para obtener más información, consulte Tipos de datos de Windows para cadenas.Este tipo se declara en WinNT.h de la siguiente manera:
#ifdef UNICODE typedef LPCWSTR LPCTSTR; #else typedef LPCSTR LPCTSTR; #endif
LPCWSTR
Un puntero a una cadena constante terminada en nulo de caracteres Unicode de 16 bits. Para obtener más información, consulte Conjuntos de caracteres utilizados por las fuentes.
Este tipo se declara en WinNT.h de la siguiente manera:
typedef CONST WCHAR *LPCWSTR;
HDC
Un identificador para un contexto de dispositivo (DC).
Este tipo se declara en WinDef.h de la siguiente manera:
typedef HANDLE HDC;
Sé que esta pregunta se hizo hace bastante tiempo y no estoy tratando de responder directamente a la pregunta original exacta, pero como este Q / A en particular tiene una calificación decente, me gustaría agregar un poco aquí para futuros lectores. Esto tiene que ver más específicamente con Win32
API
typedefs
y cómo entenderlos.
Si alguien ha realizado alguna programación de Windows durante la era de las máquinas de 32 bits desde Windows 95 hasta Windows 7-8, entienden y saben que Win32
API
está cargado typedefs
y que la mayoría de sus funciones y estructuras se deben llenar y utilizado confiar en gran medida en ellos.
Aquí hay un programa básico de Windows para dar como demostración.
#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;
}
Este es apenas un código suficiente para representar una aplicación de Windows. Esta es la configuración más básica para inicializar las propiedades mínimas básicas para representar una ventana básica y, como puede ver, ya está cargada typedefs
desde Win32
api
.
Analicemos las funciones WinMain
y InitWindowsApp
: lo primero son los parámetros de las funciones HINSTANCE
y PSTR
:
WinMain
acepta un solo HINSTANCE
objeto mientras InitWindowsApp
acepta dos HINSTANCE
objetos, un objeto PSTR o alguna otra typedef
cadena y un int.
Usaré la InitWindowsApp
función aquí ya que dará una descripción del objeto en ambas funciones.
El primero HINSTANCE
se define como un H andle para un INSTANCE y este es el que se usa más comúnmente para la aplicación. El segundo es otro HANDLE
de un INSTANCE anterior que rara vez se usa más. Se mantuvo con fines heredados para no tener que cambiar la WinMain()
firma de la función que rompería muchas aplicaciones ya existentes en el proceso. El tercer parámetro es una P ointer a un STR ing.
Entonces tenemos que preguntarnos a nosotros mismos ¿qué es un HANDLE
? Si buscamos en los Win32
API
documentos que se encuentran aquí: Tipos de datos de Windows , podemos buscarlo fácilmente y ver que se define como:
Un asa para un objeto. Este tipo se declara en WinNT.h de la siguiente manera:
typedef PVOID HANDLE;
Ahora tenemos otro typedef
. ¿Qué es un PVOID
? Bueno, debería ser obvio, pero busquemos eso en la misma tabla ...
Un puntero a cualquier tipo. Esto se declara en WinNT.h
typedef void *PVOID;
A HANDLE
se usa para declarar muchos objetos en Win32
API
cosas como:
HKEY
- Un identificador para una clave de registro. Declarado en WinDef.h
typdef HANDLE HKEY;
HKL
- Un identificador para un identificador de configuración regional. Declarado en WinDef.h
typdef HANDLE HKL;
HMENU
- Un identificador para un menú. Declarado en WinDef.h
typdef HANDLE HMENU;
HPEN
- Un mango para un bolígrafo. Declarado en WinDef.h
typedef HANDLE HPEN;
HWND
- Un tirador a una ventana. Declarado en WinDef.h
typedef HANDLE HWND;
HBRUSH
, HCURSOR
, HBITMAP
, HDC
, HDESK
, etc.Estos son todos los typedefs
que se declaran usando a typedef
que es a HANDLE
y el HANDLE
mismo se declara como a typedef
desde a PVOID
que también es a typedef
a a void pointer
.
Entonces, cuando se trata de LPCTSTR
eso, podemos encontrar eso en los mismos documentos:
Se define como
LPCWSTR
siUNICODE
se define o deLPCSTR
otra manera.
#ifdef UNICODE
typedef LPCWSTR LPCSTR;
#else
typedef LPCSTR LPCTSTR;
#endif
Espero que esto ayude como guía sobre cómo entender los usos de typedefs
los tipos de datos de Windows que se pueden encontrar en el Win32
API
.
HANDLE
alias si activa la STRICT
macro. Cuál es el valor predeterminado en nuevos proyectos, creo.