<-- Capítulo IX

Regresar a la página principal

Capítulo XI -->

Capítulo X

Registro de Windows y archivos .ini

En algunas ocasiones, nuestros programas necesitan alguna información para poder funcionar, dicha información podemos almacenarlas en una bases de datos o en un archivo cualquiera, pero existen estructuras cómodas y seguras para almacenar dicha información y utilizarla cuando creamos conveniente.

Todos ustedes deberán de haber escuchado o visto el “registro de Windows”, en dicho registro se encuentra configurado casi todo Windows, es decir, los colores que ven, el tipo de letra, el uso horario, las dll, los programas, los drivers, se podría decir que toda la configuración de Windows se encuentra en el registro, un mal uso de dicho registro podría ocasionar fallas irreversibles que podrían trancar su computadora y tendrían que reinstalar Windows de nuevo. En este capitulo introduciremos ¿cómo es el registro de Windows?, entraremos en él teniendo siempre cuidado de lo que hagamos en su interior.

Otra forma de guardar información de manera estructurada son en los archivos .ini, dichos archivos se mantienen hoy en día, para mantener la compatibilidad con sistemas de 16 Bits, ya que, Microsoft lo que recomienda es usar el registro en vez de archivos .ini, pero estos archivos siguen siendo utilizado, ya que presentan una forma rápida y simple de acceder a datos estructurados. Quedara del programador juzgar que usar en su momento. Personalmente uso normalmente el registro ya que un archivo .ini puede ser borrado con cierta facilidad por el usuario, en cambio muy pocas veces un usuario tradicional entra en el registro de Windows, sin contar que el propio Windows respalda de manera automática el registro de Windows, es decir, Windows protege nuestra información.

En este capitulo veremos las funciones Api’s que permiten manipular estas dos formas de almacenar información de manera estructurada.

REGISTRO DE WINDOWS

Vamos a presionar el botón de “inicio” luego seleccionen “ejecutar” y en el formulario de ejecución coloquen “regedit”, al presionar ENTER verán que se abre como una especie de programa, el cual contiene la estructura del registro de Windows.

Antes que nada verán como una especie de árbol, que muestra las siguientes carpetas:

HKEY_CLASSES_ROOT

HKEY_CURRENT_CONFIG

HKEY_CURRENT_USER

HKEY_DYN_DATA

HKEY_LOCAL_MACHINE

HKEY_PERFORMANCE_DATA (solo en Windows NT)

HKEY_USERS

NOTA: mencione “carpetas”, en realidad en la documentación de Microsoft no se refieren a lo mencionado como carpeta sino como “key” o “clave”, personalmente en las explicaciones voy a usar “carpeta” ya que es la figurita que posee como icono. Y considero mas cómodo este termino que el termino “key”, pero esto lo menciono para aquellos que lean la documentación oficial. Las carpetas que contiene cada carpeta las llamaré “sub-carpetas” que seria lo equivalente a “subkey”.

HKEY_CLASSES_ROOT

Esta carpeta contiene en pocas palabras, la configuración de las extensiones de archivos, objetos OLE, etc, es decir, ustedes se darán cuenta que un archivo de Word, posee un icono particular que lo identifica, y cada vez que le dan dobleclick abre inmediatamente el programa Word, dicha configuración se encuentra en esta sección. No voy a entrar en detalle en como se hace este proceso ya que eso no es tema de este manual, mi misión será enseñarles como “manipular” información en el registro.

HKEY_CURRENT_CONFIG

En esta sección podemos ver la configuración actual de algunos dispositivos.

HKEY_CURRENT_USER

En esta sección vemos la configuración del usuario actual, es decir, aquí podemos encontrar información sobre su wallpaper, colores personalizados, etc.

HKEY_USERS

En esta sección vemos al igual que la explicación anterior la configuración pero ahora no de un solo usuario sino de los usuario configurados por el sistema.

¿Cuál es la diferencia entre HKEY_CURRENT_USER y HKEY_USERS? Todos sabemos que en Windows podemos configurar distintos usuarios, cada usuario puede entrar con su clave e inicie una especie de sesión, un usuario A por ejemplo puede tener un wallpaper de una playa, y el usuario B puede tener un wallpaper de una montaña, cuando cada usuario inicia su sesión, Windows busca su configuración en HKEY_USERS y la pega en HKEY_CURRENT_USER, con esto quiero que vean que la información que posee HKEY_CURRENT_USER es variable y puede cambiar, esto lo tienen que tener en cuenta al momento que quieran guardar alguna información. Inclusive lo que hay en HKEY_CURRENT_USER se encuentra repetido en HKEY_USER, cuando el usuario cierra su sesión, Windows guarda la información en HKEY_USERS.

