¿Qué significa LPCWSTR y cómo debe manejarse?

91

En primer lugar, ¿qué es exactamente? Supongo que es un puntero (LPC significa constante de puntero largo), pero ¿qué significa "W"? ¿Es un puntero específico a una cadena o un puntero a una cadena específica? Por ejemplo, quiero cerrar una ventana llamada "TestWindow".

HWND g_hTest;
LPCWSTR a;
*a = ("TestWindow");
g_hTest = FindWindowEx(NULL, NULL, NULL, a);
DestroyWindow(g_hTest);

El código es ilegal y no funciona ya que const char [6] no se puede convertir a CONST WCHAR. No lo entiendo en absoluto. Quiero tener una comprensión clara de todos estos LPCWSTR, LPCSTR, LPSTR. Traté de encontrar algo, pero me confundí aún más. En msdn, el sitio FindWindowExse declara como

HWND FindWindowEx(      
    HWND hwndParent,
    HWND hwndChildAfter,
    LPCTSTR lpszClass,
    LPCTSTR lpszWindow
);

Entonces, el último parámetro es LPCSTR, y el compilador exige a LPCWSTR. Por favor ayuda.

lhj7362
fuente
59
Bienvenido a la notación húngara de Microsoft.
Thomas Matthews
2
en realidad hace que la documentación sea mucho más legible, lástima todo lo demás sux.
Matt Joiner
1
@Thomas: Esto no es lo que Microsoft (o Simonyi para el caso) etiquetó inicialmente como notación húngara . Es más o menos el resultado de un accidente, cuando el grupo de documentación decidió ejercitar algunas mejoras de "legibilidad". No eran desarrolladores y, en consecuencia, los cambios no fueron agradables. La información de antecedentes está disponible en la notación Hugarian - es mi turno ahora :)
IInspectable
@IInspectable: Enlace roto
Nicolas Raoul
1
@IInspectable: el enlace de trabajo es blogs.msdn.microsoft.com/larryosterman/2004/06/22/…
Julius Bullinger

Respuestas:

137

LPCWSTRsignifica "Long Pointer to Constant Wide String". La W significa ancho y significa que la cadena se almacena en un carácter de 2 bytes frente a lo normal char. Común para cualquier código C / C ++ que tenga que lidiar solo con cadenas no ASCII. =

Para obtener una cadena literal de C normal para asignar a a LPCWSTR, debe anteponerla con L

LPCWSTR a = L"TestWindow";
JaredPar
fuente
8
Solo para expandir: la parte 'LARGA' es una resaca de las ventanas de 16 bits y se puede ignorar (excepto que la necesita en el nombre)
Martin Beckett
14
"resaca de Windows de 16 bits" - ¡Eso es seguro!
John Dibling
4
No, es correcto. Era y es un puntero de 32 bits. Ya no hay punteros "cortos" de 16 bits, por lo que podría quejarse si logra encontrar un SPCWSTR.
MSalters
50
Dios mío. L ??? ¿La letra L? ¿Ni siquiera una función, L ()? ¿Simplemente L? ¿A quién diablos se le ocurrió eso?
john ktejik
12
@ user396483 Es común en muchos idiomas agregar prefijos y sufijos a las constantes para cambiar cómo se representan, sin cambiar su significado para un humano. Por ejemplo, 36ULen C # es lo mismo que (ulong)36(ulong es un entero de 64 bits sin signo). @se puede usar en el mismo idioma que un prefijo para cadenas, cambiando ligeramente la forma en que se analizan.
Zenexer
12

LPCWSTRes equivalente a wchar_t const *. Es un puntero a una cadena de caracteres ancha que no será modificada por la llamada de función.

Puede asignar LPCWSTRas anteponiendo una L a un literal de cadena:LPCWSTR *myStr = L"Hello World";

LPC T STR y cualquier otro tipo de T , tome un tipo de cadena dependiendo de la configuración Unicode para su proyecto. Si _UNICODEse define para su proyecto, el uso de tipos T es el mismo que las formas de caracteres anchos, de lo contrario las formas Ansi. La función apropiada también se llamará de esta manera: FindWindowExse define como FindWindowExAo FindWindowExWdependiendo de esta definición.

Matt Joiner
fuente
7

Es un puntero largo a una cadena ancha y constante (es decir, una cadena de caracteres anchos).

Ya que es una cadena de ancho, que desea hacer su mirada constante como: L"TestWindow". Tampoco crearía el intermedio a, solo pasaría L"TestWindow"el parámetro:

ghTest = FindWindowEx(NULL, NULL, NULL, L"TestWindow");

Si quiere ser pedantemáticamente correcto, un "LPCTSTR" es una cadena de "texto": una cadena ancha en una compilación Unicode y una cadena estrecha en una compilación ANSI, por lo que debe usar la macro adecuada:

ghTest = FindWindow(NULL, NULL, NULL, _T("TestWindow"));

Sin embargo, pocas personas se preocupan por producir código que se pueda compilar tanto para juegos de caracteres Unicode como ANSI, y si no logras que funcione correctamente, puede ser un poco de trabajo extra por poca ganancia. En este caso particular, no hay mucho trabajo adicional, pero si está manipulando cadenas, hay un conjunto completo de macros de manipulación de cadenas que se resuelven en las funciones correctas.

Jerry Coffin
fuente
1
no necesita ser pedante correctamente, use _T () si está usando constantes como _T (MAIN_WINDOW) de lo contrario, LMAIN_WINDOW fallará.
Rodolfo