Що означає 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. Будь ласка, допоможіть.


59
Ласкаво просимо до нотації угорської мови Microsoft.
Thomas Matthews

2
це насправді робить набагато читабельнішу документацію, шкода всього іншого про це sux.
Matt Joiner

1
@Thomas: Це не те, що Microsoft (чи Сімоні з цього приводу) спочатку позначив угорською нотацією . Це більш-менш результат аварії, коли група документації вирішила здійснити деякі вдосконалення "читабельності". Вони не були розробниками, а отже, зміни не були витонченими. Довідкова інформація доступна в
нотаціях Угорщини

@IInspectable: Поламане посилання
Ніколас Рауль,

Відповіді:


137

LPCWSTRрозшифровується як "Довгий вказівник на постійний широкий рядок". W означає Wide і означає, що рядок зберігається у 2-байтовому символі проти звичайного char. Загальне для будь-якого коду C / C ++, який має справу з рядками, що не належать до ASCII. =

Щоб отримати звичайний літеральний рядок C, який слід присвоїти a LPCWSTR, вам потрібно поставити префікс до L

LPCWSTR a = L"TestWindow";

8
Просто розширити - частина "LONG" є похміллям з 16-бітових вікон і може бути проігнорована (за винятком того, що це потрібно вам від імені)
Мартін Бекетт

14
"похмілля від 16-бітової Windows" - це точно!
Джон Дайблінг

4
Ні, це правильно. Це був і є 32-бітний покажчик. Більше немає "коротких" 16-бітових покажчиків, тому ви можете скаржитися, якщо вам вдасться знайти SPCWSTR.
MSalters

50
Боже мій. L ??? Буква L? Навіть не функція, L ()? Просто L? Хто це, біса, це придумав ??
john ktejik

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 не вдасться.
Родольфо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.