HKEY_LOCAL_MACHINE

Aquí podemos encontrar información acerca de nuestra computadora, es decir, me refiero a la parte física y también a la parte de software.

Aquí mencione un resumen de cómo son mas o menos las carpetas principales del registro de Windows, dejo en claro que las carpetas que se creen tienen que ser dentro de alguna que explique arriba, es decir, no pueden crear una carpeta en el ROOT del registro. Y tampoco pueden borrar ninguna de las que menciones.

Para este proyecto se necesitan 10 botones, 2 listbox y una etiqueta o label. Luego peguen este código en el formulario:

Ver Codigo

Corren la aplicación, pero mantengan el programa “regedit” abierto. Primero presionen el botón “Crear key”, luego de haberlo presionado se van al programa regedit, y vayan a este ubicación “HKEY_LOCAL_MACHINE\Software”, en el listado busquen la carpeta “MiPrueba” se darán cuenta que no tiene subcarpetas, en caso de no verlo presionen F5 para refrescar el registro.

Ahora presionen el botón “Crear Subkey”, vayan al programa “regedit” y con la carpeta “MiPrueba” seleccionada presionen F5 y se darán cuenta que ahora hay 3 subcarpetas. “carpeta1”, “carpeta2” y “carpeta3”, dichas carpetas no tiene información todavía. Ahora presionen “Crear Value” y luego presionan F5, y se darán cuenta que en “carpeta1”, ahora hay 3 valores: “Valor1” que es de tipo String, “Valor2” que es de tipo binario y “Valor3” que es de tipo DWORD, Dword es una variable de 32 Bits, o 4 byte, lo que seria equivalente a una variable del tipo long.

Al presionar “Enumerar Keys” se muestra en el listbox1 las carpetas que contiene “MiPrueba”, y al presionar “Enumerar Values” se muestra en el listbox2 los datos almacenados en la “carpeta1”. Los demás botones serán explicados cuando explique las funciones involucradas.

RegCreateKeyEx

Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, lpSecurityAttributes As Any, phkResult As Long, lpdwDisposition As Long) As Long

Con esta función creamos o abrimos una “carpeta” o key, dejo en claro algo, “subcarpeta” y “carpeta” son lo mismo, al momento de crearlas, es decir, llamamos subcarpetas a las carpetas que están subordinadas por otras, es decir, la función para crear cualquier carpeta es esta. Esto lo menciono por si esperan una función para crear los “subkeys” o “subcarpetas”, función que no existe ya que es esta misma.

“hkey” = le podemos pasar una de las siguientes constantes:

Private Const HKEY_CLASSES_ROOT = &H80000000

Private Const HKEY_CURRENT_CONFIG = &H80000005

Private Const HKEY_CURRENT_USER = &H80000001

Private Const HKEY_DYN_DATA = &H80000006

Private Const HKEY_LOCAL_MACHINE = &H80000002

Private Const HKEY_PERF_ROOT = HKEY_LOCAL_MACHINE

Private Const HKEY_PERFORMANCE_DATA = &H80000004

Private Const HKEY_USERS = &H80000003

Es decir, con estas constantes configuramos en que carpeta del ROOT estará contenida nuestra nueva carpeta.

“lpSubKey” = le pasamos la ubicación de nuestra nueva carpeta. El tercer parámetro “Reserved” siempre se la pasa 0.

“lpClass” = es una forma de identificar nuestras carpetas, en realidad es de tipo String e identifica el tipo de carpeta, !!en español!!, podemos tener 10 carpetas e identificar las primeras 5 con datos del programa, y las otras 5 datos del usuario, entonces podemos poner en este parámetro en las primeras 5 el valor de “PROGRAM” y las otras 5 el valor de “USER”, en cierta forma identificamos que tipo de carpeta es. Lo que puede servir al momento de consultarlas.

“dwOptions” = puede tomar las siguientes constantes:

Private Const REG_OPTION_BACKUP_RESTORE = 4

