vba 7 – получение значений из RegQueryValueEx возвращает строку Юникода
Вопрос
Я не могу понять, почему я получаю строку Юникода с дополнительным символом на букву
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll"
Alias "RegQueryValueExA" (ByVal hKey As LongPtr, ByVal lpValueName As String,
ByVal lpReserved As LongPtr, lpType As LongPtr,
lpData As Any, lpcbData As LongPtr) As LongPtr
If RegQueryValueEx(hKey, strValueName, 0, dwType,
ByVal RegData, lDataBufSize) = ERROR_SUCCESS Then
End If
У Regdata есть следующая ценность «мобильная адресная книга», но если вы вставьте это в Блокнот, вы увидите все дополнительные символы.Нужно ли мне конвертировать строку в ascii?
Решение
VBA использует строки Unicode, но вы вызываете Анси версия RegQueryValueEx()
(RegQueryValueExA
) вместо Юникод версия (RegQueryValueExW
).Но в обоих случаях пятый параметр получит необработанные данные Ansi/Unicode (в зависимости от вызываемой версии), а шестой параметр выражается в байты, не в персонажи.Так что вам придется это учитывать.Вы также должны учитывать тот факт, что Declare
в VBA всегда конвертирует String
значения в Ansi, а не в Unicode.Чтобы работать с API-интерфейсами Unicode с использованием строк Unicode в VBA, ознакомьтесь с подсказками в следующей статье:
ВБА:Строки Юникода и Windows API
Например:
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll"
Alias "RegQueryValueExW" (ByVal hKey As LongPtr, ByVal lpValueName As LongPtr,
ByVal lpReserved As LongPtr, lpType As LongPtr,
ByVal lpData As LongPtr, lpcbData As LongPtr) As LongPtr
If RegQueryValueEx(hKey, StrPtr(strValueName), 0, dwType,
StrPtr(RegData), lDataBufSize) = ERROR_SUCCESS Then
End If
Просто убедитесь, что RegData
заранее выделяется необходимое количество Символы Юникода необходимо получить текст Unicode, и это lDataBufSize
инициализируется числом байты выделено в RegData
так RegQueryValueExW()
знает, сколько символов он может записать RegData
.
Обновлять:для чтения двоичных данных:
Private Declare PtrSafe Function RegQueryValueEx Lib "advapi32.dll"
Alias "RegQueryValueExW" (ByVal hKey As LongPtr, ByVal lpValueName As LongPtr,
ByVal lpReserved As LongPtr, lpType As LongPtr,
lpData As Byte, lpcbData As LongPtr) As LongPtr
Dim RegData() As Byte
...
If RegQueryValueEx(hKey, StrPtr(strValueName), 0, dwType,
RegData(0), lDataBufSize) = ERROR_SUCCESS Then
End If