Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

¡Salta Por la Ventana! (Parte 1)

–Como Crear Una Ventana en Windows–

Continuamos nuestra jornada por el último código. Hasta donde recuerdo, lo último que vimos fue la estructura básica de los mensajes de Windows y como estos se mueven a traves del sistema del mismo modo en que lo hacen las botellas arrojadas al mar. La siguiente estructura es la que define la Clase Ventana. Al igual que las clases sociales o las razas de perros (valga la redundancia), una definición de clase es una especificación abstracta mas o menos general que sirve para construir ventanas. De una manera mas mundana, puede decirse que esta especificación son los planos para construir un automovil y que el automovil construido a partir de esos planos es la instancia generada. La estructura pertenece a la API de Windows y se llama WNDCLASSEX, que significa Window Class Ex. Pues existe otra estructura mas sencilla y antigua llamada WNDCLASS. Ahora veamos como trabaja esta estructura:

cbSize.- Es el tamaño en bytes de la propia estructura, en este caso es 30h que es 48 decimal.

Style.- Una constante que define el estilo de la ventana, en este caso es una combinación de CS_HREDRAW Y CS_VREDRAW, que da 3. Para mas información busquen en las constantes de windows.

*lpfnWndProc.- Este dato es truculento, pues es un entero de 32 bits que contiene la posición de memoria no de un dato o una estructura sino ¡De una función de código ejecutable! Mas adelante veremos como se asocia una función a un cierto tipo de ventana.

*cbClsExtra.- Un entero que cuenta la cantidad de bytes que mide la estructura WNDCLASSEX que sigue. Este dato es puesto en CERO por el sistema.

*cbWndExtra.- Indica los bytes necesarios para almacenar una INSTANCIA de ventana. Por ahora es cero, pero hay tipos de ventana que necesitan constantes especiales en esta sección.

*hInstance.- Indica la instancia de la aplicación a la que la ventana pertenece

*hIcon y hCursor.- Son los handles del cursor y del ícono de la ventana. Mas adelante se muestra como se obtienen estos valores.

*hBrBackground.- El handle de una brocha de fondo. Especifica el color y propiedades del fondo a partir de constantes de sistema o un objeto predefinido por nosotros mismos. En este caso se usa COLOR_WINDOW + 1 que es igual a 6

*lpszMenuName.- Posición de una cadena ascii-z que se usa para identificar los ‘recursos’ que la ventana va a necesitar. Los recursos son casi todo lo que aparece en la cara de una ventana.

*lpszClassName.-Posición de una cadena ascii-z que identifica a que ‘raza’ pertenece la ventana. Es como la marca de fuego usada para marcar al ganado. Es posible usar algo llamado ‘átomos’ que son valores especiales con significado especial que explicaré en detalle cuando me de la gana investigarlo

hIconSm.- Otro manejador de icono usado pero este es en miniatura.

Y esto es apenas para definir una ventana sencilla. Lo que sigue en el código es el relleno e inicialización de esta estructura. Solo para no confundir ahi van algunas aclaraciones:

*hInstance se copia de un lado a otro de la memoria con PUSH y POP respectivamente. Esta técnica aunque no es muy eficiente es util para cuando tenemos todos los registros ocupados.

*Como esta aplicación no usa menús porque ni siquiera tiene definida una sección de recursos, el elemento lpszMenuName vale cero.

*Los elementos hicon y hiconsm se inicializan con el valor devuelto por la función LoadIcon. Esta función recibe 2 argumentos: el handle de instancia de aplicación y una constante que define el tipo de ícono. Este valor tambien puede ser una entrada de la sección de recursos. En este caso el primero es cero porque es de la misma aplicación llamadora, el segundo parámetro es una constante llamada IDI_APPLICATION cuyo valor en hexadecimal es 07f00h.

*Para cargar el cursor son casi las mismas reglas que para el ícono, solo que ahora usamos la función LoadCursor con cero e IDC_ARROW. El valor de IDC_ARROW es también 7f00h.

Una vez que acabamos de rellenar esta enorme estructura, lo que hacemos es llamar a la función de la API de Windows llamada RegisterClassEx. Me imagino que se han de estar preguntando como meter esa enorme estructura con movimientos de Stack. La respuesta es ¡No lo hacemos!. Cuando una función necesita trabajar con una estrucura muy grande lo que hacemos es obtener la posición en la que esta estructura ‘vive’ en la memoria. Ese valor, que no es mas que un maldito entero es el que empujamos al Stack y san se acabó. Sin embargo, aquí tenemos 2 problemitas:

El primero es donde demonios se considera que ‘vive’ una estructura tan grande. Cuando manejamos estructuras grandes, tomamos como ‘domicilio’ la posición de memoria del primero de sus elementos, en este caso es cbSize. Es como jalar a una vaca por el anillo que tienen en la nariz. Y ahí es donde entra el segundo problemita:

*¿Que demonios significa eso de LEA?. La instrucción LEA toma 2 operandos, el primero es un registro general y el segundo el contenido de una celda de memoria. Al ejecutarla el sistema obtiene la EFFECTIVE ADDRESS o posición de memoria efectiva y la guarda en el registro indicado en el primer operando. Esta instrucción en apariencia inutil es muy importante, pues toda función usa posicionamientos de memoria relativos a EPB o ESP. Una dirección efectiva en cambio es la posición real del dato dentro de la memoria. Que es con la que realmente trabajan las funciones que operan sobre localidades de memoria. Creo que esta instrucción merece su nota aparte.

Para acabar, se usa LEA eax, [cbSize] para obtener la posición de memoria efectiva de la estructura WNDCLASSEX y acto seguido se introduce en el Stack con PUSH eax. Luego se llama a RegisterClass.

Hasta ahora, el programa no hace nada, apenas le dijimos como queremos la ventana de nuestro programa, en la siguiente nota se explicará por fin como demonios es que se despliega una ventana de verdad, y si se les hace aburrido, mejor sigan el consejo que da nombre esta nota y tírense por la ventana, no importa si viven en la planta baja.

enero 22, 2009 - Posted by | Uncategorized

Aún no hay comentarios.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: