manejo de pantalla

32
Manejo de pantalla Borrar pantalla Clrscr: Borrar la pantalla Ahora ya sólo nos falta saber cómo se borra la pantalla. Pues es tan fácil como usar: Code: clrscr() (clear screen, borrar pantalla) Esta función nó solo borra la pantalla, sino que además sitúa el cursor en la posición (1, 1), en la esquina superior izquierda. Code: #include <stdio.h> #include <conio.h> int main() { clrscr(); Printf ( "Hola" ); getch (); } Este método sólo vale para compiladores que incluyan el fichero stdio.h. Si tu sistema no lo tiene puedes consultar la sección siguiente. Borrar la pantalla (otros métodos) Existen otras formas de borrar la pantalla aparte de usar stdio.h. Si usas DOS: Code: system ("cls");

Upload: eamoon

Post on 03-Jul-2015

307 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Manejo de pantalla

Manejo de pantalla

Borrar pantalla

Clrscr: Borrar la pantalla

Ahora ya sólo nos falta saber cómo se borra la pantalla. Pues es tan fácil como usar:

Code:clrscr()

(clear screen, borrar pantalla)

Esta función nó solo borra la pantalla, sino que además sitúa el cursor en la posición (1, 1), en la esquina superior izquierda.

Code:#include <stdio.h> #include <conio.h> int main() { clrscr(); Printf ( "Hola" );getch (); }

Este método sólo vale para compiladores que incluyan el fichero stdio.h. Si tu sistema no lo tiene puedes consultar la sección siguiente.

Borrar la pantalla (otros métodos)

Existen otras formas de borrar la pantalla aparte de usar stdio.h.

Si usas DOS:

Code:system ("cls");Para DOS

Si usas Linux:

Code:system ("clear");Para Linux

Otra forma válida para ambos sistemas:

Page 2: Manejo de pantalla

Code:char a[5]={27,'[','2','J',0};

/* Para ambos (en DOS cargando antes ansi.sys) */

printf("%s",a);

COLOR DE TEXTO Y FONDO

http://c.conclase.net/borland/index.php?borlandlib=conio#inicio

void textcolor(int color);

Esta función selecciona el color de texto especificado por el argumento color. Esta función solamente funciona con aquellas funciones que envú}n datos de salida en modo texto directamente a la pantalla. El argumento color es un número entero entre 0 y 15 y el número 128, para activar el parpadeo; también se pueden usar constantes simbólicas definidas en conio.h en lugar de enteros. La función textcolor no afecta cualesquiera de los caracteres actualmente en pantalla, pero sEafecta aquéllas mostradas por funciones �que usan el vúeo directamente para la salida en modo texto después de llamar a la �función textcolor.

Existen varias constantes simbólicas de colores para usar.

La función textcolor no retorna ningún valor.

ejemplo

Page 3: Manejo de pantalla

#include <conio.h>

int main() {

cprintf( "Ejemplo de \"textbackground\" y \"textcolor\"\r\n\r\n" );

textbackground( BLUE );

textcolor( LIGHTRED );

cprintf( "Este mensaje tiene otro color de fondo y de texto.\r\n" );

textbackground( WHITE );

cprintf( "Este mensaje tiene un color de fondo distinto.\r\n" );

normvideo();

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

return 0;

}

void textbackground(int color);

Esta función selecciona el color de fondo especificado por el argumento color. Esta función solamente funciona con aquellas funciones que envú}n datos de salida en modo texto directamente a la pantalla. El argumento color es un número entero entre 0 y 7; también se pueden usar constantes simbólicas definidas en conio.h en lugar de enteros. La función textattr no afecta cualesquiera de los caracteres actualmente en pantalla, pero sEafecta aquéllas mostradas por funciones que usan el vú� �eo directamente para la salida en modo texto después de llamar a la función textattr.

Existen varias constantes simbólicas de colores para usar.

Page 4: Manejo de pantalla

#include <conio.h>