Private Const REG_OPTION_NON_VOLATILE = 0 ‘ La carpeta o key es no volátil, esta opción es por defecto. La información es almacenada en un archivo y es conservada cuando el sistema es reiniciado.

Private Const REG_OPTION_VOLATILE = 1 ‘ En Windows 95 es ignorado. En NT, implica que la información es almacenada en memoria y no es conservada cuando el sistema es reiniciado.

“samDesired” = especificamos los permisos de la nueva carpeta, en esto parámetro podemos usar el OR para especificar mas de una constante:

KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE)) ‘ Con esto especificamos que nuestra carpeta esta siendo abierta o creada solo con permiso para leer, en pocas palabras no podemos grabar en dicha carpeta.

KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE)) ‘ Con este parametro tenemos acceso total en nuestra carpeta.

KEY_EXECUTE = (KEY_READ) ‘Es lo equivalente a tener permiso solo para leer.

KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE)) ‘ Con esta constante tenemos permiso para escribir en nuestra carpeta.

KEY_CREATE_SUB_KEY = &H4 ‘ Tenemos permiso para crear otras capetas o subcarpetas. Que estén contenidas en la carpeta creada o abierta.

KEY_ENUMERATE_SUB_KEYS = &H8 ‘ Tenemos permiso para enumerar las carpetas o subcarpetas de una carpeta abierta.

KEY_QUERY_VALUE = &H1 ‘ Tenemos permiso para consultar los valores que contenga la carpeta.

KEY_SET_VALUE = &H2 ‘ Tenemos permiso para crear o alterar los valores de una carpeta.

“lpSecurityAttributes” = en la función esta declarada del tipo “Any” dicha declaración esta hecha a propósito, en realidad este parámetro es del tipo SECURITY_ATTRIBUTES:

Private Type SECURITY_ATTRIBUTES

nLength As Long

lpSecurityDescriptor As Long

bInheritHandle As Long

End Type

Lo que sucede es que como no vamos a usar dicha estructura, cambie la declaración en la función para que no tuviera problema al momento de ejecutarla. Dicha estructura posee mas funcionalidad en NT.

“phkResult” = es quien va a tener el “handle” de la carpeta o “key” creada o abierta. Dicha variable es la que utilizamos en la manipulación de dicha carpeta.

“lpdwDisposition” = parámetro el cual después de ejecutar la función puede tener 2 valores:

Private Const REG_CREATED_NEW_KEY = &H1 ‘ Esta constante determina que la carpeta fue creada.

Private Const REG_OPENED_EXISTING_KEY = &H2 ‘ Esta constante especifica que ya existía la carpeta.

RegCloseKey

Api: Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long

Esta función cierra el “handle” de una carpeta que haya sido abierta. Como único parámetro se le pasa dicho “handle”.

En nuestro proyecto estas dos funciones la usamos en el primer botón como se indica:

RegCreateKeyEx HKEY_LOCAL_MACHINE, "Software\MiPrueba", 0, "REG_DWORD", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, ByVal 0&, hKey, resultado

Creamos una carpeta en HKEY_LOCAL_MACHINE, en la carpeta “Software” y la carpeta nueva se llama “MiPrueba”, la identifico como “REG_DWORD” pero puedes poner el nombre que quiera, le especifico que sea volátil, con todos los accesos, la variable “hkey” sirve para almacenar el “handle” de la carpeta

If resultado And REG_CREATED_NEW_KEY Then ‘ Verificamos si fue creado con existo o si ya estaba creada.

Label1 = "Se ha creado la nueva clave o key"

Else

Label1 = "Ya existe la clave o key"

End If

RegCloseKey hKey ‘ Cerramos el “handle”.

RegOpenKeyEx

Api: Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long

Esta función se utiliza para abrir una carpeta o “key” ya existente.

“hkey” = Toma las mismas constantes que la función RegCreateKeyEx.

“lpSubKey” = Aquí se especifica la ubicación de la carpeta o “key” que se quiere abrir.

“ulOptions” = reservado, siempre se le paso 0.

“samDesired” = Tomas las mismas constantes que la función RegCreateKeyEx.

“phkResult” = La variable que se le pase en este parámetro tomara el “handle”, de la carpeta abierta.

La función en caso de abrir con éxito la carpeta retornara ERROR_SUCCESS.

RegSetValueEx

Api: Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long

Esta función sirve para asignarles valores a la carpeta, que fue abierta con RegOpenKeyEx, el termino “valores” en la ayuda de MSDN se le denomina “data”.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro de “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“lpValueName” = aquí colocamos el nombre del valor o “data”.

“reserved” = reservado, se le pasa siempre 0.

“dwType” = especificamos el tipo de dato que queremos almacenar, puede tomar las siguientes constantes:

Private Const REG_BINARY = 3 ‘ Especifica que el valor es binario

Private Const REG_DWORD = 4 ‘ Especifica que el valor es de tipo long o de 32 bits.

Private Const REG_DWORD_BIG_ENDIAN = 5 ‘ Especifica un valor del tipo long, pero que se organiza de la siguiente manera: 0x12345678 = (0x12 0x34 0x56 0x78)

Private Const REG_DWORD_LITTLE_ENDIAN = 4 ‘ Especifica un valor del tipo long, pero que se organiza de la siguiente manera: 0x12345678 = (0x78 0x56 0x34 0x12)

Private Const REG_EXPAND_SZ = 2 ‘ Usado para cadenas de texto que contienen que referencia a variables globales o “environment variables”.

Private Const REG_LINK = 6 ‘ Unicode simbolic link.

Private Const REG_MULTI_SZ = 7 ‘ Especifica un arreglo de cadena.

Private Const REG_NONE = 0 ‘ No define ningún valor

Private Const REG_RESOURCE_LIST = 8 ‘ Especifica una lista de recursos de un driver.

Private Const REG_SZ = 1 ‘ Especifica que el valor es del tipo texto

“lpData” = aquí pasamos el valor.

“cbData” = pasamos el tamaño del valor.

En el código lo usamos de esta manera:

resultado = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\MiPrueba\carpeta1", 0, KEY_ALL_ACCESS, hKey) ‘ Abrimos la carpeta “carpeta1”, con todos los accesos.

If resultado = ERROR_SUCCESS Then ‘ Si tenemos éxito.

Dim cadena As String

Dim cadena2 As String

cadena = "Datos tipo string"

RegSetValueEx hKey, "", 0, REG_SZ, ByVal cadena, Len(cadena) ‘ Guardo la cadena en el renglón de “valor predeterminado”

RegSetValueEx hKey, "Valor1", 0, REG_SZ, ByVal cadena, Len(cadena) ‘ Creo un nuevo valor llamado “valor1” y le paso también la cadena.

RegSetValueEx hKey, "Valor2", 0, REG_BINARY, 65535, 4 ‘ Especifico un valor binario que conste de 4 bytes.

RegSetValueEx hKey, "Valor3", 0, REG_DWORD, 2532, 4 ‘ Creamos un valor de tipo Dword, su tamaño siempre será de 4 bytes, BINARY puede ser mas grande o mas pequeño, no se confundan por que se vean de igual tamaño.

Else

Label1 = "error al abrir la clave o key"

End If

RegCloseKey hKey ‘ Cierro el “handle”.

RegEnumKeyEx

Api: Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As Any) As Long

Esta función sirve para enumerar las subcarpetas o subkeys de una carpeta ya abierta.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“dwIndex” = aquí colocamos el índice de la carpeta a recuperar.

“lpName” = variable que almacenara el nombre de la carpeta.

“lpcbName” = aquí especificamos el tamaño en bytes de la cadena “lpName” que queremos recuperar.

“lpReserved” = reservado, siempre pondrán 0.

“lpClass” = variable que almacenara el nombre de la clase.

“lpcbClass” = aquí especificamos el tamaño en bytes de la cadena “lpClass” que queremos recuperar.

“lpftLastWriteTime” = aunque en la función esta variable es del tipo ANY originalmente se le pasa una estructura que no vamos a usar en este momento que es:

Private Type FILETIME

dwLowDateTime As Long ‘Especifica la parte baja o 32 Bits del “file time”.

dwHighDateTime As Long ‘Especifica la parte alta o 32 bits del “file time”.

End Type

Estructura explicada en la sección de Archivos.

En nuestro caso no hay necesidad de usar dicha información.

En el código el uso de la función se representa de la siguiente manera:

resultado = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\MiPrueba", 0, KEY_ALL_ACCESS, hKey) ‘Abrimos nuestra carpeta ya creada.

