O que significa LPCWSTR e como deve ser tratado?

91

Em primeiro lugar, o que é exatamente? Acho que é um ponteiro (LPC significa constante de ponteiro longo), mas o que significa "W"? É um ponteiro específico para uma string ou um ponteiro para uma string específica? Por exemplo, eu quero fechar uma janela chamada "TestWindow".

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

O código é ilegal e não funciona, pois const char [6] não pode ser convertido para CONST WCHAR. Eu não entendo nada. Quero obter uma compreensão clara de todos esses LPCWSTR, LPCSTR, LPSTR. Tentei encontrar algo, mas fiquei ainda mais confuso. No site msdn FindWindowExé declarado como

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

Portanto, o último parâmetro é LPCSTR e o compilador exige LPCWSTR. Por favor ajude.

lhj7362
fonte
61
Bem-vindo à notação húngara da Microsoft.
Thomas Matthews
2
na verdade, torna a documentação muito mais legível, pena tudo o mais sobre isso, sux.
Matt Joiner
1
@Thomas: Isso não é o que a Microsoft (ou Simonyi) inicialmente rotulou de Notação Húngara . É mais ou menos o resultado de um acidente, quando o grupo de documentação decidiu fazer algumas melhorias na "legibilidade". Eles não eram desenvolvedores e, conseqüentemente, as mudanças não foram graciosas. Informações
básicas
@IInspectable: Link quebrado
Nicolas Raoul
1
@IInspectable: o link ativo é blogs.msdn.microsoft.com/larryosterman/2004/06/22/…
Julius Bullinger

Respostas:

139

LPCWSTRsignifica "Ponteiro longo para string larga constante". O W significa Wide e significa que a string é armazenada em um caractere de 2 bytes em relação ao normal char. Comum para qualquer código C / C ++ que precise lidar apenas com strings não ASCII. =

Para obter uma string literal C normal para atribuir a a LPCWSTR, você precisa prefixá-la com L

LPCWSTR a = L"TestWindow";
JaredPar
fonte
8
Só para expandir - a parte 'LONGA' é uma ressaca das janelas de 16 bits e pode ser ignorada (exceto que você precisa disso no nome)
Martin Beckett
14
"ressaca do Windows de 16 bits" - Com certeza!
John Dibling
4
Não, está correto. Era e é um ponteiro de 32 bits. Não há mais ponteiros "curtos" de 16 bits, então você pode reclamar se conseguir encontrar um SPCWSTR.
MSalters de
51
Meu Deus. EU??? A letra L? Nem mesmo uma função, L ()? Simplesmente L? Quem diabos veio com isso ??
john ktejik
13
@ user396483 É comum em muitos idiomas adicionar prefixos e sufixos a constantes para alterar a forma como são representadas, sem alterar seu significado para humano. Por exemplo, 36ULem C # é o mesmo que (ulong)36(ulong sendo um inteiro sem sinal de 64 bits). @pode ser usado no mesmo idioma como um prefixo para strings, mudando ligeiramente a forma como são analisadas.
Zenexer
12

LPCWSTRé equivalente a wchar_t const *. É um ponteiro para uma ampla sequência de caracteres que não será modificada pela chamada de função.

Você pode atribuir a LPCWSTRs prefixando um L a um literal de string:LPCWSTR *myStr = L"Hello World";

LPC T STR e quaisquer outros tipos T , tomam um tipo de string dependendo das configurações Unicode para seu projeto. Se _UNICODEfor definido para o seu projeto, o uso de tipos T é o mesmo que as formas de caracteres largos, caso contrário, as formas Ansi. A função apropriada também será chamada desta forma: FindWindowExé definida como FindWindowExAou FindWindowExWdependendo desta definição.

Matt Joiner
fonte
7

É um ponteiro longo para uma string ampla e constante (ou seja, uma string de caracteres largos).

Desde que é uma grande corda, você quer fazer o seu constante olhar como: L"TestWindow". Eu também não criaria o intermediário a, apenas passaria L"TestWindow"o parâmetro:

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

Se você quiser ser pedantemente correto, um "LPCTSTR" é uma string de "texto" - uma string larga em uma construção Unicode e uma string estreita em uma construção ANSI, então você deve usar a macro apropriada:

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

Poucas pessoas se preocupam em produzir código que possa compilar para conjuntos de caracteres Unicode e ANSI, e se você não conseguir fazer com que ele realmente funcione corretamente, pode ser um pouco mais de trabalho extra com pouco ganho. Nesse caso específico, não há muito trabalho extra, mas se você estiver manipulando strings, há todo um conjunto de macros de manipulação de string que resultam nas funções corretas.

Jerry Coffin
fonte
1
você não precisa ser pedantemente correto, use _T () se você estiver usando constantes como _T (MAIN_WINDOW) caso contrário, LMAIN_WINDOW irá falhar.
Rodolfo