int main() {

cprintf( "Ejemplo de \"textbackground\" y \"textcolor\"\r\n\r\n" );

textbackground( BLUE );

textcolor( LIGHTRED );

cprintf( "Este mensaje tiene otro color de fondo y de texto.\r\n" );

textbackground( WHITE );

cprintf( "Este mensaje tiene un color de fondo distinto.\r\n" );

normvideo();

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

return 0;

}

Los colores que se pueden usar son:

BLACK 0 BLUE 1 GREEN 2 CYAN 3 RED 4 MAGENTA 5 BROWN 6 LIGHTGRAY 7

El numero adelante del color es el código en numero de dicho color.

En algunos casos se pueden usar versiones claras de los colores en el texto, que son:

DARKGRAY 8 LIGHTBLUE 9

Page 5: Manejo de pantalla

LIGHTGREEN 10 LIGHTCYAN 11 LIGHTRED 12 LIGHTMAGENTA 13 YELLOW 14 WHITE 15

Para el texto ademas se tiene la opcion de hacerlo parpadear (blink), sumando al color

BLINK 128

osea, digamos asi:

Código:

textcolor(RED+BLINK);

OTRO:

void textattr(int atributo);

Esta función asigna ambos colores de primer plano y de fondo en una sola llamada. (Normalmente, se asignan estos atributos mediante las funciones a textcolor y textbackground). La

función textattr no afecta cualesquiera de los caracteres actualmente en pantalla, pero sEafecta aquéllas mostradas por funciones que usan el vú� �eo directamente para la salida en modo texto después de llamar a la función textattr.

La información de los colores estEcodificado en el argumento atributo según este �diagrama:

Bits

7 6 5 4 3 2 1

P f f f p p p p

En el argumento atributo de 8 bits:

pppp es el color de primer plano de 4 bits (0-15).

Page 6: Manejo de pantalla

fff es el color de fondo de 3 bits (0-7).

P es el bit de encendido de parpadeo.

Si el bit del parpadeo estEactivado, entonces los caracteres parpadean. Esto se puede �lograr añadiendo la constante BLINK al atributo.

Si se usan las constantes simbólicas definidas en conio.h para crear los atributos de texto usando textattr, ten en cuenta las siguientes limitaciones para el color de fondo seleccionado:

Sólo se pueden elegir uno de los primeros ocho colores para el fondo.

Deberás mudar el color de fondo seleccionado 4 bits a la izquierda para que estén colocados en las posiciones correctas de los bits.

Existen varias constantes simbólicas de colores para usar.

#include <conio.h>

int main() {

/* Azul de fondo y rojo claro de texto */

int atributo=BLUE << 4 | LIGHTRED;

cprintf( "Ejemplo de \"textattr\"\r\n\r\n" );

textattr( atributo );

cprintf( "Este mensaje tiene otro color de fondo y de texto.\r\n" );

textattr( atributo + BLINK );

cprintf( "Este mensaje estEparpadeando.\r\n" );�

Page 7: Manejo de pantalla

normvideo();

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

return 0;

}

OTRO

void textmode(int modo);

Esta función selecciona un modo de texto especificado por el argumento modo. Este argumento puede ser una constante simbólica del tipo de enumeración text_modes (en conio.h).

Cuando se llama a la función textmode, la ventana en uso es reiniciada a la pantalla completa, y los atributos de texto en uso son reiniciados a normal, correspondiendo a una llamada a normvideo. Especificando LASTMODE a textmode causa el modo de texto más recientemente seleccionado a ser seleccionado de nuevo.

La función textmode deberú} usarse solamente cuando la ventana o pantalla es en modo de texto (supuestamente para cambiar a un modo de texto diferente). Este es el único contexto donde se usa la función textmode. Cuando la pantalla estEen modo gráfico, usa �la función restorecrtmode en vez de salirse temporalmente a mode de texto.

Existen varias constantes simbólicas para indicar los modos de texto.

#include <conio.h>

