Что означает LPCWSTR и как с этим обращаться?

91

Прежде всего, что это такое? Я предполагаю, что это указатель (LPC означает константу длинного указателя), но что означает "W"? Это конкретный указатель на строку или указатель на конкретную строку? Например, я хочу закрыть окно с именем «TestWindow».

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

Код недопустим и не работает, поскольку const char [6] не может быть преобразован в CONST WCHAR. Я вообще этого не понимаю. Я хочу получить четкое представление обо всех этих LPCWSTR, LPCSTR, LPSTR. Я пытался что-то найти, но запутался еще больше. На сайте msdn FindWindowExобъявлено как

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

Итак, последний параметр - это LPCSTR, а компилятор требует LPCWSTR. Пожалуйста помоги.

lhj7362
источник
59
Добро пожаловать в венгерскую нотацию Microsoft.
Томас Мэтьюз,
2
на самом деле это делает документацию более читаемой, жаль всего остального, отстой.
Мэтт Джойнер
1
@Thomas: Это не то, что Microsoft (или Simonyi в этом отношении) изначально пометила венгерской нотацией . Это более или менее результат несчастного случая, когда группа документации решила внести некоторые улучшения в "читаемость". Они не были разработчиками, и поэтому изменения не были изящными. Справочная информация доступна в гугарской нотации - теперь моя очередь :)
Inspectable
@IInspectable: Неработающая ссылка
Николас Рауль
1
@IInspectable: рабочая ссылка blogs.msdn.microsoft.com/larryosterman/2004/06/22/…
Юлиус Буллингер,

Ответы:

137

LPCWSTRозначает «длинный указатель на постоянную широкую строку». W обозначает широкий и означает, что строка хранится в виде 2-байтового символа, а не обычного char. Общее для любого кода C / C ++, который имеет дело со строками, отличными от ASCII. =

Чтобы получить обычную буквальную строку C для присвоения a LPCWSTR, вам нужно добавить к ней префикс L

LPCWSTR a = L"TestWindow";
ДжаредПар
источник
8
Просто чтобы расширить - часть «ДЛИННАЯ» - это пережиток 16-битных окон, и ее можно проигнорировать (кроме того, что вам нужно это в названии)
Мартин Беккет,
14
«похмелье от 16-битной винды» - это точно!
Джон Диблинг,
4
Нет, это правильно. Это был и остается 32-битный указатель. Больше нет "коротких" 16-битных указателей, так что вы можете пожаловаться, если вам удастся найти SPCWSTR.
MSalters
50
О Господи. L ??? Буква L? Даже не функция L ()? Просто обычный L? Кто, черт возьми, это придумал ??
John Ktejik 06
12
@ user396483 Во многих языках принято добавлять префиксы и суффиксы к константам, чтобы изменить их представление, не изменяя их значение для человека. Например, 36ULв C # это то же самое, что (ulong)36(ulong - 64-битное целое число без знака). @может использоваться на том же языке в качестве префикса для строк, немного изменяя способ их анализа.
Zenexer
12

LPCWSTRэквивалентно wchar_t const *. Это указатель на строку широких символов, которая не будет изменена при вызове функции.

Вы можете присвоить LPCWSTRs, добавив L к строковому литералу:LPCWSTR *myStr = L"Hello World";

LPC T STR и любые другие типы T принимают строковый тип в зависимости от настроек Unicode для вашего проекта. Если _UNICODEопределено для вашего проекта, использование типов T такое же, как и формы широких символов, в противном случае формы Ansi. Соответствующая функция также будет вызываться таким образом: FindWindowExопределяется как FindWindowExAили в FindWindowExWзависимости от этого определения.

Мэтт Джойнер
источник
7

Это длинный указатель на постоянную широкую строку (т.е. строку широких символов).

Поскольку это широкая струна, вы хотите, чтобы ваш постоянный выглядеть следующим образом : L"TestWindow". Я бы тоже не стал создавать промежуточное звено a, просто передал L"TestWindow"бы параметр:

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

Если вы хотите быть педантично правильным, «LPCTSTR» - это «текстовая» строка - широкая строка в сборке Unicode и узкая строка в сборке ANSI, поэтому вам следует использовать соответствующий макрос:

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

Мало кто заботится о создании кода, который может компилироваться как для кодировок Unicode, так и для наборов символов ANSI, и если вы не добьетесь того, чтобы он действительно работал правильно, это может быть довольно большой дополнительной работой с небольшой прибылью. В этом конкретном случае дополнительной работы не так уж и много, но если вы манипулируете строками, есть целый набор макросов манипулирования строками, которые разрешают правильные функции.

Джерри Гроб
источник
1
вам не нужно быть педантично правильным, используйте _T (), если вы используете такие константы, как _T (MAIN_WINDOW), иначе LMAIN_WINDOW завершится ошибкой.
Rodolfo