.

Declaramos variables

.

maximo = 255 ‘Especificamos la cantidad de bytes que queremos recuperar.

nombre = Space(maximo) ‘Llenamos con espacios en blanco la variable que almacenara la información-.

.

.

If resultado = ERROR_SUCCESS Then

While RegEnumKeyEx(hKey, cnt, nombre, maximo, ByVal 0&, nombrec, maximoc, ByVal 0&) <> ERROR_NO_MORE_ITEMS ‘Mientras existan subcarpetas.

List1.AddItem Left$(nombre, maximo) & " clase = " & nombrec ‘Añadimos el nombre de la carpeta y la clase a la cual pertenece, dejo en claro que en Windows 98 no me retorno el nombre de la clase pero en Windows 2000 si lo retorna.

cnt = cnt + 1 ‘Muevo el índice “dwIndex”

‘Reconfiguro las variables.

Wend

End If

RegCloseKey hKey ‘Cierro la carpeta.

Hay que destacar que después que la función RegEnumKeyEx se ejecuta, el valor que posee la variable “máximo” es la cantidad de caracteres que posee la cadena. Lo mismo se aplica para “maximoc”, con la función Left, lo que estoy haciendo es desechando los espacios en blancos sobrantes. Es esa la razón del por que “reconfiguro las variables”.

RegEnumValue

Api: Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

Función que sirve para enumerar o retornar todos los valores que puede poseer una carpeta o key que se encuentre abierto. Es muy parecido su uso a la función RegEnumKeyEx.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro de “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“dwIndex” = aquí colocamos el índice del valor a recuperar.

“lpValueName” = variable que almacenara el nombre del valor o data.

“lpcbValueName” = aquí especificamos el tamaño en bytes de la cadena “lpValueName” que queremos recuperar.

“lpReserved” = reservado, siempre pondrán 0.

“lpType” = variable que almacena el tipo de valor. Puede tomar los mismos valores que los que toma la variable “dwType” en la función RegSetValueEx.

“lpData” = variable que contiene la información de dicho valor.

“lpcbData” = aquí especificamos el tamaño en bytes de la información que queremos recuperar en “lpData”, este tamaño dependerá de la “data” a recuperar, si es DWORD tendremos que pasar el valor de 4. En caso de ser una cadena tendremos que pasar el tamaño en bytes de lo que queremos recuperar. Y así, dependiendo del tipo de dato a recuperar. En nuestro caso recuperamos los datos del tipo REG_SZ.

En el código el uso de la función se representa de la siguiente manera:

.

.

.

If resultado = ERROR_SUCCESS Then

While RegEnumValue(hKey, cnt, nombre, maximo, ByVal 0&, tipo, ByVal valor, maximo2) <> ERROR_NO_MORE_ITEMS

If tipo = REG_SZ Then ‘ Tomamos los valores solo del tipo RG_SZ.

List2.AddItem Left$(nombre, maximo) & " valor = " & Left$(valor, maximo2)

End If

cnt = cnt + 1 ‘Muevo el índice “dwIndex”

‘Reconfiguro las variables.

Wend

End If

Como pueden ver su uso es muy similar a RegEnumKeyEx.

RegDeleteValue

Api: Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long

Función utilizada para eliminar un valor o data de cierta carpeta o key que este abierto.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro de “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“lpValueName” = nombre del valor o data a eliminar.

RegDeleteKey

Api: Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String) As Long

Función que elimina una subcarpeta o “subkey” del registro.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro de “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“lpSubKey” = nombre de la subcarpeta contenida en “hkey” que se quiera eliminar.

RegQueryValueEx

Api: Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long

Función utilizada para consultar la información de cierto valor o “data”.

“hkey” = aquí se le pasa el “handle” de la carpeta abierta, en pocas palabras la variable que usaron en el parámetro de “phkResult” en la función RegOpenKeyEx, es la variable que colocan aquí.

“lpValueName” = nombre del valor o data.

“lpReserved” = reservado, siempre pondrán 0.

“lpType” = variable que almacena el tipo de valor. Puede tomar los mismos valores que los que toma la variable “dwType” en la función RegSetValueEx.

“lpData” = variable que contiene la información de dicho valor.