int main() {

Page 8: Manejo de pantalla

struct text_info *ti;

unsigned char modo_original;

modo_original = ti->currmode;

clrscr();

cprintf( "Ejemplo de \"textmode\"\r\n\r\n" );

cprintf( "Cambiamos de modo: BW40.\r\n" );

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

textmode( BW40 );

cprintf( "Ahora cambiamos a modo: C4350.\r\n" );

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

textmode( C4350 );

cprintf( "Ahora cambiamos a modo \"normal\".\r\n" );

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

textmode( modo_original );

return 0;

}

Page 9: Manejo de pantalla

POSICIONAMIENTO DEL CURSOR

//Funcion: gotoxy()

//Sintaxis:

//void gotoxy(int x, int y);

//Descripcion: Mueve el cursor de la ventana de texto a la posicion segun las coordenadas

//especificadas por los argumentos x e y. Si las coordenadas no son validas entonces

//la llamda a la funcion gotoxy es ignorada. Los argumentos no pueden ser 0.

//Ejemplo:

#include <conio.h>

void main() {

clrscr();

cprintf( "Ejemplo de \"gotoxy\"\n\n" );

cprintf( "1Elinea " );�

cprintf( "2Elinea" );�

gotoxy( 5, 20 ); //me posiciono en "renglon" 20

cprintf( "3Elinea, pero sale £ltima" );�

gotoxy( 20, 2 ); //me posiciono en el "renglon" 2

cprintf( "4Elinea, pero sale segunda" );�

gotoxy( 1, 15 ); //me posiciono en el "rengon" 15

cprintf( "Pulsa una tecla para continuar...\r\n" );

getch();

}

Usa la funcion gotoxy(int x, int y);

como dice la palabra Go To XY EN español ir a XY, donde X y Y son las cordenadas de la pantalla

Normalmente la pantalla esta dividida en 80 columnas y 25 filas...

Solo tienes que Colocar las coordenadas.. Supongamos que quieres poner el cursor en la columna

Page 10: Manejo de pantalla

3 fila 10.. Coloca el comando

gotoxy(3,10);

Esta funcion pertenece a la libreria conio.h asi que no olvide colocar en el encabezado

#include<conio.h>

void gotoxy(int x, int y);

Mueve el cursor de la ventana de texto a la posición según las coordenadas especificadas por los argumentos x e y. Si las coordenadas no son válidas entonces la llamda a la función gotoxy es ignorada. Los argumentos no pueden ser 0.

#include <conio.h>

int main() { clrscr(); cprintf( "Ejemplo de \"gotoxy\"\r\n\r\n" ); cprintf( "1ª línea" ); cprintf( "2ª línea" ); gotoxy( 5, 20 ); cprintf( "3ª línea" ); gotoxy( 20, 1 ); cprintf( "4ª línea" ); gotoxy( 1, 15 ); cprintf( "Pulsa una tecla para continuar...\r\n" ); getch();

return 0;}

Normalmente, al ejecutar un programa escrito en lenguaje C, el cursor se posiciona (por defecto) en la primera columna de la primera fila.

_ (cursor)

 

A partir de esa posición, se mostrarán por pantalla los datos de salida de dicho programa.

Ejemplo 1 (ejemplo_11_33_1.c del libro): Si se escribe

Page 11: Manejo de pantalla

#include <stdio.h>

int main(){   printf( "uno dos tres" );

   return 0;}

Tal cual está escrita la función printf, por pantalla se verá el texto "uno dos tres" pegado a la esquina superior izquierda de la misma.

uno dos tres

 

Hasta ahora, no nos hemos preocupado del lugar exacto de la pantalla donde queremos que se muestren los datos de salida. Sin embargo, si deseamos visualizar dicho texto en otro lugar de la pantalla, por ejemplo, en la segunda línea:

uno dos tres

 

Esto se puede conseguir haciendo uso de la secuencia de escape nueva línea (\n).

   printf( "\nuno dos tres" ); (ejemplo_11_33_2.c del libro)

