Ver Mensaje Individual
  #10 (permalink)  
Antiguo 17/11/2004, 01:27
Avatar de Beakdan
Beakdan
 
Fecha de Ingreso: diciembre-2001
Ubicación: Monterrey, Nuevo León
Mensajes: 433
Antigüedad: 22 años, 4 meses
Puntos: 7
Antes de pasar al código, una pequeña nota sobre subclassing.
Subclassing en el contexto de los mensajes de windows (no en el contexto de OOP), no es otra cosa sino crear un procedimiento que habrá de procesar los mensajes que el sistema operativo envía a la ventana, y "colgar" este procedimiento en la cola de mensajes. Normalmente, el procedimiento creado procesará sólo algunos mensajes (antes o después del procedimiento normal) y dejará los demás para que los procese el procedimiento normal.
El sistema operativo, para cada ventana busca un procedimiento al cual pasarle notificaciones de lo que ocurre con la ventana. En VB, esto queda perfectamente oculto, dejándonos con los eventos.
Por ejemplo, al hacer click en un botón o en el formulario, el sistema operativo debe informar al procedimiento del formulario que hubo un click.

¿Como lo Hace en C?
En lenguaje C, el procedimiento suele estar definido como:
LRESULT CALLBACK WndProc( HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam )
Para detectar el click en el Boton, vemos si messg es igual a WM_COMMAND, si es así, verificamos si el Word bajo de wParam corresponde a algún identificador de botón que hayamos definido, para luego decidir que hacer.
Para detectar el click en la ventana, windows no enviará WM_COMMAND, sino WM_LBUTTONDOWN ó WM_RBUTTONDOWN ó WM_MBUTTONDOWN seguido de WM_LBUTTONUP ó WM_RBUTTONUP ó WM_MBUTTONUP (según el caso, y pueden haber otros mensajes entre estos.) Entonces, se tiene que verificar que el mensaje de sistema que avisa que el botón de mouse ha sido liberado, ocurra sobre la ventana, para validar el click. Aunque esto suene un poco complicado, no lo es realmente.

¿Como lo Hace en VB?
En VB todo este proceso queda oculto. Los mensajes son agrupados en grupos que el usuario identifica (click en este caso) independientemente de que para el SO sean notificaciones distintas, y se entrega un evento acorde. Y los mensajes que los desarrolladores consideraron que no llegaríamos a usar, simplemente no están.

¿Qué tiene que ver esto con el tema?
Todo. Es precisamente por esta simplificación por la que muchos programadores abandonaron VB. Llega un punto en el que se tienen que hacer muchos malabares para obtener una funcionalidad que en otros lenguajes se da por hecha. Sin embargo, es esta misma simplificación la que lo hace un lenguaje popular. La simplificación nos limita mucho, porque si una funcionalidad no está ya en el control que se usa, lo primero que te recomendarán es "cámbiate de lenguaje" o "consigue otro control".

Aunque VB oculte los mensajes del SO, podemos poner nuestro propio procedimiento, y manipular del mismo modo que en C los mensajes (subclassing). El problema con subclassing, es que casi todas las librerías que encontrarás resultarán inestables. He programado en VB desde la versión 4, y para hacer subclassing he intentado de todo: DLL's OCX's, archivos de clase que sólo funcionan en el programa compilado, etc. En la versión 5, hacer subclassing se volvió algo más simple, pero siempre inestable. Presionar el botón STOP en el Ide, era un error de sistema asegurado... En VB6, intenté hacer mi propio método, pero no era mejor que los que había usado. La librería más estable que encontré fue la de www.vbaccelerator.com , pero hace algunos meses, encontré un código de Paul Caton que eliminaba todos los problemas, usando ensamblador en VB, para crear el procedimiento de ventana. Desde entonces, uso esas rutinas, y uso ensamblador embebido para mejorar el desempeño de mis rutinas VB (antes reemplazaba al compilar el código objeto generado por VB con uno propio), pero eso es otra historia.

El código que te presento, permite mover los scrollBars del grid, pero la estructura del programa, por el modo en que maneja los mensajes, tiene más tintes de C que de VB. Te recomiendo que veas en el SDK las definiciones de las funciones y las constantes usadas, para que te resulte más claro. Nada te impide que crees un clase a manera de envoltorio en la cual definirías los eventos que pudieras llegar a usar.

Como nota final, reitero que el código en los módulos de clase, no es mío, sino de Paul Caton, buscando en la red seguramente encontrarás más referencias sobre su técnica de meter ensamblador en VB6 ("Assembler Code Tunk" si bien recuerdo).

http://www.ag-info.com/MsGrid_SC.zip

Y a pesar de todos los posibles inconvenientes que el lenguaje Basic puede llegar a presentar para muchos, yo me sigo quedando con el, no porque no sepa usar otros, o porque vaya a hacer más rápido mi aplicación, sino porque me gusta...