“lpcbData” = aquí especificamos el tamaño en bytes de la información que queremos recuperar en “lpData”, este tamaño dependerá de la “data” a recuperar si es DWORD tendremos que pasar el valor de 4. En caso de ser una cadena tendremos que pasar el tamaño en bytes de lo que queremos recuperar. Y así, dependiendo del tipo de dato a recuperar. En nuestro caso recuperamos los datos del tipo REG_SZ.

Con esto cerramos la parte del registro de Windows, como pueden darse cuenta no es tan complicado utilizar el registro, y es bueno que se acostumbre a utilizarlo, para cuando quieran que su programa almacene información para algún uso especifico.

De todas, maneras vamos a ver ahora la segunda forma estructurada para almacenar información y me refiero a los archivos INI.

ARCHIVOS INI

Antes de ir al proyecto vamos a estudiar como esta estructurado un archivo *.ini, si abren cualquier archivo verán básicamente 2 cosas,

[TITULO]

Data = Valor

Data2 = Valor

[TITULO2]

Data = Valor

Data2 = Valor

Un archivo INI esta formado por secciones y cada sección, contiene sus valores, el nombre de los valores o data puede repetirse en diferentes secciones. Inclusive para recuperar algún valor siempre será necesario saber la sección donde el valor esta ubicado. Cabe mencionar que lo que llamamos “data” en la documentación oficial lo pueden ver como “key”.

Ya visto un poco la estructura del archivo INI, vamos al proyecto. El cual necesitara de 7 botones. Luego pegan este código en el formulario:

Ver Codigo

Pueden ir presionando los botones uno por uno, y medida que lo presionan vean el archivo “c:\ejemplo.ini”, que es el archivo que crea nuestro programa.

WritePrivateProfileSection

Api: Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpString As String, ByVal lpFileName As String) As Long

Esta función nos sirve para crear una sección, y un posible “dato” o “key” asociado a dicha sección

“lpAppName” = colocamos aquí la sección a crear.

“lpString” = posible “data” que queramos crear cuando se cree la sección.

“lpFileName” = ruta del archivo INI, si el archivo no existe la propia función lo crea.

En nuestro ejemplo lo usamos en el Command1:

WritePrivateProfileSection "sección 1", "", "c:\ejemplo.ini"

WritePrivateProfileSection "sección 2", "", "c:\ejemplo.ini"

WritePrivateProfileSection "sección 3", "", "c:\ejemplo.ini"

Con esto creamos 3 secciones vacías, en caso que inicialmente una de las secciones tenga algún valor seria algo así:

WritePrivateProfileSection "Seccion 1", "Data = valor", "c:\ejemplo.ini"

WritePrivateProfileString

Api: Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long

Esta función sirve para crear “key” o “data” del tipo string.

“lpApplicationName” = sección en donde se creara el “key”.

“lpKeyName” = nombre del “key” o “data”.

“lpString” = valor que contendrá el “key”.

“lpFileName” = ruta del archivo INI.

Ejemplo:

WritePrivateProfileString "sección 1", "Valor1", "texto", "c:\ejemplo.ini"

Introducimos en la “sección 1” , el “Valor1 = texto”.

En caso de querer pasar un número, traten a ese número como de tipo String.

Ejemplo:

WritePrivateProfileString "sección 2", "Valor1", "4412", "c:\ejemplo.ini"

GetPrivateProfileInt

Api: Declare Function GetPrivateProfileInt Lib "kernel32" Alias "GetPrivateProfileIntA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal nDefault As Long, ByVal lpFileName As String) As Long

Función utilizada para recuperar de una sección un valor de tipo entero.

“lpApplicationName” = sección en donde se encuentra el “key”.

“lpKeyName” = nombre del “key” o “data”.

“nDefault” = valor por defecto, que se emplea en caso de no existir el “key”, pasado en “lpKeyName”.

“lpFileName” = ruta del archivo INI.

Ejemplo:

Dim valor As Integer

valor = GetPrivateProfileInt("sección 2", "Valor1", 0, "c:\ejemplo.ini")

MsgBox valor

Como pueden ver el valor que retorna es el valor entero que solicitamos. “nDefault” significa que en caso de que no exista “Valor1”, la función retorna el valor por defecto que en nuestro caso es 0. Pero puede ser cualquier valor.

GetPrivateProfileString

Api: Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Función utilizada para recuperar de una sección un valor de tipo string.

“lpApplicationName” = sección en donde se encuentra el “key”.

