vba 7: recuperar valores de RegQueryValueEx devuelve una cadena Unicode
Pregunta
No puedo entender por qué recibo una cadena Unicode con caracteres adicionales 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
RegData tiene el siguiente valor "Libra de direcciones móvil", pero si lo pega en el bloc de notas, verá todos los caracteres adicionales.¿Necesito convertir la cadena a ascii?
Solución
VBA usa cadenas Unicode, pero estás llamando al ansi versión de RegQueryValueEx()
(RegQueryValueExA
) en vez de Unicódigo versión (RegQueryValueExW
).Pero en ambos casos, el quinto parámetro recibirá datos Ansi/Unicode sin procesar (dependiendo de la versión llamada) y el sexto parámetro se expresa en bytes, no en caracteres.Entonces tienes que dar cuenta de eso.También hay que tener en cuenta el hecho de que Declare
en VBA siempre convierte String
valores a Ansi, nunca a Unicode.Para trabajar con API Unicode utilizando cadenas Unicode en VBA, consulte el siguiente artículo para obtener sugerencias:
VBA:Cadenas Unicode y la API de Windows
Por ejemplo:
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
Sólo asegúrate de que RegData
está preasignado al número requerido de caracteres Unicode necesario para recibir el texto Unicode, y que lDataBufSize
se inicializa con el número de bytes asignado en RegData
entonces RegQueryValueExW()
sabe en cuántos caracteres puede escribir RegData
.
Actualizar:para leer datos binarios:
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