Partiendo de que, inicialmente, el cursor se encuentre en la primera columna de la primera fila, es decir, en la esquina superior izquierda de la pantalla, la secuencia de escape nueva línea (\n) lo moverá al principio de la segunda fila y, a continuación, se escribirá el texto "uno dos tres". Obsérvese que, los caracteres que forman la secuencia de escape, (\) y (n), no aparecen en pantalla.

La instrucción anterior hace lo mismo que las dos siguientes

   printf( "\n" );   printf( "uno dos tres" ); (ejemplo_11_33_3.c del libro)

Ejemplo 2: Si por pantalla se quiere ver

unodos

Page 12: Manejo de pantalla

tres

 

hay que escribir

   printf( "uno\ndos\ntres" ); (ejemplo_11_34_1.c del libro)

El proceso de ejecución de esta instrucción es el siguiente: justo en la esquina superior izquierda de la pantalla (primera línea) se muestra el texto "uno". Después, una secuencia de escape nueva línea (\n) mueve el cursor al principio de la línea siguiente (segunda línea), en donde se visualiza el texto "dos". Posteriormente, otra secuencia de escape nueva línea (\n) vuelve a mover el cursor al principio de la línea siguiente (tercera línea) y, finalmente, se muestra el texto "tres".

La instrucción anterior es equivalente a:

   printf( "uno" );   printf( "\ndos" );   printf( "\ntres" ); (ejemplo_11_34_2.c del libro)

Igualmente, se podría escribir

   printf( "uno\n" );   printf( "dos\n" );   printf( "tres" ); (ejemplo_11_34_3.c del libro)

Ejemplo 3: Para visualizar

   uno dos tres

 

se puede escribir

   printf( "\n   uno dos tres" ); (ejemplo_11_35.c del libro)

Ejemplo 4: Y para mostrar

   uno   dos   tres

Page 13: Manejo de pantalla

 

escribiremos, por ejemplo,

   printf( "\n   uno\n   dos\n   tres" ); (ejemplo_11_36.c del libro)

La secuencia de escape tabulador horizontal (\t) mueve el cursor a la posición siguiente del tabulador horizontal de la pantalla. Entre cada posición hay ocho caracteres, por tanto, dichas posiciones están en las columnas 1, 9, 17, 25, 33, 41, 49, 57, 65 y 73.

Ejemplo 5: De la instrucción

   printf( "diez\tveinte\ttreinta" ); (ejemplo_11_37.c del libro)

se obtiene por pantalla

diez    veinte  treinta

 

Obsérvese que, la d (de diez), la v (de veinte) y la primera t (de treinta) están en las posiciones del tabulador horizontal 1, 9 y 17, respectivamente. Gráficamente, representando los espacios en blanco mediante guiones (-), en pantalla se muestra:

1       9       17      25  ...

diez----veinte--treinta

 

Entre el carácter d (de diez) y la v (de veinte) hay exactamente ocho caracteres (la v no se cuenta), al igual que entre la v (de veinte) y la primera t (de treinta).

Las secuencias de escape comilla doble (\") y barra invertida (\\) sirven para mostrar por la pantalla los caracteres comilla doble (") y barra invertida (\), respectivamente.

Ejemplo 6 (ejemplo_11_39_1.c del libro): Al escribir

   printf( "\n\t\t7 de julio \"San Fermin\"" );

en la segunda línea de la pantalla se mostrará, a partir de la tercera posición del tabulador horizontal (columna 17), el mensaje: "7 de julio "San Fermin""

Page 14: Manejo de pantalla

1       9       17      25 ...

                7 de julio "San Fermin"

 

void window(int izquierda, int superior, int derecha, int inferior);

Define una ventana de texto en pantalla especificado por los argumentos izquierda y superior, que describen la esquina superior izquierda y por los argumentos derecha e inferior, que describen la esquina inferior derecha. El tamaño mínimo de la ventana de texto es una columna por una fila. La ventana por defecto es la pantalla completa con la esquina superior izquierda siendo (1,1) y la inferior derecha siendo (C,F); donde C es el número de columnas y F el número de filas según el modo de texto en uso. La llamada a la función window será ignorada si alguno de los argumentos no son válidos.

#include <conio.h>

int main() { clrscr(); cprintf( "Ejemplo de \"window\"\r\n\r\n" ); cprintf( "La ventana de texto será de (10,10) á (50,20).\r\n" ); window( 10, 10, 50, 20 ); cprintf( "Ahora estamos dentro de la ventana de texto.\r\n" ); cprintf( "Pulsa una tecla para continuar..." ); getch();

return 0;}

void _setcursortype(int tipo_cursor);

Selecciona la apriencia del cursor entre tres tipos. El argumento tipo_cursor indica el tipo de cursor a seleccionar según éstos:

_NOCURSOR Desactiva el cursor

_NORMALCURSORCursor normal: el carácter de subrayado

_SOLIDCURSOR Cursor es un cuadrado

Page 15: Manejo de pantalla

relleno

^ #include <conio.h>

int main() { char nombre[15], si_no=' ';

_setcursortype( _SOLIDCURSOR ); clrscr(); cprintf( "Ejemplo de \"_setcursortype\"\r\n\r\n" ); cprintf( "Cambiamos el cursor a cuadrado.\r\n\r\n" ); cprintf( "Escribe tu nombre: " ); cscanf( "%s", &nombre ); cprintf( "\r\n(Ahora desactivaremos el cursor)\r\n\r\n" ); _setcursortype( _NOCURSOR ); cprintf( "Escribiste \"%s\", ¿es esto correcto? (s/n) ", nombre ); while( si_no != 's' && si_no != 'n' ) si_no = getche(); cprintf( "\r\nOpción: %s\r\n", 's'==si_no ? "SI" : "NO" ); cprintf( "Pulsa una tecla para continuar..." ); getch(); _setcursortype( _NORMALCURSOR );

return 0;}

gotoxy (ir al punto x,y) nos posiciona el puntero en la coordenada que especifiquemos, por ejemplo:

gotoxy ("20,10");printf("Hola C");

lo cual nos da como resultado que el puntero se mueva a la linea 20 y la columna 10, despues imprime en pantalla Hola C

QUE VAMOS A HACER:Un programa que imprima en pantalla el enunciado "HOLA C" en la posicion 20,30

CODIGO:

#include #include main ()

Page 16: Manejo de pantalla

{gotoxy (20,30);printf("Hola C");getch();return 0;}EXPLICACION:Explicare linea por linea

#include<stdio.h> Agregamos la libreria standar de entrada y salida i/o (in/out) necesaria para introducir datos proporcionar salidas.

#include<conio.h> Agregamos la libreria conio.h que es necesaria para compilar ciertas instrucciones como getch();

main() Es la funcion principal e nuestro programa, en ella van contenidos todas las instrucciones de nuestro programa que estan entre llaves { }

{ Inicio del programa.

printf("Hola C"); Sentencia que indica al programa que debe desplegar en pantalla lo que esta entre comillas, en este caso: Hola C

getch(); Sentencia que espera a que el usuario presione cualquier tecla. Como resultado obtenemos una pausa con la cual podemos comprobar nuestro programa.

return 0; Sentencia que hace que no se regrese ningun valor.

} Fin del programa.

Page 17: Manejo de pantalla

EJEMPLOS DE GOTOXY

#include<conio.h>#include<stdio.h>void main (void){clrscr();textcolor(4);gotoxy(35,13);cprintf ("*hola mundo*");getch();}

*********************************Otro ejemplo#include<stdio.h>#include<conio.h>void main (void){clrscr();textcolor(3);gotoxy(40,20);cprintf("*");gotoxy(38,21);cprintf("* * *");gotoxy(36,22);cprintf("* * * * * ");gotoxy(34,23);cprintf("* * * * * * * ");gotoxy(36,24);cprintf("* * * * * ");gotoxy(38,25);cprintf("* * * ");gotoxy(40,26);cprintf("*");getch();}

CREACION DE VENTANA

Page 18: Manejo de pantalla

Una Simple Ventana.Ejemplo: simple window

