vba 7 - recuperar valores de RegQueryValueEx retorna string unicode
Pergunta
Não consigo entender por que recebo de volta uma string Unicode com caracteres extras por letra
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
O Regdata tem o seguinte valor "Livro de endereços móveis", mas se você colar isso no bloco de notas, verá todos os caracteres extras.Preciso converter a string para ascii?
Solução
O VBA usa strings Unicode, mas você está chamando o Ansi versão de RegQueryValueEx()
(RegQueryValueExA
) ao invés de Unicode versão (RegQueryValueExW
).Mas em ambos os casos, o 5º parâmetro receberá dados Ansi/Unicode brutos (dependendo da versão chamada) e o 6º parâmetro será expresso em bytes, não em personagens.Então você tem que prestar contas disso.Você também deve levar em conta o fato de que Declare
em VBA sempre converte String
valores para Ansi, nunca para Unicode.Para trabalhar com APIs Unicode usando strings Unicode em VBA, dê uma olhada no seguinte artigo para obter dicas:
VBA:Strings Unicode e a API do Windows
Por exemplo:
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
Apenas certifique-se de que RegData
é pré-alocado para o número necessário de Caracteres Unicode necessário para receber o texto Unicode, e que lDataBufSize
é inicializado com o número de bytes alocado em RegData
então RegQueryValueExW()
sabe em quantos caracteres pode escrever RegData
.
Atualizar:para ler dados binários:
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