USAR CURSORES CON VISUAL BASIC

 

Fecha: 18/Sep/97
Autor: Jordi Garcia Busquets



- Como utilizar un cursor diferente al predeterminado en VB3

Para poder usar en un programa hecho en VB3 un cursor que no sea el de por defecto hay
que usar la funcion de la API "LoadCursor", la cual carga el cursor a partir de un modulo que
esté en memoria. Con módulo nos referimos tanto a un ejecutable como una DLL, ambos conteniendo
recursos como cursores o iconos, que puedan ser capturados a partir de las funciones de la API.
En el siguiente ejemplo os muestro el metodo que yo seguí para crearme una DLL
conteniendo un cursor, y luego poder usar el cursor dentro de mi programa.
Empezemos primero con los pasos para crear la libreria:

1-Me creé un fichero de recursos con el Resource Workshop que viene con el Turbo Pascal
1.5 for Windows. Con el editor de cursores he dibujado el cursor y definido el punto caliente.
2-Al cursor le he dado un nombre interno (en mi caso "HOLA") y he salvado el fichero
de recursos (en mi caso "CURSOR.RES")
3-Me creo un fichero CURSOR.PAS con el contenido siguiente:

library CURSOR;

{$R CURSOR.RES}

begin
end.

4-Lo compilo, sea con Turbo Pascal for W, Borland Pascal o Delphi.
Resultado: CURSOR.DLL.

-------------

Una vez hecho todo esto y para sacar el cursor en nuestro programa deberemos realizar
varias tareas:

1-Al cargar el programa, cargar la libreria en memoria. (LoadLibrary)
2-Cargar el cursor que contiene la libreria. (LoadCursor)
3-Obtener el cursor por defecto del Windows (GetClassWord)
4-Cambiar el cursor por el nuestro (SetclassWord)
5-Al acabar el programa, descargar la libreria de la memoria (FreeLibrary)
y descargar el cursor de la memoria. (DestroyCursor)


Pongamos a probar todo esto. Cread un proyecto nuevo. Cread un modulo y poned las
siguientes declaraciones:

'---Declaraciones

Declare Function DestroyCursor Lib "User" (ByVal hCursor As Integer) As Integer
Declare Function LoadLibrary Lib "kernel" (ByVal LibName as string) as integer
Declare Function LoadCursor Lib "User" (ByVal hInstance As Integer, ByVal lpCursorName As Any) As Integer
Declare Function SetClassWord Lib "User" (ByVal hWnd As Integer, ByVal nIndex As Integer, ByVal wNewWord As Integer) As Integer
Declare Function GetClassWord Lib "User" (ByVal hWnd As Integer, ByVal nIndex As Integer) As Integer
Declare Sub FreeLibrary Lib "Kernel" (ByVal hLIbMod As Integer)
Global Const GCW_HCURSOR = (-12)

Global DLLInstance As Long
Global CursorPorDefecto
Global MiCursor

'---Fin de declaraciones

En el form_load del formulario en blanco creado por defecto, poned el siguiente codigo:

Sub Form_Load ()
Dim lastcursor as integer

'Cargamos la DLL en memoria y obtenemos un handle
'Supongamos que la tenemos a c:\windows\temp
DLLInstance = LoadLibrary("c:\windows\temp\cursor.dll")

'Cargamos el cursor de la libreria y obtenemos un handle
MiCursor = LoadCursor(DLLInstance, "HOLA")

'Obtenemos el handle del cursor por defecto del Windows
CursorPorDefecto = GetClassWord(me.hWnd, GCW_HCURSOR)

'Cambiamos el cursor por el nuestro
lastcursor = SetClassWord(me.hWnd, GCW_HCURSOR, MiCursor)

End Sub

Cuando el formulario se descarga, eliminamos la libreria de la memoria.


Sub Form_QueryUnload (Cancel As Integer, UnloadMode As Integer)
Dim lastcursor As Integer
Dim ret as integer

'Restauramos el cursor al cursor por defecto del Windows
lastcursor = SetClassWord(Me.hWnd, GCW_HCURSOR, CursorPorDefecto)

'Descargamos el cursor y liberamos todos los recursos que ocupaba
ret = DestroyCursor(MiCursor)

'Descargamos la libreria de la memoria
FreeLibrary (DLLInstance)

End Sub


- Como utilizar un cursor diferente al predeterminado en VB4-16 bits

En VB4 está claro que todo este tinglado de crear una libreria, cargarla, etc no es
necesario, ya que esta opcion está implementada en el entorno del Visual Basic. Por ejemplo,
para hacer que en un botón de una pantalla aparezca un cursor diferente personalizado lo
único que tenemos que hacer es crear previamente el cursor y guardar-lo en un fichero de
cursor (.cur), ir a la propiedad mouseicon del botón, asignar-le el cursor, y finalmente
poner la propiedad mousepointer a 99-Custom. Y todo resuelto.
Está claro que, si en algun momento, nos interesa cargar un cursor de una libreria
que ya esté en memoria lo podremos seguir haciendo como en el ejemplo anterior, pues las
declaraciones de las funciones y su funcionamiento no varían.


- Como utilizar un cursor diferente al predeterminado en VB4-32 bits y VB5.

En VB4-32 bits y VB5, además de disponer de todas las opciones anteriores, se nos ofrece
una nueva: la posibilidad de cargar mediante las API un cursor directamente de un fichero.
La función API que hace esto es la "LoadCursorFromFile".
Su declaración es:

'----Declaración
Declare LoadCursorFromFile& Lib "user32" Alias "LoadCursorFromFileA" (Byval lpFileName as String)


Un ejemplo similar al primero hecho con VB3, usando ahora esta función:


Sub Form_Load ()
Dim lastcursor as long

'Cargamos el cursor del fichero y obtenemos un handle
MiCursor = LoadCursorFromFile("C:\windows\temp\resource.cur")

'Obtenemos el handle del cursor por defecto del Windows
CursorPorDefecto = GetClassWord(me.hWnd, GCW_HCURSOR)

'Cambiamos el cursor por el nuestro
lastcursor = SetClassWord(me.hWnd, GCW_HCURSOR, MiCursor)

End Sub


- Nota para todas las versiones

Fijaos en que el segundo parametro en la declaración de la función "LoadCursor" es de
tipo "Any", pero nosotros le pasamos una cadena con el nombre de la libreria. Esto es así
porque esta función puede usarse para mostrar también los cursores por defecto del Windows
(la flecha, la flecha vertical, el I-Beam, etc). Para hacer esto debemos establecer el primer
parametro a 0 y el segundo será un valor integer o long, dependiendo de si trabajamos en 16 o
32 bits, que identifique al cursor que queremos mostrar.
He aquí las declaraciones de los cursores típicos del Windows:

Public Const IDC_ARROW = 32512&
Public Const IDC_IBEAM = 32513&
Public Const IDC_WAIT = 32514&
Public Const IDC_CROSS = 32515&
Public Const IDC_UPARROW = 32516&
Public Const IDC_SIZE = 32640&
Public Const IDC_ICON = 32641&
Public Const IDC_SIZENWSE = 32642&
Public Const IDC_SIZENESW = 32643&
Public Const IDC_SIZEWE = 32644&
Public Const IDC_SIZENS = 32645&

Por ejemplo, para hacer aparecer el I-Beam, escribid:

MiCursor = LoadCursor(0,IDC_IBEAM)

Lo unico que hay que tener en cuenta aquí es no usar la API "DestroyCursor" cuando
cargemos este tipo de cursores.


- Consejos

Cuando se trata de trabajar con este tipo de funciones que cargan librerias en memoria,
de vez en cuando haciendo pruebas el programa se aborta, por la razón que sea, y el resultado
es que la libreria queda cargada en memoria. Para poder descargarla yo uso un programa muy
útil que se encuentra escondido en el directorio c:\vb\cdk del Visual Basic 3.0, y que se llama
wps.exe. Con el podréis ver los ejecutables y las librerías que estan en memoria, y
descargarlas a vuestro antojo.
Los que no tengais VB3.0 no os apureis, que tambien lo podreis encontrar en Internet.
Simplemente id a Altavista, escribid "WPS.EXE", y listos.


- Demostración

Podreis encontrar un ejemplo de uso de un cursor en VB3 en el programa que os adjunto.
Es una implementación de un tablero de ajedrez, donde se validan a medida que avanzan los
movimientos las jugadas validas de una partida de ajedrez. Por ahora, que yo sepa, solo tiene
estos detalles por solucionar:

+ Al invertir el tablero, el programa no deja mover los peones.
+ El enroque corto, largo, jaque, jaque mate y matar el peón al paso no estan
contemplados.

Espero que os guste y os sea util, si es que teníais pensado hacer algun programa
de demostracion de ajedrez.


******************************************
Jordi Garcia Busquets
Estudiante de 3º de informatica
Universidad de Girona. Catalunya. Espanya.
jordi@hades.udg.es
******************************************


ir al índice

 Para bajar los listados, pulsa en el link (cursorJG.zip 18.7 KB)