Crèdit 5 -ASI

Introducció a les DLL de l'API de Windows



Visual Basic permite utilizar la interfaz de programación de aplicaciones (API) de Windows: incluya funciones de las bibliotecas de vínculos dinámicos (archivos .DLL) de la API de Windows.

En este capítulo:


Definición de DLL
Una biblioteca de vínculos dinámicos (DLL) es un conjunto de procedimientos, externos a la aplicación, a los que se puede llamar desde la aplicación. Las DLL no están enlazadas a su archivo ejecutable y, por tanto, pueden vincularse en tiempo de ejecución en lugar de cargarse en tiempo de compilación. Esto quiere decir que las bibliotecas pueden actualizarse independientemente de la aplicación y que múltiples aplicaciones pueden compartir una misma DLL.

La API de Windows
Windows proporciona archivos DLL que contienen rutinas a las que puede llamar desde Visual Basic. Dichas DLL crean la interfaz de programación de aplicaciones de Windows (API de Windows). De esta forma podemos llamar a las funciones de bajo nivel de Windows desde Visual Basic.


Las versiones de 32 bits del sistema operativo Windows (Windows 98 i posteriores) constan de tres DLL principales: User32, GDI32 y Kernel32. Estas DLL proporcionan la mayor parte de la funcionalidad de la API de Windows.


User32.dll trata las tareas relacionadas con la administración de ventanas, menús, controles y cuadros de diálogo. Por ejemplo, puede llamar al procedimiento FlashWindow de User32.dll para hacer que una ventana parpadee.


GDI32.dll se encarga de la presentación de gráficos.

Kernel32.dll se ocupa de las tareas del sistema operativo. Por ejemplo, puede llamar al procedimiento GetWindowsDirectory de Kernel32.dll para obtener la ruta de acceso actual de la carpeta de Windows.

Además de estas tres DLL, Windows contiene muchas otras DLL que amplían la funcionalidad de Visual Basic.

Utilización de una DLL
Hay dos pasos básicos para usar un procedimiento de una DLL:
1. Utilice la instrucción Declare para indicar a Visual Basic qué procedimiento desea usar.
2. Llame al procedimiento de una DLL desde el lugar adecuado del código.


Declarar un procedimiento
Los procedimientos de DLL residen en archivos externos a su aplicación de Visual Basic, por lo que debe declarar un procedimiento de una DLL antes de poder llamarlo. Al declarar un procedimiento se está proporcionando a Visual Basic la información que necesita para encontrar y ejecutar el procedimiento que se desea utilizar.


Ejemplo: en el código siguiente se declara la rutina de API FlashWindow (declaraciones generales de un módulo .BAS.)

Declare Function FlashWindow Lib "User32" _
   (ByVal hWnd As Long, ByVal bInvert As Long) _
   As Long
   

Llamar a un procedimiento
Cuando haya declarado un procedimiento, podrá invocarlo como si se tratara de un procedimiento de Visual Basic, como se muestra en la siguiente instrucción de código:

   lResultado = FlashWindow(form1.hWnd, 1)
 

Nota: Si declara la función en un módulo, puede utilizar el Examinador de objetos para pegar en su aplicación la llamada al procedimiento.

Guardar el trabajo
Visual Basic no puede comprobar si está pasando valores correctos a un procedimiento de una DLL. Si pasa valores incorrectos, es posible que falle la aplicación de Visual Basic. Por eso, es conveniente que guarde el trabajo frecuentemente cuando trabaje con archivos DLL.


Recuperar declaraciones con el Visor API

Puede utilizar el programa Visor API que se incluye con Visual Basic para recuperar las declaraciones correctas para los procedimientos de la API de Windows.

Cuando carga un archivo de texto API como el archivo Win32api.txt, el Visor API lee el archivo y muestra los tipos, constantes e instrucciones Declare para los procedimientos de la API de Windows. También se puede utilizar el Visor API para copiar una declaración al Portapapeles y después pegarla en su aplicación de Visual Basic.


Cargar una declaración desde una base de datos
Para recuperar determinadas declaraciones de DLL, es más rápido cargar y buscar un archivo de base de datos (.mdb) que buscar un archivo de texto (.txt). El Visor API le permite elegir entre buscar en el archivo de texto de API y convertir el archivo de texto a un archivo de base de datos. Cuando se le pregunte si desea crear una base de datos y responda afirmativamente, el Visor API creará un archivo de base de datos .mdb. A partir de ese momento podrá cargar el archivo .mdb siempre que utilice el Visor API.
Para obtener más información acerca de la finalidad de determinados procedimientos de DLL, vea el Win32 Software Development Kit (SDK) incluido en el CD-ROM de Microsoft Developer Network.


Determinar el alcance de un procedimiento de DLL
Si declara una DLL en un módulo estándar, la DLL es pública de forma predeterminada y el código puede llamarla desde cualquier lugar de la aplicación de Visual Basic. Para declarar un procedimiento de una DLL en un formulario o un módulo de clase, debe incluir la palabra clave Private en la declaración.

