Nota:
Las añadidas en la última actualización están en negrita y
marcadas con un asterisco rojo (*)
Las que tienen solo el asterisco, pero no están en negrita,
(o están en negrita pero sin el asterisco) es que he
actualizado el contenido.
Algunos links apuntan a páginas en las que están las declaraciones y es
posible que solo estén
las declaraciones de Visual Basic .NET y las de C#.
Nota del 30/Nov/07:
En esta página solo están los links (enlaces) a las páginas con la definición de
las funciones tanto para C (el original) como para Visual Basic 6.0 (o
anterior), Visual Basic .NET (cualquier versión) y Visual C#.
Nota:
Las funciones que no tienen un link es porque aún están en la página original y
todavía no he actualizado el contenido. Si quieres ver el resto de declaraciones
de las funciones del API, puedes hacerlo desde:
Equivalencias con el API de Windows.
En esta página encontrarás las declaraciones
tanto para VB .NET como para C# de algunas de las funciones del API de
Windows,
además de las constantes y
tipos de datos usados habitualmente por el API de Windows.
Si viene al caso, también te pondré un link al artículo en el que se utiliza
dicha API, para que tengas un ejemplo práctico y "realista" de cómo
usarla, ya
que aquí simplemente te mostraré la forma de declarar la función,
constante o
tipo de datos, sin ningún ejemplo de cómo usarla.
En el caso de que no exista un artículo publicado que la utilice, procuraré
añadir un link a una página con un ejemplo "práctico" para usar la
función del
API y, si es posible o viene al caso, también te indicaré la clase de
.NET que
podemos usar para realizar la misma tarea.
En cada función del API de Windows he incluido
la definición de la misma que aparece en la documentación del SDK de
Windows,
así como las declaraciones para VB6, VB .NET y C#.
Estas son las declaraciones de funciones del API
de Windows equivalentes para Visual Basic .NET y C# (y la misma
declaración para Visual Basic 6.0
-clásico-).
Nota:
En las declaraciones aquí mostradas, salvo descuido, he usado la forma
"recomendada" de .NET, es decir: aplicando el atributo
DllImport, (definido en
System.Runtime.InteropServices) en caso de
que usemos la forma "clásica" de VB6, el
compilador de VB creará una declaración "parecida" a la de
DllImport, pero usando los valores predeterminados.
A continuación te muestro la forma de usar el atributo DllImport y los
campos que puedes indicar. En su versión simple, funciona de la
siguiente forma (según los parámetros usados):
DllImport(String) Se indica el nombre de la Librería de Windows que contiene la función, esta es
la forma "recomendable" de usar este atributo si queremos usar lo
valores predeterminados del resto de campos.
DllImport(String, EntryPoint := String)
Se indica el nombre de la librería en el primer parámetro, en el segundo se indicará el nombre de la función tal y
como está definida en el fichero de cabecera (.H) correspondiente.
Habitualmente existen dos
nombres de para cada función del API, una acabada con W y otra
acabada con A, según se utilice un sistema operativo Unicode
(Windows NT/2000/XP/2003/CE) o no (Win95/98/ME). Ver más abajo
la descripción de CharSet, EntryPoint y ExactSpelling.
Los otros parámetros de este atributo, que podemos indicar (usando la forma: nombre_campo := valor
en VB o nombre_campo = valor en C#) son:
- CharSet:
El tipo de juego de caracteres a usar.
Puede ser:
--Auto, se elegirá el juego de caracteres adecuado según
el sistema operativo.
--Ansi para sistemas Windows 98 / ME o
--Unicode para sistemas Windows NT / 2000/ XP / 2003 / CE
El valor predeterminado es Auto, por tanto si no se indica ningún valor especial en EntryPoint, se elegirá la función que
mejor se adecue al sistema operativo.
- EntryPoint:
El valor del campo EntryPoint indica el nombre "exacto" de la
función del API que queremos usar.
Si el nombre de la función del API tiene el mismo nombre que el
usado en la declaración, no es necesario indicar este valor.
Como he indicado antes, ese nombre puede acabar con A o W,
según el tipo de función a usar: ANSI o UNICODE
respectivamente.
Si no indicamos en EntryPoint el nombre de la función, se usará
la que "coincida" con el nombre de la función indicada en la
declaración y según el valor asignado al campo CharSet (o
ExactSpelling) se añadirá la letra A o W (si es que existen dos
versiones diferentes).
Si no se indica ningún valor específico en CharSet, (el valor
realmente será Auto), se usará la versión ANSI (acabada en A) o
UNICODE (acabada en W) según el sistema operativo en el que se
esté ejecutando la aplicación.
- ExactSpelling:
Indica si el nombre de la función se ha escrito de la misma
forma que en la librería del API. Esto es para cuando no se usa
EntryPoint, ya que en caso de que el valor de este campo sea
False, se añadirá una A al nombre de la función si CharSet es
Ansi y una W si el valor de Charset es Unicode.
El valor predeterminado para C# es false.
El valor predeterminado para VB dependerá del valor de CharSet,
para Ansi y Unicode es True, para Auto es False.
- SetLastError:
Ver la documentación en línea para más información.
El valor predeterminado para VB y C# es False.
Si en VB utilizamos Declare en lugar de DllImport para declarar
la función, el valor de SetLastError es True.
- PreserveSig:
Ver la documentación en línea para más información.
El valor predeterminado es True.
- CallingConvention:
Ver la documentación en línea para más información.
El valor predeterminado es WinAPI que se convertirá en una
llamada StdCall para plataformas Windows o en Cdecl para CE.
- BestFitMapping:
Ver la documentación en línea para más información.
El valor predeterminado es True.
|
Si quieres ver las declaraciones para .NET de muchas de las funciones del API
de Windows, no debes dejar de visitar este sitio:
PINVOKE.NET.
Equivalencias en los tipos de datos
Los tipos de datos equivalentes entre el API
de Windows y los tipos de .NET, los podríamos resumir según la siguiente
tabla, en la que se muestran también los de VB6.
Nota:
Debido a que prácticamente todos los tipos del API, salvo
excepciones, se corresponden con un entero de .NET (Int32), para
que la tabla no sea demasiado monótona, de los tipos de .NET sólo
mostraré los tipos definidos en el CTS (Common Type
System), sistema de tipos comunes de .NET, es decir los tipos
de datos del propio .NET Framework, ya que no creo que te resulte
difícil saber a que tipo de VB o C# equivale.
Como podrás comprobar, básicamente
con saber que el tipo Int32 (Integer en VB, int en C#) de .NET
equivale a un LONG del API de Windows, tendríamos más que
suficiente, ya que ese es el tipo de datos (incluso camuflado) es
el que se suele usar en las librerías del API que están escritas en
C "normal".
También
comprobarás que .NET dispone de "tipos" para lo que en el API de
Windows se soluciona con "apaños de andar por casa", tal es el caso
de los punteros de C, que en .NET se solucionan mediante delegados.
Algunos tipos, como el UINT se podrían
cambiar por el "específico", pero también funcionará si se cambia por un
Int32. El caso de HWND que es el "handle" de una ventana, se puede
cambiar
indistintamente por un Int32 o preferiblemente por System.IntPtr.
Tipo del API |
Descripción |
.NET |
VB6 |
HWND |
Handle de la ventana de destino |
Int32
System.IntPtr (4) |
Long |
UINT |
|
Int32 |
Long |
WPARAM |
Cuando se usa en Send/PeekMessage, el primer mensaje a enviar a la ventana |
Int32 |
Long |
LPARAM |
El segundo mensaje a enviar a la ventana |
Int32 |
Long |
DWORD |
|
Int32 |
Long |
BOOL |
|
Boolean |
Long/Boolean |
HRESULT |
|
Int32 |
Long |
LPCTSTR |
Dirección de una cadena (no modificable) |
String o StringBuilder (2) |
ByVal String |
LPTSTR |
Dirección de una cadena (modificable) |
String o StringBuilder (2) |
ByVal String |
|
|
|
|
LPMSG |
Puntero a una estructura del tipo MSG
(1) |
|
-- |
LPDEVMODE |
Puntero a una estructura del tipo DEVMODE (1) |
|
-- |
|
|
|
|
WNDENUMPROC |
Puntero a una función CallBack (3) |
Llamada a una función definida por un delegado |
Long (AddressOf) |
CALLBACK |
Definición de la función CallBack (3) |
Definición de un delegado |
-- |
|
|
|
|
- Los punteros a estructuras normalmente se definen usando la estructura como parámetro
por referencia (ByRef en VB, ref en C#)
- Cuando enviamos cadenas al API de Windows, es preferible indicar un tipo
StringBuilder ya que de esta forma evitamos la recreación de una nueva cadena,
que es lo que ocurriría si usamos un tipo de datos String.
- Las funciones CallBack son punteros a otras funciones, en .NET todo esto se maneja
usando delegados (en VB .NET en los punteros a funciones se usará AddressOf
para realizar la llamada al delegado).
- Es recomendable que para los manejadores de las ventanas utilices un
tipo IntPtr en lugar de un Int32, ya que la propiedad
Handle de los controles de Windows.Forms es del tipo
IntPtr, y esa propiedad precisamente se puede usar para casi todas
las funciones del API de Windows.