viernes, 21 de noviembre de 2008

API´s de Windows: Parte 1

¿Qué es el API Win32 ?
Win32 es un conjunto de funciones, tipos y mensajes pre-definidos para poder programar sobre los sistemas operativos de 32 bits de Microsoft. El API Win32, surge para cubrir la necesidad de crear un sistema operativo
de 32 bits como es Windows 95, frente al API de 16 bits existente de Windows 3.1. Surge el problema de que Win32, no es compatible con el API de 16 bits, lo que implica que si queremos portar un código de Windows 3.1
a Windows 95, deberemos reescribir el código. Aunque hemos dicho que el API Win32 no es compatible con el
API de 16 bits, hay una versión que es Win32s que sirve para la versión 3.1 de Windows. Algunas de las limita- ciones entre ambos API son:
 No soportan nombres de ficheros largos, sólo el conocido formato 8.3 de DOS.
 No tiene API de comunicaciones.
 No soportan las capacidades Plug & Play.

________________________________________
Llamadas a las Funciones del API de Windows
Un programador de aplicaciones Windows además de conocer el entorno de trabajo de Windows debe
conocer también su entorno de programación, conocido generalmente como interfaz de programación de aplicaciones de Windows ( Windows Application Programming Interface, abreviadamente Windows API ).
La característica primaria de la API de Windows son las funciones y los mensajes internos/externos de
Windows.
Las funciones Windows son el corazón de las aplicaciones Windows. Hay más de 600 funciones de
Windows dispuestas para ser llamadas por cualquier lenguaje, como C o Visual Basic.
A través de estos mecanismos, podemos realizar gran cantidad de funciones que hasta el momento no
teníamos ni idea que se podían realizar. La utilización de ésta serie de librerías que contienen las funciones
de la API pueden solucionar gran cantidad de problemas en la programación, aunque también no debemos desestimar el gran poder destructivo de las mismas. La depuración de un programa es muy diferente si éste
tiene incorporadas llamadas a APIs, ya que el resultado de las mismas en algunos casos puede llegar a ser incomprensible. Cuando se trabaja con éstas funciones siempre es recomendable tener a mano una buena
guía o bien tener a mano alguien que sepa, para no encontrarnos con posibles problemas.
Las dos principales ventajas que obtenemos con la utilización de APIs es la gran funcionalidad que
podemos darle a nuestra aplicación, y en segundo lugar la gran velocidad de proceso, ya que a menudo es
mucho más rápido realizar una función a través de la API adecuada que por medio del lenguaje en si mismo.
Los mensajes son utilizados por Windows para permitir que dos o más aplicaciones se comuniquen entre
sí y con el propio sistema Windows. Se dice que las aplicaciones Windows son conducidas por mensajes o
sucesos.
Conocer todas las APIs de Windows es imposible, ya que tiene gran similitud con aprenderse la guía de teléfonos.
Lo que debemos hacer es realizar un razonamiento contrario, nosotros tenemos una necesidad a la
hora de programar, y debemos pensar que eso tiene una solución con una API.. En la mayoría de los casos
es así.
________________________________________
Librerías Dinámicas.
Casi todas las APIs de Windows se unen formando librerías de enlace dinámico.
Una librería dinámica ( Dynamic Link Libraries, abreviadamente DLLs ) permite que las aplicaciones
Windows compartan código y recursos. Una DLL es actualmente un fichero ejecutable que contiene funciones
de Windows que pueden ser utilizadas por todas las aplicaciones.
Si bien en DOS estamos acostumbrados a utilizar librerías de enlace estático, es decir, a la hora de
compilar incluyen junto con nuestro código, y de esta manera cuando se ejecuta nuestra aplicación, todas las librerías se cargan en memoria esperando a ser invocadas. Sin embargo, cuando trabajamos con DDLs, el
enlace con la aplicación es dinámico en tiempo de ejecución.
Una DDL no se incluye dentro de nuestro código, sino que en el momento que realizamos la llamada a
la función, la DLL se carga en memoria, se utiliza la API, y a continuación se descarga.
La gran ventaja que posee este método es que no es necesario tener gran cantidad de código cargado
en memoria a la hora de ejecutar nuestra aplicación. En contra, es necesario que cuando llevemos nuestro ejecutable a otra instalación, tengamos que llevar las DLLs necesarias.
También tenemos que pensar que si utilizamos las DLLS que nos proporciona Windows, en cualquier
máquina con este sistema operativo vamos a encontrar esas mismas DLLs, con lo cual no es necesario que
nos las llevemos.
La utilización de librerías dinámicas tiene ventajas. Una ventaja es que como están separadas del
programa se pueden actualizar sin tener que modificar los programas que las utilizan. Otra ventaja es el
ahorro de memoria principal y de disco ya que como es Windows quien administra la utilización de las DLLs,
no existe duplicidad de código cuando varias aplicaciones las utilizan.
También, como todo (jeje) tiene inconvenientes. Uno de ellos es el tiempo que Windows tiene que emplear
en leer las funciones que el programa necesita utilizar de una DLL.
Otra desventaja es que cada programa ejecutable necesita que estén presentes las DLLs que utiliza.
Cuando se utilizan librerías estáticas, las funciones que el programa necesita se incluyen en el mismo,
por lo que ni se pierde tiempo en leerlas ni la librería tiene que estar presente.
La mayoría de éstas librerías suelen estar localizadas en el directorio SYSTEM de Windows.
Dentro de Windows tenemos gran cantidad de DLLs, agrupando las APIs en funciones respecto a un
mismo tema. Además en cada nueva versión de Windows, posiblemente tengamos más DLLs para utilizar.
Para acceder a las funciones de las librerías dinámicas, lo primero que debemos hacer es declararlas.
________________________________________
Declaración de una Función DLL.
Para declarar una función de una librería dinámica, tiene que escribir una sentencia declare en el módulo global de la aplicación, o en la sección de declaraciones de la forma o del módulo correspondiente. Por ejemplo:
Declare Function lopen Lib "kernel" Alias "_lopen" (Byval lpPathname as string, Byval iReadWrite As Integer) as Integer
La cláusula Lib indica al lenguaje de programación la librería donde puede encontrar la función de la API
de Windows declarada. Las DLLs del entorno operativo están en "Kernel", "GDI", "User", o en una de las
DLLs correspondientes a un driver de dispositivo tal como "Sound". Para otras DLLs, el nombre incluye el
camino completo. Por ejemplo: "c:\windows\system\lzexpand.dll"
La cláusula alias indica que la función tiene otro nombre en la librería dinámica ( DLL ). Esto es útil
cuando el nombre de la función coincide con alguna palabra clave, con alguna variable o constante global, o
el nombre de la función DLL, tiene caracteres no reconocidos por el lenguaje de programación.
La sentencia declare debe contener asimismo una lista de los parámetros que se pasarán a la función.
La mayor parte del trabajo consiste en determinar cuáles serán esos parámetros. Algo muy utilizado dentro
de los parámetros son lo que podemos traducir como manejadores ( handles ). Esto es un valor entero único definido por el entorno operativo y utilizado para referirse a objetos tales como formularios, controles, etc. Un handle es un número de identificación. HWnd es un handle para referirse a una ventana, hDC es un handle para referirse al contexto de dispositivo de un objeto ( Device Context ). Cuando una función de una DLL espera
recibir como argumento un handle, se debe declarar como ByVal Integer.
Declare Function IsIconic Lib "User" (ByVal hWnd As Integer) As Integer
If IsIconic (Form1.hWnd) Then ....
El entorno operativo asigna un handle a cada formulario de una aplicación para posteriormente identificarles.
La propiedad hWnd de un formulario o de un control no gráfico permite acceder a este handle.
Por contexto de dispositivo se entiende un conjunto de atributos (color de fondo, tipo de letra, espaciado
entre caracteres, posición actual de la pluma, paleta de colores, etc.) que determinan la localización y la
apariencia de un objeto. Una aplicación puede modificar estas propiedades a través del hDC del objeto.
Afortunadamente, Microsoft ha pensado en el programador y proporciona una herramienta dentro de
algunos lenguajes de programación de entorno visual como es el API viewer, en Visual Basic versión 4.0.
Con ésta herramienta podemos cargar unos archivos TXT que nos proporcionan las sentencias declare de
gran cantidad de funciones API. Si no poseemos ningún tipo de ayuda respecto a una API específica, es muy posible
que todos nuestros intentos en utilizarla sean inútiles.
Para declarar una función de una librería dinámica, se tiene que escribir en la sección de declaraciones de
un formulario o de un módulo de la aplicación en construcción.
Una función declarada en un formulario es privada para este formulario, y declarada en un módulo es
pública, y por lo tanto puede ser llamada desde cualquier parte de la aplicación.
Si la función no retorna un valor, se declarará como un procedimiento o sub, aunque esta opción no se
utiliza casi nunca, pues la mayoría de las APIs retornan un valor, aunque sea una verificación de su realización.
Los argumentos que se pasan a una función pueden ser pasados por valor o por referencia. UN parámetro
por valor quiere decir que lo que estamos metiendo dentro de la función es el contenido de la variable, mientras
que por referencia se introduce la dirección de memoria donde reside la variable que contiene el valor que queremos
pasar.
Habitualmente, dentro de nuestro programa trabajamos con variables que se pasan por valor, es decir, no
nos interesa la posición de memoria de la variable, sino su contenido. Al trabajar con APIs la cosa cambia. La mayoría
de estas funciones están desarrolladas en C, y en este lenguaje se utiliza asiduamente los punteros (direcciones de memoria )
Por defecto, los lenguajes actuales de entorno visual pasa los argumentos por referencia ( utilizando direcciones de
32 bits ).
Para pasar un argumento por valor, se debe de escribir la palabra clave ByVal delante de la declaración del argumento.
Algunas funciones aceptan más de un tipo de datos para un mismo argumento, y esto se indica declarando
el argumento como Any.

Declare Function Catch Lib "Kernel" (lpCatchBuf As Any) As Integer
Esta función puede ser llamada con un argumento tipo cadena, de tipo largo, etc.
________________________________________
Algunas Funciones de la API.
Algunas de las funciones del API, se pueden agrupar en:
- Funciones de direccionamiento de memoria a 32 bits.
Recupera el API para aplicaciones que utilizan 32 bits.
- Funciones de ejecución de aplicaciones.
Tiene la función de cargar y ejecutar aplicaciones.
ej: Winhelp
Loadmodule
- Funciones bitmap.
Crea y maneja los bitmaps.
Createbitmap, crea un bitmap.
Getpixel, recupera el color RGB del pixel especificado.
- Funciones callback o rellamada.
Recupera información sobre algo que se está ejecutando, con la posibilidad de hacer algún cambio.
Abortproc, procesa los trabajos de impresora cancelados.
EnumFontFamProc, recupera información sobre las fuentes (tipo de letra) disponibles.
- Funciones de cuadro de diálogo común.
Funciones que actúan sobre una caja de diálogo común, cambiando su color, texto, etc.
Choosecolor, crea una caja de diálogo seleccionando el color.
- Funciones de comunicación.
Funciones que gestionan los dispositivos de comunicaciones.
Opencomm, abre un dispositivo de comunicaciones.
- Funciones de cursor.
Gestionan todo lo relacionado con el cursor.
Createcursor, crea un cursor con dimensiones especificadas.
- Funciones DDE (Data Dinamic Exchange ).
Gestiona el intercambio de datos dinámico.
DdeAccessData, proporciona un acceso a un objeto con memoria global.
DdeGetdata, copia los datos de un objeto de memoria global a un buffer.
- Funciones de error.
Funciones que gestionan los errores de los dispositivos.
Debugoutput, envía mensajes al terminal erróneo.
- Funciones de movimiento y visualización.
Isiconic, determina si una ventana está minimizada.
- Funciones para las propiedades.
Informa y modifica el estado de las propiedades.
Getprop, devuelve una lista de propiedades de una ventana.
- Funciones pen.
Son las funciones correspondientes al lápiz.
- Funciones de paleta de colores.
- Funciones de dibujo y pintura.
- Grupo de funciones OLE.
Funciones que se basan en el manejo de objetos.
Olenumobjects, enumera los objetos en un documento.
- Funciones Toolhelp.
Normalmente devuelven información sobre los objetos que hay en memoria.
- Funciones Drag & Drop
Funciones de arratrar y soltar.
Tiene información sobre la posición de arrastre de algún elemento, si se puede arrastrar, etc.
- Funciones de controladores instalables.
Hacen una gestión de los controladores instalables.
- Funciones de decodificación LEMPEL-ZIV.
Hacen una gestión de los ficheros comprimidos.
- Funciones para la impresión.
Devuelve tamaños de letra, página, etc. y activa o desactiva algunas funciones, configura colores, etc.
a la hora de imprimir.
- Funciones SHELL (entorno).
Son las funciones que controlan el entorno.
FindExecutable: recupera el nombre del ejecutable asociado a un fichero especificado.
- Funciones "Stress"
Controla espacio libre y manejadores de ficheros (handles).
AllocDiskSpace: crea un fichero del espacio consumido en una partición del disco (instalar software).
- Funciones TrueType
Funciones que controlan los fuentes o tipos de letra a utilizar.
GetRasterizarCaps: recupera el estado del tipo de letra en un sistema. Cuando se hace un cambio de
tipo de letra , reestablece el que hay por defecto.
- Funciones de versión.
Función que controla la versión de los ficheros.
GetfileVersionInfo: devuelve información sobre un fichero especificado.
- Funciones GDI.
Controla todo lo que se refiere a los gráficos, ya sea tipos de letra, manejo de trabajo a la hora de una
impresión, prepara la impresora para aceptar datos, etc.
StartPage: Prepara un controlador de impresora para aceptar datos.
StarDoc: Inicializará un trabajo de impresión.
GetRasterizerCaps: recupera el estado del tipo de letra de un sistema.
- Funciones KERNEL.
Lleva a cabo una E/S a ficheros, control de errores,etc.
hread: Lee datos de un fichero.
hwrite: escribe datos en un fichero.
Debugoutput: envía mensajes a un terminal erróneo.
- Funciones de usuario.
Son funciones en las que el usuario realiza alguna acción, como activar o desactivar flechas de scroll-
bar (texto horizontal-vetical), recupera información de mensajes de hardware, etc.
GetDriverInfo: recupera datos de un dispositivo instalable.
CopyIcon: copia un icono.
OpenDriver: abre un dispositivo instalable.
________________________________________
Una de las primeras funciones que vamos a comentar es bastante utilizada.
En muchas ocasiones hemos querido saber qué resolución tiene la pantalla de la pc en el momento que se ejecuta nuestro software. Con ésta información podemos dar un aspecto bastante más profesional a nuestra aplicación si ajustamos el tamaño de nuestros formularios a la resolución de la pantalla. También a través de
la misma API sabemos la cantidad de puntos que nos da la impresora, con lo que podemos ajustar nuestros informes independientemente de la impresora seleccionada. Esta función la tenemos dentro de la librería GDI,
y se denomina GetDeviceCaps. Dependiendo del valor del índice introducido, así nos da la información sobre la cantidad de puntos horizontales de la pantalla, cantidad de puntos verticales de la pantalla, puntos por pulgada horizontalmente en la impresora y puntos por pulgada verticalmente en la impresora.
Declare Function GetDeviceCaps Lib "GDI" ( ByVal HDC As Integer, Byval nIndex As Integer) As Integer
Global Const HorRes = 8 ' resolución horizontal en pixels
Global Const VerRes = 10 ' resolución vertical en pixels
Global Const PPPX = 88 ' pixels por pulgada en X
Global Const PPPY = 90 ' pixels por pulgada en Y
Private Sub Command1_click()
p1 = GetDeviceCaps ( HDC, HorRes )
p2 = GetDeviceCaps ( HDC, VerRes )
i1 = GetDeviceCaps ( Printer, HDC, PPPX )
i2 = GetDeviceCaps ( Printer, HDC, PPPY )
Label1.Caption = "Pantalla: " & p1 & " x" & p2
Label2.Caption = "Impresora: " & i1 & " x " & i2
End Sub
________________________________________
En muchas ocasiones necesitamos conocer dónde esta el directorio de Windows y dónde reside el
directorio System del mismo. Es muy lógico suponer que todas las instalaciones están en el directorio C:\Windows.
Puede ser que se ejecute desde una red, o que el usuario haya cambiado el directorio por omisión. En cualquiera de estos casos no podemos referirnos directamente a estos directorios, sino que debemos conocerlos dinámicamente cuando ejecutamos la aplicación.
Para ello utilizamos dos APIs de la librería Kernel, la primera nos devuelve el directorio de Windows
(GetWindowsDirectory ), mientras que la segunda el directorio de System ( GetSystemDirectory ).
Para hacer funcionar esta API debemos inicializar la variable que nos devuelve la información, con 255 caracteres rellenos con el valor ASCII 0. Si la cadena estuviese vacía, no funcionaría, y su comportamiento sería impredecible.
Declare Function GetWindowsDirectory Lib "Kernel " (ByVal lpBuffer As String, ByVal nSize As Integer
Declare Function GetSystemDirectory Lib "Kernel" (ByVal lpBuffer As String, ByVal nSize As Integer
Private Sub Command2_Click ()
Dim Camino As String
Camino = String( 255, 0 )
w = GetWindowsDirectory ( Camino, Len(camino))
Label3.Caption = Camino
w = GetSystemDirectory ( Camino, Len(Camino))
Label4.Caption = Camino
End Sub
________________________________________
Por último queria comentar una utilidad realizada con llamadas a APIs. Consiste en el efecto de poder rotar
un texto, algo que dentro de algunos lenguajes no se puede hacer, como es en el entorno Visual Basic, a no ser
que sea por medio de una imagen. Esto no se realiza con una simple llamada, sino que es necesaria una estructura de programación más compleja.
En primer lugar debemos definir dos estructuras. La primera nos va a permitir introducir una posición del texto, y la segunda es una definición completa de una fuente por el usuario.
Type RECT
LEFT As Integer
TOP As Integer
RIGHT As Integer
BOTTOM As Integer
End Type
Global Const F_TAMNOMBRE = 32
Type FUENTE
FANCHO As Integer
FLARGO As Integer
FESCAPE As Integer
FORIENTACION As Integer
FWEIGHT As Integer
FITALICA As String * 1
FUNDERLINE As String * 1
FSTRIKEOUT As String * 1
FCHARSET As String * 1
FOUTPRECISION As String * 1
FCLIPRECISION As String * 1
FQUALITY As String * 1
FPITCHANDFAMILY As String * 1
FNOMBRE As String * F_TAMNOMBRE
End Type
Global Const TRANSPARENTE = 1
Global Const OPACO = 2
Como se ha comentado antes, se utilizan varias APIs para realizar este efecto. Todo ellas son de la
librería GDI, excepto una de USER.

Declare Sub GETCLIENTRECT Lib "USER" (ByVal HWND As INTEGER, LPRECT As RECT)
Declare Function SETBKMODE Lib "GDI" (ByVal HDC As Integer, ByVal NBKMODE As Integer) As Integer
Declare Function CREATEFONTINDIRECT Lib "GDI" (LPLOGFONT As FUENTE) As Integer
Declare Function SELECTOBJECT Lib "GDI" (ByVal HDC As Integer, ByVal HOBJECT As Integer
Declare Function TEXTOUT Lib "GDI" (ByVal X As Integer, ByVal Y As Integer, ByVal LPSTRING As String ByVal NCOUNT As Integer) As Integer
Declare Function DELETEOBJECT Lib "GDI"

El mecanismo utilizado para visualizar un texto inclinado consiste en crear una fuente ya inclinada y
visualizar el texto con esa fuente y el fondo transparente para no ocultar otros elementos de la pantalla. En el ejemplo que sigue se puede ver que se va realizando el giro a través de una barra de desplazamiento.
Private Sub HScroll_Change ( )
Dim POS As RECT
Dim LF As FUENTE
Dim I As Integer, ANGULO As Integer
Dim HFONT As Integer, HOLDFONT As Integer
Dim TEXTO As String
' INICIALIZA EL TEXTO A VISUALIZAR
TEXTO = " TEXTO A ROTAR "
' ESPECIFICA LA FUENTE A USAR
LF.NOMBRE = "Arial"
LF.FWEIGHT = 1000
' USA FONDO TRANSPARENTE
I = SETBKMODE (HDC, TRANSPARENTE )
' CENTRA EL TEXTO EN LA VENTANA
Call GETCLIENTRECT ( HWND, POS )
Cls
ANGULO = HScroll.Value
LF.FESCAPE = ANGULO
HFONT = CREATEFONTINDIRECT ( LF )
HOLDFONT = SELECTOBJECT ( HDC, HFONT )
I = TEXTOUT ( HDC, POS.RIGHT / 2, POS.BOTTOM / 2, TEXTO. Len ( TEXTO ))
I = SELECTOBJECT ( HDC, HOLDFONT )
I =DELETEOBJECT ( HFONT )
' RESTAURA EL FONDO POR DEFECTO
I = SETBKMODE ( HDC, OPACO )
End Sub
Como podemos comprobar, no siempre se puede realizar las operaciones que deseamos con una sola API.
En la mayoría de los casos es necesario utilizar varias, que se complementan para obtener los resultados deseados.
________________________________________
Algunas Funciones Interesantes y una breve descripcion dde cada una:
GetUserName (Devuelve en nombre del usuario)
GetComputerName (Devuelve en nombre del computador)
GetDiskFreeSpace (Devuelve información sobre el disco duro)
GetDiskFreeSpaceEx (Devuelve la capacidad de un disco mayor de 2Mb.)
GetVolumeInformation (Nombre del Disco, tipo de formato y numero de disco)
GetLogicalDriveStrings (Devuelve las unidades disponibles en un ordenador)
GetLocalTime (Devuelve la fecha y hora del ordenador)
GetCursorPos (Devuelve la posición del cursor en la pantalla)
GetDriveType (Devuelve el tipo de Unidad)
SetWindowPos (Formulario Siempre Visible)
GlobalMemoryStatus (Información sobre la memoria fisica disponible)
ShellExecute (Ejecutar)
GetVersionEx (Devuelve la versión del Windows)
SystemParametersInfo (Cambia el fondo de pantalla del Windows)
SHFileOperation (Enviar un archivo a la papelera de reciclaje)
GetWindowsDirectory (Mustra la ruta del Windows)
GetSystemDirectory (Mustra la ruta del directorio System de Windows)
sndPlaySound (Ejecutar sonidos .WAV)
FindExecutable (Busca el archivo ejecutable asociado a un archivo, y muestra el icono)
GetKeyboardStateByString - SetKeyboardStateByString (Seleccionar y Deseleccionar el Bloque Numerico del teclado)
FindWindow (Indica si una aplicación determinada esta en ejecución)
SystemParametersInfo (Activa/Desactiva las teclas de Escape - CTRL+ALT+SUB - ALT+TAB - CRTL+ESC)
GetSysColor (Devuelve los colores del Windows)
GetACP (Determina la página de código ANSI vigente)
SetWindowPos (Esconder y mostrar la barra de tareas del Windows)
ExitWindowsEx (Apaga o Reinicia el Windows 95/98)
GetSystemInfo (Información sobre el Hardware)
SystemParametersInfo (Devuelve y establece parámetros del sistema de Windows)
________________________________________

0 comentarios. Puedes dejar el tuyo:

Tú opinión es importante. Exprésate!