A veces las personas ingresan al IRC y preguntan "¿Como hago una ventana...?". Bien, no es tan simple como parece. No es difícil una vez que sepas lo que estás haciendo, pero hay algunas cosas que necesitas hacer para poder crear un ventana. Y son mas de las que pueden ser explicadas en una sala de chat o en una nota rápida.

Siempre me gustó hacer las cosas primero y aprenderlas luego... por lo tanto aqui está el código de una simple ventana que será explicado en breve.

#include <windows.h>

const char g_szClassName[] = "myWindowClass";

// Step 4: the Window ProcedureLRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0;}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASSEX wc; HWND hwnd; MSG Msg;

//Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0;

Page 19: Manejo de pantalla

wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

// Step 2: Creating the Window hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);

// Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam;}

Generalmente este es el programa más simple que puedes escribir par crear una ventana funcional, digamos unas 70 líneas de código. Si has compilado el primer ejemplo, entonces este debería funcionar sin problemas.

Paso 1: Registrar la Clase VentanaUna Clase Ventana almacena información sobre el tipo de ventana, incluyendo su Window Procedure, los íconos grandes y pequeños y el color de fondo. De esta forma podemos registrar una clase una vez y luego crear muchas ventanas a partir de ésta, sin tener que especificar todos los atributos una y otra vez. Muchos de los atributos que especificamos en la Clase Ventana pueden ser cambiados, si se desea, en una base per-windows.

Page 20: Manejo de pantalla

La Clase Ventana no tiene nada que ver con las clases de C++.

const char g_szClassName[] = "myWindowClass";La variable anterior almacena el nombre de nuestra Clase Ventana y la usaremos en breve para registrar nuestra clase en el sistema.

WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName =g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

Este es el código que usamos en WinMain( ) para registrar nuestra Clase Ventana en el sistema. Para ello, rellenamos los campos de una estructura WNDCLASSEX y llamamos a RegisterClassEx( ). Los campos de la estructura son los siguientes:

cbSize

El tamaño de la estructura

style

El estilo de la clase (CS *), no confundirse con el estilo de la ventana (WS *). Generalmente este campo puede ser puesto en cero.

lpfnWndProc

Puntero al Window Procedure de esta clase.

cbClsExtra

Cantidad extra de asignación de memoria para datos de la clase. Generalmente cero.

cbWndExtra

Cantidad extra de asignación de memoria por ventana de este tipo. Generalmente cero.

Page 21: Manejo de pantalla

hInstance

Handle a la instancia de la aplicación (la que obtenemos en el primer parámetro de WinMain( ) )

hIcon

Handle al ícono grande (32x32), mostrado cuando el usuario presiona Alt+Tab.

hCursor

Handle al cursor que será mostrado sobre la ventana.

hbrBackground

Pincel para fijar el color de fondo de nuestra ventana.

lpszMenuName

Nombre del recurso Menú para usar con las ventanas de esta clase.

lpszClassName

Nombre para identificar la clase.

hIconSm

Handle al ícono pequeño (16x16), usado en la barra de tareas y en la esquina superior izquierda de la ventana.

No te preocupes si esto no queda muy claro aún, las distintas partes que vimos serán explicadas mas adelante. Otra cosa para recordar es no intentar memorizar toda esta estructura. Yo raramente (de hecho nunca) memorizo estructuras o parámetros de funciones, esto es un desperdicio de tiempo y esfuerzo. Si conoces las funciones que necesitas llamar, entoces es una cuestión de segundos mirar los parámetros exactos en la ayuda de tu compilador. Si no tienes los archivos de ayuda entonces consigue algunos porque sin ellos estas perdido. Eventualmente irás aprendiendo los parámetros de las funciones que mas usamos.

Luego llamamos a RegisterClassEx( ) y chequeamos por alguna falla, si hubo alguna mostramos un mensaje y abortamos el programa retornando a la función WinMain( ).

Paso 2: Crear la Ventana:

Una vez que la clase ha sido registrada, podemos usarla para crear una ventana. Observemos los parámetros de la función CreateWindowEx( ) (como lo haremos con cada nueva llamada a la API que veamos), los explicaré brevemente:

