2025-02-05
Introducción a win32
Allá por el año 2000 Brook Milles (theForger) escribió un tutorial para aprender las nociones básicas de win32, que voy a exponer en el blog, dado que es la forma en la que programé algunas cosas.
¿Sobre qué trata este tutorial?
Este tutorial está destinado a presentarte las bases (y algunos extras comunes) de escribir programas utilizando la API de WIN32. El lenguaje usado es C, y generalmente compilarán bien la mayoría de los compiladores de C++. Además, mucha de la información es aplicable a cualquier lenguaje que pueda acceder a la API, incluyendo Java, Assembler y Visual Basic. Sin embargo no voy a presentar nigún código relacionado a estos lenguajes y queda a cargo del lector si desea hacerlo, de hecho, varias personas han usado previamente este tutorial en otros lenguajes con algo de éxito.
Este tutorial no pretende enseñar el lenguaje C++ ni tampoco cómo usar algún compilador en particular (Borland C++, Visual C++, BCC-Win32, etc...). Sin embargo me tomaré un momento en el apéndice para dar algunas notas sobre como usar los compiladores que conozco.
Si no sabes que es una macro o que que es typedef o si no sabes cómo funciona la sentecia switch(), entonces te recomiendo que primero leas un buen libro o tutorial sobre el lenguaje C.
Un Simple programa Win32
Si eres un completo principiante vamos a asegurarnos que eres capaz de compilar una aplicación básica de windows. Copia el siguiente código a tu compilador y si todo va bien obtendrás uno de los programas mas pobres jamás escritos.
Recuerda compilar esto como C, no como C++. Esto probablemente no importe pero debido a que todo el código es C puro tiene sentido comenzar por el camino correcto. En muchos casos todo lo necesario es simplemente poner el código en un archivo con extensión .c en vez de .cpp. Si todo esto te marea simplemente guarda el archivo con el nombre test.c y listo.
#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK); return 0; }
Si esto no funciona, tu primer paso es leer que errores obtuviste y si no los entiendes búscalos en la ayuda o en algún documento que acompañe tu compilador. Asegúrate de haber especificado "GUI Win32" y no "Console" dentro de la opción project/compile/target de tu compilador. Desafortunadamente no puedo ayudarte mucho con esta parte ya que los errores y cómo corrregirlos varían de compilador en compilador (y de persona en persona).
Quizás obtengas algunos "Warnings" diciéndote que no has usado los parámetros provistos en WinMain( ), pero esto está bien. Ahora que sabemos que puedes compilar un programa veamos esta pequeña porción de código:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
WinMain() es en Windows el equivalente al main() de DOS o UNIX. Es ahí donde los programas comienzan su ejecución. Los parámetros son los siguientes:
| HINSTANCE hInstance | Handle al módulo ejecutable del programa (el archivo .exe en memoria). |
| HINSTANCE hPrevInstance | Siempre nulo (o NULL) en programas Win32. | LPSTR lpCmdLine | Un string (o cadena de caracteres) con los argumentos de linea de comando. No incluye el nombre del programa. |
| int nCmdShow | Un valor entero que puede ser pasado a ShowWindow( ), veremos esto mas adelante. |
hInstance es usado para cosas como cargar recursos y cualquier otra tarea que sea realizada en una base por-modulos. Un módulo puede ser el archivo .EXE cargado en memoria o una librería DLL cargada en tu programa. En la mayor parte de este tutorial (por no decir todo el tutorial) habrá un solo módulo del cual preocuparse: el EXE.
hPrevInstance es usado en Win16 como handle a la instancia de ejecución anterior (si la hubo). Esto ya no se aplica en Win32 por lo tanto ignoramos este parámetro.
WINAPI especifica una convención de llamada y es definida como stdcall. No te preocupes si no sabes que sigifica esto ya que no nos afectará dentro del alcance de este tutorial. Solo recuérdalo.
Tipos de datos en Win32
Seguramente has encontrado que muchos de los tipos de datos tienen definiciones específicas de windows, UINT para unsigned int (entero no signado) LPSTR para char*, etc... lo que elijas depende de ti. Si te sientes mas cómodo utilizando char* en lugar de LPSTR eres libre de hacerlo. Solo asegúrate bien de que tipo de dato se trata antes de substituir algo.
Sólo recuerda algunas cosas y luego será fácil de interpretar. El prefijo LP representa Long Pointer (Puntero Largo). En Win32 la parte larga es obsoleta por lo tanto no te preocupes por ella. Si no conoces que es un puntero puedes hacer lo siguiente: buscar un tutorial de C, o seguir adelante y saltarte una parte. Realmente recomiendo la primer opción, aunque muchas personas elijen la segunda... Después no digas que no te avisé.
La letra C que sigue luego de LP indica que se trata de un puntero "Constante". Por lo tanto LPCSTR representa "Long Pointer to Const String" o "Puntero Largo un String Constante" pero como ya dijimos, en Win32 podemos ignorar la parte "long" así que esto podría leerse "Puntero a un String Constante", uno que no se puede modificar. Por otro lado LPSTR no es constante y puede ser modificado.
Quizás has visto una "T" ahí en medio. No te preocupes por esto por ahora, a menos que intencionalmente estés trabajando con UNICODE, no significa nada.