Ir al contenido

publicidad

Foto

Curso MM: 1 Elementos Básicos


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
No hay respuestas en este tema

#1

Escrito 01 agosto 2009 - 15:19

Elementos básicos
- Api de Windows (application programming interface): es un conjunto de funciones y estructuras específicas de Windows.
- Programación orientada a eventos: tanto la estructura como la ejecución de los programas van determinados por los sucesos que ocurran en el sistema o que ellos mismos provoquen. Mientras en la programación secuencial (o estructurada) es el programador el que define cuál va a ser el flujo del programa, en la programación dirigida por eventos será el propio usuario --o lo que sea que esté accionando el programa-- el que dirija el flujo del programa. Aunque en la programación secuencial puede haber intervención de un agente externo al programa, estas intervenciones ocurrirán cuando el programador lo haya determinado, y no en cualquier momento como puede ser en el caso de la programación dirigida por eventos.
Lo que se hace es programar sólo lo necesario en respuesta a los eventos que nos interesan. El resto los tratará el sistema por defecto, así que no tenemos que preocuparnos por ellos.
- Comunicación con mensajes: los eventos generan mensajes que van a parar la ventana adecuada para que los procese.
- Independencia de dispositivo: en Windows no tratas directamente con el hardware, lo haces a través del sistema operativo. Solicitas un "contexto de dispositivo" y trabajas con él en vez de con el hardware.
- Recursos: los elementos ajenos al código fuente como iconos, imágenes, sonidos, menús, se almacenan aparte con el nombre de "recursos".
- Nuevos tipos de datos: como RECT o HWND. Todos los datos del api win32 están en mayúsculas. Para que sean reconocidos hay que incluir la línea #include en el código fuente.
- Notación húngara: cuando trabajas en grupo es bueno que tengáis un acuerdo sobre cómo llamar a las variables. Una de esas formas es la notación húngara. Por ejemplo:
i - entero.
b - booleana.
sz - cadena terminada en 0.
p - puntero.
h - handle (identificador de algún elemento).
w - unsigned short integer(WORD).
dw - unsigned long integer (DWORD).
l - long integer.
etc.

Echando un vistazo dentro de un programa de Windows
Primero unas pocas explicaciones y luego vamos con el código completo de un programa básico.

- En Windows no hay main(), hay WinMain(), ésta función inicializa algunas cosas y crea la ventana, luego ya nos podemos olvidar de ella.

- La clase ventana: Todas las ventanas se crean basadas en la clase ventana, que es una plantilla que define los atributos de una ventana. Por ejemplo los botones se crean con un tipo concreto de la clase ventana. Para crear una ventana propia hay que registrar el tipo de ventana y luego crear una ventana con esa clase. Para hacerlo se usa RegisterClassEx() y luego CreateWindow().

- Las clases ventana se representan con una extructura del API llamada WNDCLASSEX que define los atributos:

[code:1]typedef struct _WNDCLASSEX {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HICON hIconSm;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSEX;[/code]
Si revisamos la estructura podemos ver:

- lpfnWndProc - puntero al procedimiento de ventana para la clase ventana.
- hIcon - el icono para la clase ventana.
- hIconSm - mini icono opcional.
- hCursor - el cursor del ratón.
- hbrBackground - el pincel de fondo para la clase ventana.

Para crear una ventana utilizamos CreateWindow() , un ejemplo:

[code:1]hwnd = CreateWindow(szAppName,
"My Game",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);[/code]
- szAppName es el nombre del programa. "My Game" es el nombre de la ventana. WS_OVERLAPPEDWINDOW es una ventana tradicional redimensionable. CW_USEDEFAULT indica la posición xy de la ventana y su tamaño.

- Manejando mensajes. Los mensajes contienen la siguiente información: una ventana, un identificador del mensaje y parámetros. Los parámetros se llaman wParam y lParam y en cada mensaje tienen una utilidad diferente. Los mensajes los gestiona el procedimiento de ventana ( WndProc() ) por defecto pero los programas pueden enrutarlos hacia los procedimientos adecuados a través del bucle de mensajes que hay en WinMain():

[code:1]while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}[/code]
- El Procedimiento de ventana: Toda ventana en un programa de Windows tiene asociado un procedimiento de ventana, que es una función especial que puede ser llamada por Windows para pasarle mensajes. Se define así:

[code:1]LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);[/code]
- hwind - handle de la ventana a la que se quiere enviar el mensaje.
- iMsg - identificador del mensaje.
- wParam - parámetro principal del mensaje.
- lParam - parámetro secundario del mensaje.

Casi todos los WndProc() tienen una gran sentencia switch para trabajar con los mensajes. Un ejemplo con un sólo mensaje:

[code:1]LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch (iMsg) {
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, iMsg, wParam, lParam);
}[/code]

Este switch sólo maneja un mensaje (WM_DESTROY), el resto van a DefWindowProc() que los trata por defecto.