“lpKeyName” = nombre del “key” o “data”.

“lpDefault” = valor por defecto, que se emplea en caso de no existir el “key”, pasado en “lpKeyName”.

“lpReturnesString” = variable en donde se almacenara la cadena de texto.

“nSize” = tamaño en bytes, de la cantidad de caracteres que queremos recuperar.

“lpFileName” = ruta del archivo INI.

Ejemplo:

Dim valor As String

Dim caract As Integer

valor = Space(255)

caract = GetPrivateProfileString("sección 1", "Valor3", "Defecto", valor, 255, "c:\ejemplo.ini")

MsgBox Left$(valor, caract)

En este caso la función retorna, la cantidad de caracteres que se recupero, dicha cantidad la almacena la variable “caract”.

GetPrivateProfileSection

Api: Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Función que sirve para retornar todos los “data” o “key” con sus respectivos valores de una sección especifica.

“lpApplicationName” = sección en donde se encuentra el “key”.

“lpReturnesString” = variable en donde se almacenara todos los “data” con sus respectivo valor.

“nSize” = tamaño en bytes, de la cantidad de caracteres que queremos recuperar.

“lpFileName” = ruta del archivo INI.

Ejemplo:

Dim valor As String

Dim caract As Integer

valor = Space(1000)

caract = GetPrivateProfileSection("sección 1", valor, 1000, "c:\ejemplo.ini")

Debug.Print valor

Como verán en la ventana “inmediato” de VB, podemos ver todos los “data” con su respectivo valor de la “sección 1”.

GetPrivateProfileSectionNames

Api: Declare Function GetPrivateProfileSectionNames Lib "kernel32.dll" Alias "GetPrivateProfileSectionNamesA" (ByVal lpszReturnBuffer As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Función que sirve para retornar todas las secciones de un archivo INI en específico.

“lpszReturnesBuffer” = variable en donde se almacenara todas las secciones del archivo INI.

“nSize” = tamaño en bytes, de la cantidad de caracteres que queremos recuperar.

“lpFileName” = ruta del archivo INI.

Ejemplo:

Dim valor As String

Dim caract As Integer

valor = Space(1000)

caract = GetPrivateProfileSectionNames(valor, 1000, "c:\ejemplo.ini")

Debug.Print valor

Hace lo mismo que la función anterior con la diferencia que con esta función tomamos el nombre de todas las secciones que posee el archivo INI en cuestión.

WriteProfileSection

Api: Declare Function WriteProfileSection Lib "kernel32" Alias "WriteProfileSectionA" (ByVal lpAppName As String, ByVal lpString As String) As Long

WriteProfileString

Api: Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (ByVal lpszSection As String, ByVal lpszKeyName As String, ByVal lpszString As String) As Long

GetProfileInt

Api: Declare Function GetProfileInt Lib "kernel32" Alias "GetProfileIntA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal nDefault As Long) As Long

GetProfileSection

Api: Declare Function GetProfileSection Lib "kernel32" Alias "GetProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long) As Long

GetProfileString

Api: Declare Function GetProfileString Lib "kernel32" Alias "GetProfileStringA" (ByVal lpAppName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long) As Long

Estas funciones no usadas en el código, hacen exactamente lo mismos que sus homologas de arriba, pueden ver que la diferencia en el nombre es que no tienen la palabra “Private”, y que no tienen como parámetro “lpFileName”, y esto se debe a que estas funciones sirven para escribir directamente en el archivo “win.ini”.

¿Qué usar? En realidad Microsoft quiere que la gente se olvide de los archivos INI y usen el registro de Windows, pero en mi opinión todo dependerá del proyecto a realizar, es claro que el registro de Windows es mas estructurado, mas versátil, permite mas tipos de valores, etc, pero algunas ocasiones los archivos INI nos saquen de aprietos de manera rápida y sencilla, ya que como se habrán dado cuenta, manejar el registro a nivel de programación es mas complicado que manejar los archivo INI. Pero algunas veces seria “tonto” usar el registro para almacenar un solo valor. Para ello seria mas optimo los archivos INI. Pero como dije todo dependerá del proyecto a realizar.

<-- Capítulo IX

Regresar arriba

Regresar a la página principal

Capítulo XI -->

Desarrollado por Eduardo Roa. Copyright 2002-2003 Todos los derechos reservados