Tipos de datos de los argumentos
Las DLL normalmente se escriben en el lenguaje de programación C. Por tanto, los argumentos se definen mediante tipos de datos de C. Cuando utilice la instrucción Declare para una DLL de Visual Basic, deberá hacer coincidir el tipo de datos del argumento con el tipo de datos de C.
En la tabla siguiente se muestran las declaraciones en lenguaje C más utilizadas y sus equivalentes en Visual Basic para compiladores de 32 bits.

 
Declaraciones en lenguaje C Declaración de Visual Basic Llamar con
Puntero a una cadena (LPSTR) ByVal <variable> As String Cualquier variable String o Variant
char ByVal <variable> As Byte Una expresión que dé como resultado un tipo de datos Byte.
Integer ByVal <variable> As Long Una expresión que dé como resultado un tipo de datos Long
Controlador de Windows (hWnd, hDC, hMenu) ByVal <variable> As Long Una expresión que dé como resultado un tipo de datos Long.
NULL ByVal <variable> As String Una constante vbNullString.


Nota: En los compiladores antiguos de C de 16 bits, el tipo de datos int de C se asigna al tipo de datos Integer de Visual Basic. En los compiladores de C de 32 bits, el tipo de datos int de C se asigna al tipo de datos Long de Visual Basic.

Si desea ver una lista completa de los tipos de datos del lenguaje C y las directrices para utilizarlos en Visual Basic, consulte Conversión de declaraciones de C a Visual Basic en los Libros en pantalla de Visual Basic. Seleccione Acceso a las DLL y a la API de Windows para encontrar el salto al tema.

En las DLL, el tipo de datos del argumento determina el tipo de datos que va a devolver el procedimiento. De todas maneras, en Visual Basic puede definir un procedimiento de forma que su argumento acepte todos los tipos de datos.

Por ejemplo, suponga que desea que su aplicación de Visual Basic devuelva códigos postales para direcciones de España y de otros países. Puede definir un procedimiento de DLL que acepte tanto un valor numérico como un valor de cadena para este argumento.


Si su aplicación se utiliza en España, el tipo de datos Integer puede devolver el valor numérico del código postal. Si se utiliza en un país en el que no existen códigos postales, el tipo de datos String puede devolver un valor de cadena en vez de uno numérico.


Tipos de argumento flexibles
Para declarar un argumento que pueda aceptar más de un tipo de datos, utilice el tipo de datos Any. El tipo de datos Any indica que Visual Basic no comprueba el tipo: es decir, Visual Basic le permitirá pasar cualquier tipo de variable para este argumento.

Importante: debe asegurarse de que una DLL pueda aceptar el tipo de datos de un argumento. Si pasa un tipo de datos incorrecto, la DLL provocará un error de Windows de protección general.


A la hora de declarar un procedimiento de DLL, debe proporcionar el nombre de función correcto. Visual Basic traduce los argumentos de cadena procedentes de Visual Basic al procedimiento de DLL.


Juegos de caracteres ANSI y Unicode
Cada uno de los procedimientos de la API de Win32 que tiene argumentos de tipo cadena viene en dos versiones: el juego de caracteres ANSI y el juego de caracteres Unicode. En ANSI, cada byte representa un carácter, mientras que en Unicode, cada carácter está representado por dos bytes.


Traducción entre ANSI y Unicode
Internamente, Visual Basic 5 utiliza el juego de caracteres Unicode para almacenar cadenas. Sin embargo, cuando llame a una función de la API de Win32 tendrá que utilizar la versión ANSI de la función de la API. Cuando llama a un procedimiento de DLL, Visual Basic convierte automáticamente una cadena al formato ANSI. Cuando vuelve de un procedimiento de DLL, Visual Basic traduce de nuevo la cadena al formato Unicode.


Los nombres de las funciones de la API de Windows suelen tener el sufijo 'A' si son ANSI y 'W' si son Wide (Unicode). Si pega la instrucción Declare desde el Visor API, obtendrá el nombre ANSI correcto de la función.


Por ejemplo, para utilizar la función SetWindowText de la API de Win32, la declaración correcta es la siguiente:

   Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA"    _
   (ByVal hwnd As Long, ByVal lpString As String) as Long
   

Aunque su aplicación de Visual Basic llamará a SetWindowText, en realidad llamará a la versión ANSI de la función, SetWindowTextA.

Cuando un procedimiento de una DLL acepta un valor nulo, éste espera un valor cero (0) en lugar de una cadena vacía. Para pasar un valor nulo, declare el argumento con ByVal As String y pase la constante vbNullString, como se muestra en el código siguiente:

   Declare Function FindWindow Lib "User32" _
   Alias "FindWindowA" _
   (ByVal lpClassName As String, _
   ByVal lpCaption As String) As Integer
   
   rc = FindWindow (vbNullString, "Microsoft Word")