Как преобразовать Qt QString в LPCTSTR в Windows - PullRequest
0 голосов
/ 25 июня 2018

Я пытался открыть реестр и изменить его. Вот как я открываю реестр:

HKEY hKey;
LPCTSTR subKey = TEXT("a registry subkey to be opened");
RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_ALL_ACCESS , &hKey);

Но вот проблема, я хочу использовать QString для прагматического изменения подраздела. И поставить QString так:

QString subKeyString = QString("%1").arg(subKeyName);
LPCTSTR subKey = TEXT(subKeyString); //but it's not working here

Я думал, что это потому, что я не изменил QString на LPCTSTR, я попробовал это решение, но все еще не могу найти способ поместить пользовательский QString в макрос TEXT. Я не совсем уверен, WinApi под капотом, я просто попытался, что я мог сделать.

Есть ли способ решить эту проблему?

Edit:
Вот как я конвертирую QString в LPCTSTR:

QString testString = "converting QString to LPCSTR";
QByteArray testStringArr = testString.toLocal8Bit();
LPCSTR lp = LPCSTR(testStringArr.constData()); //the QString is converted to LPCTSTR
//but when I put the LPCSTR to the TEXT macro, the error is still there, like the next line below will not complie
LPCSTR lp = TEXT(LPCSTR(testStringArr.constData())); //This line will not work

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Макрос TEXT() работает только с литералами времени компиляции, а не с данными времени выполнения.TCHAR и связанные API-интерфейсы были разработаны, чтобы помочь людям перенести свой код из Win9x / ME на основе ANSI в WinNT 4+ на основе Unicode, сопоставляя литералы между char и wchar_t и сопоставляя имена функций между A иW варианты.Но эти дни давно прошли.

правильное решение в этой ситуации - полностью игнорировать TCHAR и сосредоточиться только на Unicode.QString - это оболочка для строки Unicode.Поэтому используйте только функции API реестра на основе Unicode и притворяйтесь, что TCHAR не существует.

В Windows API на основе Unicode ожидают строки wchar_t в кодировке UTF-16.Используйте метод QString::toStdWString(), чтобы получить std::wstring, который является оболочкой C ++ для строки wchar_t:

QString subKeyString = QString("%1").arg(subKeyName);
std::wstring subKey = subKeyString.toStdWString();
HKEY hKey;
RegOpenKeyExW(HKEY_LOCAL_MACHINE, subKey.c_str(), 0, KEY_ALL_ACCESS, &hKey);

В качестве альтернативы, вы можете использовать метод QString::utf16().Однако он возвращает указатель const ushort*, поэтому вам придется привести его к типу const wchar_t*:

QString subKeyString = QString("%1").arg(subKeyName);
LPCWSTR subKey = reinterpret_cast<LPCWSTR>(subKeyString.utf16());
HKEY hKey;
RegOpenKeyExW(HKEY_LOCAL_MACHINE, subKey, 0, KEY_ALL_ACCESS, &hKey);
0 голосов
/ 25 июня 2018

Возможно, я немного опоздал на вечеринку, но, основываясь на двух других ответах, что-то настолько простое, как это смазывало бы колеса:

inline const WCHAR *QStoWCHAR (const QString& qs)
{
    return (const WCHAR *) qs.utf16 ();
}

И тогда вы можете это сделать (например,):

RegOpenKeyExW (HKEY_LOCAL_MACHINE, QStoWCHAR (my_qstring), 0, KEY_ALL_ACCESS, &hKey);
0 голосов
/ 25 июня 2018
Макрос

TEXT, как предполагалось, помогал поддерживать не-Unicode и Unicode версии приложения.В зависимости от того, определен ли _UNICODE (или UNICODE, не помню уже).TEXT("foo") расширится до L"foo" или до "foo".Аналогичным образом, CreateWindow будет либо CreateWindowW, который принимает WCHAR* параметры, либо CreateWindowA, который принимает CHAR* параметры.

Учитывая, что сейчас 2018 год, я предлагаю вам забыть о макросе TEXT ине-Unicode версии приложения.QString::utf16() вернет строки UTF16, которые ожидает WinAPI.Если вы компилируете с настройкой компилятора «Native wchar_t», вам нужно будет привести то, что utf16() возвращает к WCHAR*.Если "Native wchar_t` выключен, он будет работать как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...