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?

Foi útil?

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top