- Trabajando con recursos. (bitmap, cursor, dialog box, icon, menu, user-defined). Primero se les asigna un número en el archivo Resource.h a cada recurso para poder identificarlos. Después todos se definen usando un lenguaje de script en un archivo con extensión *.rc en el que se indica el tipo de recurso y otros datos como el nombre del archivo. Luego se compilan en un archivo *.res. que se enlaza con el código fuente del programa para crear el ejecutable. Ejemplo:

IDI_MINE ICON "Mine.ico"
IDC_MINE CURSOR "Mine.cur"

Vamos con el ejemplo

Es una especie de "Hola mundo". Consta de 4 archivos:
- Resource.h : cabecera para identificar los recursos con números.
- skeleton.rc : localización de los recursos definidos en Resource.h.
- Skeleton.h : cabecera para compilar el programa con windows.h y Resource.h
- Skeleton.cpp : el programa con WinMain() y WndProc().

Resource.h : se asigna un número a cada recurso.
[code:1]//-----------------------------------------------------------------
// Skeleton Resource Identifiers
// C++ Header - Resource.h
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Icons Range : 1000 - 1999
//-----------------------------------------------------------------
#define IDI_SKELETON 1000
#define IDI_SKELETON_SM 1001[/code]

Skeleton.rc :identifica el tipo de recurso (ICON los dos) y su localización.
[code:1]//-----------------------------------------------------------------
// Skeleton Resources
// RC Source - Skeleton.rc
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------
#include "Resource.h"

//-----------------------------------------------------------------
// Icons
//-----------------------------------------------------------------
IDI_SKELETON ICON "Skeleton.ico"
IDI_SKELETON_SM ICON "Skeleton_sm.ico"[/code]

Skeleton.h
[code:1]//-----------------------------------------------------------------
// Skeleton Application
// C++ Header - Skeleton.h
//-----------------------------------------------------------------

#pragma once //para que no sea incluido éste archivo más de una vez.

//-----------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------
#include
#include "Resource.h"[/code]

Skeleton.cpp
[code:1]//-----------------------------------------------------------------
// Skeleton Application
// C++ Source - Skeleton.cpp
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Include Files
//-----------------------------------------------------------------
#include "Skeleton.h"

//-----------------------------------------------------------------
// Declaración de la función del procedimiento de ventana.
//-----------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam);

//-----------------------------------------------------------------
// Funciones globales
//-----------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Skeleton"); //TEXT es una macro para portabilidad de textos.

WNDCLASSEX wndclass;
HWND hWindow; //aquí guardaremos el identificador (handle) de la ventana que vamos a crear.
MSG msg;

// se crea la clase de ventana para definir la ventana principal.
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_SKELETON));
wndclass.hIconSm = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_SKELETON_SM));
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;

// Se registra la clase de ventana.
if (!RegisterClassEx(&wndclass))
return 0;

// creamos la ventana.
hWindow = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

// Mostramos y actualizamos la ventana.
ShowWindow(hWindow, iCmdShow);
UpdateWindow(hWindow);

// El bucle principal de mensajes.
while (GetMessage(&msg, NULL, 0, 0)) //obtiene un mensaje de la cola.
{
// Process the message
TranslateMessage(&msg); //adapta algunos mensajes.
DispatchMessage(&msg); //manda los mensajes a WndProc().
}
return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hDC; //variable donde guardaremos el identificador del contexto de dispositivo.
PAINTSTRUCT ps; //estructura necesaria para dibujar.
RECT rect; //estructura que define un rectángulo.

switch (msg)
{
case WM_PAINT: //cada vez que se modifica la ventana el sistema genera un mensaje de éstos.
// Dibujar texto centrado en el área cliente de la ventana principal.
// Con BeginPaint() pedimos un contexto de dispositivo para dibujar en la ventana indicada en hWindow.

hDC = BeginPaint(hWindow, &ps);

//Con GetClientRect obtenemos en una estructura RECT las coordenadas de los cuatro puntos que
//definen el área cliente de la ventana.

GetClientRect(hWindow, &rect);
DrawText(hDC, TEXT("This is a skeleton application!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);

//Es necesario advertir al sistema que dejamos de dibujar.

EndPaint(hWindow, &ps);
return 0;

case WM_DESTROY:
// Salimos del programa cuando se genera éste mensaje. Pulsando la X de la ventana, o con el menú, o ctrl-f4,etc.
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWindow, msg, wParam, lParam);
}[/code]

Código Fuente

¿Cómo compilar el ejemplo?
- Vas a Archivo->Nuevo Proyecto.
- Seleccionas "Windows application" y le das un nombre al proyecto. Aceptar.
- Buscas la carpeta en la que se encuentra para grabar allí el archivo de proyecto *.dev
- Si te crea automáticamente un archivo main.cpp pincha a la izquierda en el nombre del proyecto y con el botón derecho eliminas main.cpp.
- Pincha con el botón derecho en el nombre del proyecto y dale a "añadir a proyecto".
- Selecciona Resource.h, Skeleton.cpp y Skeleton.rc y dale a Abrir.
- Justo encima un icono que son cuatro cuadraditos separados es para compilar.
- Y ya está hecho. (también hay otro icono para compilar+ejecutar).


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad