¿Qué es LPCTSTRy LPCTSTRcomo (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 LPCTSTRy LPCTSTRcomo (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_UNICODELPCTSTR=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:
LPCTSTRUn
LPCWSTRifUNICODEestá definido, un loLPCSTRcontrario. 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
LPCWSTRUn 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;
HDCUn 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 typedefsy 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 APIestá cargado typedefsy 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 typedefsdesde Win32 api.
Analicemos las funciones WinMainy InitWindowsApp: lo primero son los parámetros de las funciones HINSTANCEy PSTR:
WinMainacepta un solo HINSTANCEobjeto mientras InitWindowsAppacepta dos HINSTANCEobjetos, un objeto PSTR o alguna otra typedefcadena y un int.
Usaré la InitWindowsAppfunción aquí ya que dará una descripción del objeto en ambas funciones.
El primero HINSTANCEse 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 HANDLEde 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 APIdocumentos 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 HANDLEse usa para declarar muchos objetos en Win32 APIcosas 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 typedefsque se declaran usando a typedefque es a HANDLEy el HANDLEmismo se declara como a typedefdesde a PVOIDque también es a typedefa a void pointer.
Entonces, cuando se trata de LPCTSTReso, podemos encontrar eso en los mismos documentos:
Se define como
LPCWSTRsiUNICODEse define o deLPCSTRotra 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 typedefslos tipos de datos de Windows que se pueden encontrar en el Win32 API.
HANDLEalias si activa la STRICTmacro. Cuál es el valor predeterminado en nuevos proyectos, creo.