HWND hwnd; hwnd = CreateWindowEx(

Page 22: Manejo de pantalla

WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);

El primer parámetro (WS_EX_CLIENTEDGE) es el estilo extendido de la ventana, en este caso he configurado éste para darle un borde interno y hundido al marco de la ventana. Pon este valor en cero para observar la diferencia, o prueba con otros valores para ver que hacen.

A continuacióm tenemos el nombre de la clase (g_szClassName), éste le dice al sistema que tipo de ventana crear. Debido a que queremos crear una ventana a partir de la clase que hemos registrado, usamos el nombre de dicha clase. Luego especificamos el nombre de nuestra ventana o título que aparecerá en la barra de título de la ventana.

El parámetro que tenemos como WS_OVERLAPPEDWINDOW es estilo de la ventana. Hay algunos de éstos y deberías mirarlos y experimentar para observar que hacen. De todos modos serán cubietos mas adelante.

Los siguientes cuatro parámetros ( CW_USEDEFAULT, CW_USEDEFAULT,320,240) son las coordenadas X e Y de la esquina superior izquierda de la ventana y el alto y ancho de de la ventana, respectivamente. He puesto los campos X e Y con el valor CW_USEDEFALT para dejar que windows elija en qué lugar de la pantalla ubicar la ventana. Recuerda que la parte izquierda de la pantalla tiene un valor de X igual a cero y se incrementa hacia la derecha y la parte superior de la pantalla tiene un valor cero de Y y se incrementa cuando avanzamos hacia abajo en la pantalla. Las unidades son los pixeles, el cual es la miníma unidad que una pantalla puede mostrar en una resolución determinada.

Los siguientes parámetros (NULL,NULL,g_hInstance,NULL) corresponden al handle de la ventana padre, al handle del menú, al handle de la instancia de la aplicación y un puntero a los datoscon los cuales se creó la ventana. En windows las ventanas son ordenadas en la pantalla de acuerdo a una jerarquía de padre e hijo. Cuando ves un botón en una ventana, el botón es el Hijo de la ventana en la cual está contenido y dicha ventana es su Padre. En este ejemplo, el handle al padre es nulo debido a que no tenemos padre, estamos en el nivel principal de las ventanas. El handle al menú es nulo debido a que, por ahora, no tenemos menú. El handle a la instancia de la aplicación es puesto con el valor que es pasado en el primer parámetro del WinMain( ). Los datos de creación (los culaes nunca uso) pueden ser usados para enviar información adicional a la ventana que está siendo creada. También es nulo. Si estás preguntándote que es la palabra mágica NULL, es simplemente definida como cero (0). En realidad, en C está definida como ((void *) 0), debido a que está destinada a ser usada con punteros. Por lo tanto probablemente obtengas algunos "warnings" si la utilizas para valores enteros, de todas maneras esto depende del compilador y del nivel de warnings en la configuaración del mismo. Puedes elegir ignorar los warnings o usar el valor cero (0)en lugar de NULL.

Page 23: Manejo de pantalla

La principal causa de que las personas no conozcan cuales son las fallas de sus programas es que no chequean los valores de retorno de las llamadas a funciones para determinar si éstas han fallado o no. CreateWindow( ) puede fallar aún si eres un experimentado programador debido a que hay una gran cantidad de errores que son fáciles de cometer. Hasta que aprendas como identificar rápidamente dichos errores date la oportunidad de resolverlos y siempre chequea los valores de retorno!

if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; }

Después que hemos creado la ventana y hemos chequeado para asegurarnos de que tengamos un handle válido, mostramos la ventana utilizando el último parámetro provisto en WinMain( ) y luego lo actualizamos para asegurarnos que se halla redibujado en la pantalla a si mismo de manera apropiada.

ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);

El parámetro nCmdShow es opcional, simplemente puedes pasar el valor SW_SHOWNORMAL en todo momento y listo. Sin embargo si usamos el parámetro provisto en WinMain( ) le da a quien esté corriendo tu programa la oportunidad de especificar si quiere que la ventana comienze visible, maximizada, minimizada, etc... Encontrarás opciones para este parámetro en las propiedades de los iconos del escritorio y apartir de estos valores será determinado el valor que tome el parámetro nCmdShow.

Paso 3: El Bucle de Mensajes

Este es el corazón del programa, la mayoria de las cosas que tu programa realiza pasan a través de este punto de control.

while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam;

GetMessage() obtiene un mensaje de la cola de mensajes de tu aplicación. Cada vez que el usuario mueve el mouse, presiona el teclado, hace click en el menú de la ventana , etc... el sistema genera mensajes que ingresan en la cola de mensaje de la tu aplicación. Utilizando GetMessage( ) estás solicitando que el siguiente mensaje disponible en la cola sea removido de la misma y te sea entregado para procesarlo. Si no hay mensajes, GetMessage( ) se bloquea . Si no estás familiarizado con dicho término, esto significa que espera a que halla un mensaje en la cola y luego te lo retorna.

Page 24: Manejo de pantalla

TranslateMessage( ) hace algunos procesos adicionales en los eventos del teclado, como generar mensajes WM_CHAR que van junto a los mensajes WM_KEYDOWN. Finalmente DispatchMessage( ) envía el mensaje a la ventana que había recibido dicho mensaje. Esta podría ser nuestra ventana principal, otra ventana, o un control e incluso una ventana que fué creada "detrás de la escena" por el sistema o algún otro progama. Esto no es algo que debería precocuparte debido a que lo único que nos interesa saber es que obtenemos el mensaje y lo envíamos, el sistema se encarga de hacer el resto asegurándose de trabajar con la ventana correcta.

Paso 4: El Windows ProcedureSi el bucle de mensajes es el corazón del programa entonces el Windows Procedure es el cerebro. Aqui es donde todos los mensajes son envíados para que sean procesados por nuestra ventana.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){ switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0;}

El Windows Procedure (pronunciado "winprock") es llamado por cada mensaje que procesamos, el parámetro HWND es el handle dela ventana a la cual se aplica el mensaje. Esto es importante debido a que puedes tener dos o mas ventanas de la misma clase que usarán el mismo Windows Procedure (WndProc( ) ), la diferencia es que el parámetro hWnd será diferente dependiedno de la ventana. Por ejemplo cuando obtenemos el mensaje WM_CLOSE (cerrar ventana) destruimos la ventana y debido a que usamos el handle de la ventana (que recibimos en el primer parámetro) sabremos que ventana es la que hay que destruir. Las demás ventanas no se verán afectadas, solo la que recibió el mensaje.

WM_CLOSE es envíado cuando el usuario presiona ALT+F4 o cuando presiona el botón . Esto causará que la ventana sea destruida por default, pero prefiero manejarlo explicitamente debido a que es el punto perfecto para realizar "limpiezas" o preguntarle al usuario si desea guardar los cambios, etc...antes que la ventana se destruida. (i.e el programa finalice).

Cuando llamamos a DestroyWindow( ) el sistema envía el mensaje WM_DESTROY a la ventana que va a ser destruída, que en este caso es nuestra ventana, y por lo tanto destruimos todas las ventanas hijas antes de remover nuestra ventana del sistema. Debido a que esta es nuestra única ventana en nuestro programa todo lo que hacemos es salir del

Page 25: Manejo de pantalla

mismo, para ello utilizamos la llamada PostQuitMessage( ). Esta envía el mensaje WM_QUIT al bucle de mensajes pero nunca recibimos este mensaje debido a que éste causa que GetMessage( ) retorne FALSE y como vimos en el código del Bucle de Mensajes, cuando esto sucede, dejamos de procesar mensajes y retornamos el código resultante final, el Wparam del WM_QUIT el cual es el valor pasado en PostQuitMessage( ). El valor de retorno solo es usado si tu programa está diseñado para ser llamado por otro programa y quieres que retorne un valor especifico.