You are on page 1of 42

1

Introduccin a la
Programacin
para Windows
con Visual C++
Ignacio Alvarez Garca
Ing. De Sistemas y Automtica
Universidad de Oviedo
Enero de 2005
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
1
INDICL
1. Programacin orientada a entornos graicos ....................................................................... 1
2. Introduccin a la programacin orientada a objetos con C--........................................ 4
2.1 Clases y objetos ............................................................................................................... 5
2.1.1 lunciones constructor y destructor......................................................................... 6
2.2 Clases deriadas...............................................................................................................
2.3 Sobrecarga de unciones ................................................................................................ 8
2.3.1 Sobrecarga de operadores ......................................................................................... 9
2.4 lunciones irtuales ......................................................................................................... 9
2.5 Otras caractersticas interesantes de C--................................................................. 10
2.5.1 Declaracin de ariables locales............................................................................. 10
2.5.2 Ll puntero this.......................................................................................................... 10
2.5.3 Polimorismo ............................................................................................................ 10
2.5.4 Parametros por deecto........................................................................................... 11
2.5.5 Creacin y eliminacin dinamica de objetos ........................................................ 12
2.5.6 Operador reerencia ,&,.......................................................................................... 12
3. Programacin en entorno \indows ................................................................................... 14
3.1 Ventanas......................................................................................................................... 14
3.2 Sericios del sistema..................................................................................................... 15
4. Programacin con la librera MlC en Visual C--........................................................... 15
4.1 1ipos de aplicacin....................................................................................................... 15
4.2 Creacin del marco de programa ............................................................................... 15
4.3 Programacin de la arquitectura documento,ista.................................................. 18
4.3.1 Implementacin del documento............................................................................ 19
4.3.2 Implementacin de la ista ..................................................................................... 21
4.3.2.1 lunciones y clases para el dibujo.................................................................. 23
4.3.2.2 Seleccionando dierentes caractersticas de dibujo..................................... 24
4.3.2.3 Lscala de dibujo............................................................................................... 25
4.3.2.4 lunciones auxiliares de la entana y la ista................................................ 26
4.3.3 Lnlazando eentos con el cdigo que los sire ................................................... 26
4.3.4 Crear y llamar a cuadros de dialogo....................................................................... 29
4.3.4.1 Creando el cuadro de dialogo con el editor de recursos ........................... 29
4.3.4.2 Creacin de la clase y de las ariables miembro asociadas a controles ... 31
4.3.4.3 Llamada al cuadro de dialogo........................................................................ 32
4.3.4.4 Cuadros de dialogo con comportamiento dinamico.................................. 33
4.3.4.5 Inicializando controles en la clase dialogo................................................... 35
4.3.4.6 Cuadros de dialogo predeinidos .................................................................. 36
4.3.5 Lentos temporizados............................................................................................. 36
4.3.5.1 Litando el parpadeo...................................................................................... 3
4.4 Programando aplicaciones MDI y basadas en dialogo............................................ 39
4.5 Utilizar hilos de procesamiento .................................................................................. 39
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
1
1. Programacin orientada a entornos grficos
La programacin para entornos graicos diiere sustancialmente de la programacin
orientada a interaz de tipo texto ,modo consola,. Mientras que en modo consola el
programador organiza de orma secuencial tanto las instrucciones de calculo como las de
interaccin con el usuario ,print, scan, getchar, etc.,, en un entorno graico no esta
deinido el orden exacto en que el usuario interactuara con el programa ,ej: pulsar una u
otra opcin de men, maximizar la entana, pulsar un botn, cambiar un texto, etc.,.
Por ello, la orma de organizar un programa para ambos entornos es bastante distinta
,igura 1,.
Ln modo consola se an intercalando las sentencias de calculo y las de interaccin con el
usuario en la secuencia que desea el programador.
Sin embargo, en modo graico se ejecuta un bucle permanentemente: se espera por un
eento ,del usuario o del sistema,, se ejecuta el cdigo asociado a ese eento, y se uele a
esperar el siguiente. Los eentos pueden ser ariados: se ha pulsado un botn del ratn, se
ha pulsado una tecla, se ha seleccionado una opcin de men, se ha creado una entana, se
ha cambiado el tamano de la entana, etc. Ademas, no se puede deinir a priori el orden de
los eentos sino que depende del usuario.
Sentencias
Clculo y E/S
Alternativa
Sentencias
Clculo y E/S
Sentencias
Clculo y E/S
Bucle
Sentencias
Clculo y E/S
Estilo de programa
en modo consola
Estilo de programa
en modo grfico
Espera
evento
Sentencias
ev1
Segn evento
Sentencias
ev2
Sentencias
ev3
Sentencias
ev4
Sentencias
Inicializacin
Sentencias
ev Terminar
igvra 1
Dentro de los dierentes eentos en modo graico, es importante comprender los asociados
al dibujo de la entana. A dierencia del modo consola, en que se manda escribir algo en la
consola ,print, y esa escritura es permanente` ,esto es, no es necesario rerescarla,, en
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
2
modo graico sera necesario redibujar la entana completa o parte de ella cuando sea
requerido, y este requerimiento puede proenir del programa o del sistema ,p. ej., la
entana estaba siendo tapada por otra y lo ha dejado de estar,, lo cual es indicado mediante
un eento. Por ello, en modo graico es necesario que el programa tenga almacenado todos
los datos necesarios para poder redibujar todo el contenido de la entana en cualquier
momento en que sea recibido al eento redibujar`.
Para realizar la programacin de las entanas y de sus eentos, el Sistema Operatio con
entorno graico ,en nuestro caso \indows, proporciona una serie de unciones en una
librera. Lse conjunto de unciones se suele denominar API ,Application Programming
Interace,, que en \indows se llama SDK ,Sotware Deelopment Kit,. Las unciones ah
contenidas seriran para gestionar entanas ,crear, redimensionar, cerrar, etc., de dierentes
tipos ,normal, men, botn, cuadro de dialogo, cuadro de texto, lista de seleccin, etc.,,
obtener eentos, realizar acciones de dibujo, etc.
Un API es un conjunto de unciones muy extenso, ya que son necesarias muchas y muy
ariadas unciones para gestionar el entorno de entanas. Ademas, muchas de las
uncionalidades son muy repetitias a lo largo de los programas ,ej. crear entana principal
con opciones de men,, requiriendo un conjunto de llamadas al API relatiamente
complejo y pesado incluso para el programa mas sencillo.
Ll siguiente ejemplo muestra, simplemente para ilustrar su complejidad, el cdigo para la
programacin de una entana sin ninguna uncionalidad adicional.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
3
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure (se llama cada vez que se despacha un mensaje en
el bucle principal de programa)
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;
}
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;
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;
}
Ejemplo.c
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
4
Para acilitar este trabajo, muchos entornos de desarrollo ,en nuestro caso Visual C--,
proporcionan una orma mas sencilla de acceder al API, mediante una librera de clases que
encapsula la mayor parte de la complejidad, y slo deja como tarea al programador la
realizacin de las partes especicas de su programa. La librera de clases en Visual C-- se
llama MlC ,Microsot loundation Classes,. As, por ejemplo, la creacin de la entana
principal estara encapsulada en una serie de objetos que hacen que se pueda crear el marco
del programa sin escribir una sola lnea de cdigo adicional a las clases ya disponibles!
Para ayudar an mas, los entornos de desarrollo suelen disponer de utilidades que permiten
situar de orma graica los elementos de interaz ,mens, botones, cuadros de texto, etc.,, e
incluso enlazarlos con las unciones de sericio de sus eentos de una orma graica e
intuitia. De esta manera, el programador se ahorra de escribir gran cantidad de cdigo ,se
ahorra no slo tiempo, sino tambin errores, y, ademas, la parte a la ista` de su programa
es muy clara y concisa.
Dado que los elementos de interaz graico se pueden describir y utilizar mucho mas
acilmente como objetos, lo habitual es que se utilice la programacin orientada a objetos
para la programacin de estos interaces.
Ln lo que sigue de este documento, por lo tanto, se describiran por este orden de una
orma muy sucinta:
Los principios de la programacin orientada a objetos.
Los dierentes elementos que aparecen en un programa orientado a entorno
graico, particularizando para \indows.
La programacin mediante la librera de clases MlC sobre Visual C-- para
entorno \indows.
2. Introduccin a Ia programacin orientada a objetos
con C++
La programacin orientada a objetos permite trasladar a los programas la orma de pensar
que tenemos en la solucin o descripcin de problemas en general. Normalmente nos
reerimos a entidades ,objetos,, que solemos clasiicar en grupos con caractersticas y
uncionamiento comunes ,clases,, y de las cuales nos interesan ciertas caractersticas
,propiedades, y su uncionamiento ,mtodos,.
Ademas, al relacionar unos objetos con otros para disenar sistemas complejos, solemos
utilizar la encapsulacin, esto es, permitimos que los objetos interacten entre s slo a
tras de las caractersticas y uncionalidades expuestas al exterior, mientras que las
caractersticas y uncionalidades internas de cada uno son ignoradas por el resto.
Ll lenguaje C-- es una extensin a C para soportar la programacin orientada a objetos
,POO,. Lo que sigue no es un manual de C--, sino una muy bree introduccin para ser
capaz de manejar los objetos, propiedades y mtodos de las clases de MlC. Para una
documentacin mas exhaustia se sugiere la lectura de Aprenda C-- como si estuiera en
1`, de la Uniersidad de Naarra, y descargable en Internet.
Para escribir cdigo en C-- se pondra la extensin .cpp` a los archios de cdigo uente.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
5
2.1 Clases y objetos
Ll elemento undamental de la POO es la clase. Una clase es una deinicin de propiedades
y mtodos para un conjunto de entidades que comparten caractersticas comunes.
Ln C--, una clase se deine de manera similar a una estructura, pero utilizando la palabra
clae class` en lugar de struct`, y pudiendo declarar como integrantes de la misma tanto
ariables ,propiedades, como mtodos ,unciones que manipulan dichas ariables, slo se
indica su prototipo en la declaracin de la clase,.
Por ejemplo, para la manipulacin de nmeros complejos podemos crear una clase
Complejo, que incluira como ariables la parte real e imaginaria, y como mtodos el
calculo del mdulo, argumento, la suma , multiplicacin y diisin de otro complejo, la
exponenciacin, etc. 1anto las ariables como los mtodos pueden ser pblicos ,accesibles
desde dentro y uera del objeto,, priados ,accesibles slo desde las unciones de la clase, o
protegidos ,accesibles desde las unciones de la clase y de sus deriadas,.
Las sentencias anteriores contienen la declaracin de una clase. Para que tenga
uncionalidad, se necesita:
Lscribir el cuerpo de las unciones de la clase Complejo. Para ello, se escribe el
prototipo de la uncin, indicando que pertenece a la clase, y a continuacin su
cuerpo:
tipodevuelto clase::funcion(params)
{
}
Crear ariables de tipo Complejo, y utilizar las ariables y mtodos deseados para
cada una de esas ariables. Cuando se accede a un mtodo, ste utiliza las ariables
de la instancia ,ariable, objeto, sobre la que se aplica.
...
class Complejo
{
// Attributes
public:
float re,im;
// Operations
public:
float Modulo();
float Arg();
void AnadirReal(float valor);
...
} ;
...
EjemploPOO.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
6
1ras la ejecucin del cdigo anterior, a` sera el complejo 11-4j, y b` sera el complejo
5-14j.
Mediante el uso de ariables y unciones miembro pblicas y priadas se puede conseguir
que desde el exterior a los objetos de la clase Complejo slo se pueda acceder a las
uncionalidades deseadas, resultando por tanto el comportamiento de dichos objetos una
caja negra que slo puede interactuar con otros elementos de la orma que haya preisto su
programador.
Para acilitar la realizacin de programas orientados a objetos, es habitual que para cada
clase dierente se utilicen 2 archios, uno de cabecera ,.h, y otro de implementacin ,.cpp,.
Ln el archio de cabecera se coloca la deinicin de la clase, y en el archio de
implementacin el cuerpo de las unciones. Para el ejemplo anterior, lo usual sera diidir el
cdigo en 3 archios:
class Complejo
{
// Attributes
...
} ;
#include "complejo.h"
float Complejo::Modulo()
{
...
}
void Complejo::AnadirReal(float v)
{
...
}
...
#include "complejo.h"
main()
{
Complejo a,b;
float z;
a.re=3; a.im=4;
b.re= a.Modulo();
b.im=a.im+10;
a.AnadirReal(8);
}
2.1.1 Funciones constructor y destructor
Lxisten dos unciones especiales que se pueden anadir a las clases: constructor y destructor.
Ll constructor es una uncin que se llama exactamente igual que la clase y que no
...
class Complejo
{
...
} ;
float Complejo::Modulo()
{
float result;
result=sqrt(re*re+im*im);
}
...
void Complejo::AnadirReal(float valor)
{
re+=valor;
}
...
main()
{
Complejo a,b;
float z;
a.re=3; a.im=4;
b.re= a.Modulo(); b.im=a.im+10;
a.AnadirReal(8);
}
EjemploPOO.cpp
Complejo.h Complejo.cpp EjemploPOO.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas

deuele nada ,ni siquiera oid,. Ll constructor es llamado automaticamente por C--
cuando se crea un nueo objeto de la clase. Ademas, puede haber arios constructores con
dierentes parametros. Para el caso de los complejos, podramos hacer un constructor que
d el alor por deecto 0-0j, y otro que d un alor inicial dado desde el exterior:
1ras la ejecucin del cdigo anterior, a` sera el complejo 0-0j ,se ha utilizado el
constructor sin parametros,, y b` sera el complejo 5-8j.
De la misma manera existe la uncin destructor, que es llamada de orma automatica por
C-- cuando deja de existir el objeto. Ll destructor se declara como el constructor con una
tilde ,~, delante.
2.2 Clases derivadas
Dado que mltiples clases pueden compartir elementos comunes, la POO se suele realizar
de orma jerarquizada, escribiendo clases base` con las partes comunes y deriando a partir
de ellas clases mas especializadas con otros elementos especicos. Una clase deriada` de
otra hereda todas sus caractersticas, esto es, ariables y unciones miembro, ademas de
poder anadir las suyas propias. Un objeto de la clase deriada podra acceder a todas las
ariables y unciones declaradas en ella, as como a las ariables y unciones pblicas o
protegidas de la clase base. Asimismo, de la nuea clase puede deriarse otra, etc.,
ormandose una jerarqua de clases.
Para deriar una clase de otra se indica en su declaracin:
class clasederivada : public clasebase
{
// Variables y funciones de la clase derivada
} ;
#include "complejo.h"
main()
{
Complejo a;
Complejo b(5,8);
}
...
Complejo::Complejo()
{
re=0; im=0;
}
Complejo::Complejo(float i_re,float i_im)
{
re=i_re; im=i_im;
}
...
...
class Complejo
{
...
// Operations
public:
Complejo();
Complejo(float i_re,float i_im);
...
} ;
Complejo.h
Complejo.cpp
EjemploPOO.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
8
Puesto que en la misma declaracin de la clase deriada se necesita conocer quin es la
clase base, se debe realizar en el archio de cabecera ,.h, de la clase deriada la inclusin del
archio de cabecera de la clase base.
Por ejemplo, para realizar una serie de objetos graicos que se puedan dibujar ,lnea,
cuadrado, cuadrado con texto, elipse, etc.,, se podra realizar una jerarqua de clases como
la que sigue:
colorBorde Color
NuevoTam(tX,tY) nombre[40] char
MoverA(nueX,nueY) tamX,tamY int
Dibujar() posX,posY int
Mtodos Propiedades
Deriva de: ObjetoGraf Clase:
colorBorde Color
NuevoTam(tX,tY) nombre[40] char
MoverA(nueX,nueY) tamX,tamY int
Dibujar() posX,posY int
Mtodos Propiedades
Deriva de: ObjetoGraf Clase:
Dibujar()
Mtodos Propiedades
ObjetoGraf Deriva de: Linea Clase:
Dibujar()
Mtodos Propiedades
ObjetoGraf Deriva de: Linea Clase:
PonQuitaFondo(siono)
CambiarFondo(nue) fondo Fondo
Dibujar() hayFondo int
Mtodos Propiedades
ObjetoGraf Deriva de: ConFondo Clase:
PonQuitaFondo(siono)
CambiarFondo(nue) fondo Fondo
Dibujar() hayFondo int
Mtodos Propiedades
ObjetoGraf Deriva de: ConFondo Clase:
Dibujar() radioEsquina int
Mtodos Propiedades
ConFondo Deriva de: Rectangulo Clase:
Dibujar() radioEsquina int
Mtodos Propiedades
ConFondo Deriva de: Rectangulo Clase:
Dibujar()
Mtodos Propiedades
ConFondo Deriva de: Elipse Clase:
Dibujar()
Mtodos Propiedades
ConFondo Deriva de: Elipse Clase:
CambiarTexto(nue) fuente Font
Dibujar() texto[100] char
Mtodos Propiedades
ConFondo Deriva de: Texto Clase:
CambiarTexto(nue) fuente Font
Dibujar() texto[100] char
Mtodos Propiedades
ConFondo Deriva de: Texto Clase:
Ln el ejemplo anterior, la clase 1exto tiene las ariables miembro o.`,o.Y, tav`, tavY,
vovbre, cotororae por ser ObjetoGra; ba,ovao y fovao por ser Conlondo, raaio.qviva por
ser Rectangulo, y teto y fvevte por ser 1exto. Desde las unciones miembro de 1exto se
podra acceder a aquellas ariables miembro de las clases ineriores que hayan sido
declaradas pblicas o protegidas.
Lo anterior es asimismo aplicable a las unciones miembro.
2.3 Sobrecarga de funciones
Si una clase deriada tiene deinida una uncin idntica ,con el mismo nombre,
parametros y tipo deuelto, que en la clase base, se dice que ha sobrecargado dicha
uncin. Cuando se llama a esta uncin se utiliza la de la clase deriada y no la de la base.
Lsto permite que las clases deriadas tengan uncionalidades dierentes a la clase base con
el mismo nombre de uncin.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
9
2.3.1 Sobrecarga de operadores
Dentro de las unciones que se pueden sobrecargar estan los operadores. Lsto quiere decir
que se puede redeinir el comportamiento de un operador, por ejemplo la suma, para una
clase determinada. As, se podra hacer ,er apartado 2.5.6 para la explicacin de & y
apartado 2.5.2 para la explicacin de this,:
1ras la ejecucin del cdigo anterior, a` sera el complejo 3-4j, y b` sera el complejo 5-12j.
2.4 Funciones virtuales
Cuando se utilizan unciones sobrecargadas, en muchos casos es necesario llamar a la
uncin de la clase deriada desde la clase base. Ln el ejemplo anterior, si se utiliza una
tabla de objetos graicos de orma genrica, para cada uno de ellos se utilizara la uncin de
dibujo apropiada de la clase deriada. Cuando se desea utilizar una uncin sobrecargada
por una clase deriada desde una reerencia a la clase base, debe indicarse que esa uncin
es irtual.
Ll siguiente ejemplo muestra este comportamiento para los objetos graicos ,er
signiicado de new y delete en 2.5.5,:
#include "Complejo.h"
main()
{
Complejo a,b;
a.re=3; a.im=4;
b.re=2; b.im=8;
b+=a;
}
...
Complejo& Complejo::operator +=(const Complejo& otro)
{
re+=otro.re;
im+=otro.im;
return *this;
}
...
...
class Complejo
{
...
// Operations
public:
Complejo& operator +=(const Complejo& otro);
...
} ;
...
Complejo.h
Complejo.cpp
EjemploPOO.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
10
Ln el ejemplo anterior, el tipo de uno` es ObjetoGra, pero se puede crear el objeto de
cualquier clase que derie de ObjetoGra. Si el operador selecciona n~~1, uno` apuntara a
un objeto de tipo 1exto ,que tambin es ObjetoGra,, y si selecciona n~~2 uno` apuntara
a un objeto de tipo Llipse.
Si la uncin Dibuja,, no es irtual, se llamara a la uncin Dibuja,, de ObjetoGra, ya que
se resuele a qu uncin se llama en tiempo de compilacin y uno` es de tipo ObjetoGra.
Si la uncin Dibuja,, es irtual, en tiempo de ejecucin se comprueba el tipo actual del
objeto a que apunta uno` ,1exto o Llipse,, y se llama a la uncin adecuada:
1exto::Dibuja,, si se haba escogido n~~1, o Llipse::Dibuja,, si se haba escogido n~~2.
2.5 Otras caractersticas interesantes de C++
A continuacin se describen otras caractersticas del lenguaje C-- que pueden ser
necesarias o tiles.
2.5.1 DecIaracin de variabIes IocaIes
Ln C-- las ariables locales pueden declararse en cualquier punto del programa, y no slo
al principio de un bloque de cdigo como en C.
2.5.2 EI puntero this
Dentro de las unciones de una clase existe la ariable implcita this`, que es un puntero al
objeto de la clase que se esta utilizando en ese momento.
2.5.3 PoIimorfismo
Ln C-- se pueden declarar arias unciones con el mismo nombre pero con parametros o
tipo deuelto distintos. Ll compilador escogera para cada llamada la uncin que se
corresponda con los parametros y el tipo deuelto de cada llamada.
Ljemplo:
#include "Texto.h"
#include "Elipse.h"
main()
{
ObjetoGraf *uno;
int n;
// Pide valor de n
...
if (n==1)
uno=new Texto;
else
uno=new Elipse;
uno->Dibuja();
delete uno;
}
EjemploGraf.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
11
2.5.4 Parmetros por defecto
Se pueden declarar parametros por deecto en una uncin, poniendo en su declaracin ,en
el .h, el alor por deecto. Si esos parametros no se pasan, se utiliza el alor por deecto.
Por ejemplo, en el caso anterior se podan haber uniicado las ersiones 1 y 2 de Sumar:
...
class Complejo
{
...
// Operations
public:
void Sumar(float real,float imag=0);
void Sumar(const Complejo& otro);
...
} ;
#include "Complejo.h"

main()
{
Complejo a,b;
a.re=3; a.im=4;
b.re=2; b.im=8;
a.Sumar(3,2); // Usa 1 versin de Sumar
a.Sumar(2); // Usa 2 versin de Sumar
a.Sumar(b); // Usa 3 versin de Sumar
}
...
void Complejo::Sumar(float real,float imag)
{
re+=real;
im+=imag;
}
void Complejo::Sumar(float real)
{
re+=real;
}
void Complejo::Sumar(const Complejo& otro)
{
re+=otro.re;
im+=otro.im;
}
...
...
class Complejo
{
...
// Operations
public:
void Sumar(float real,float imag);
void Sumar(float real);
void Sumar(const Complejo& otro);
...
Complejo.h
Complejo.cpp
EjemploPOO.cpp
Complejo.h
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
12
2.5.5 Creacin y eIiminacin dinmica de objetos
Si se desea crear de orma dinamica un objeto, se utiliza el operador new seguido de la clase
que se desea crear. Lste operador realiza la asignacin dinamica de memoria para el objeto,
llama al constructor del mismo, y por ltimo deuele un puntero al objeto creado para
poderlo utilizar. O sea, equiale a un malloc,sizeo,clase,, seguido de un clase::clase,,.
Ademas, se puede hacer que en la creacin llame a otro constructor pasando los
parametros del mismo.
Cuando se desea eliminar un objeto creado dinamicamente se utiliza delete, que llama al
destructor y luego elimina la memoria asignada.
2.5.6 Operador referencia (&)
Ln C-- existe un nueo operador & que se aplica a la declaracin de una ariable o del
tipo deuelto por una uncin, en cuyo caso esta ariable o alor deuelto se conierten en
una reerencia, esto es, algo as como un puntero no modiicable. As, si se hace:
#include "Complejo.h"

main()
{
Complejo *ptA,*ptB;
ptA=new Complejo; // *ptA vale 0+j0 (constructor por defecto)
ptB=new Complejo(5,5); // *ptB vale 5+j5 (constructor con 2 parmetros)
ptA->Sumar(*ptB);
delete ptA;
delete ptB;
}
#include "Complejo.h"

main()
{
Complejo a,b;
a.re=3; a.im=4;
b.re=2; b.im=8;
a.Sumar(3,2); // Usa 1 versin de Sumar
a.Sumar(2); // Usa 1 versin de Sumar con imag=0
a.Sumar(b); // Usa 3 versin de Sumar
}
...
void Complejo::Sumar(float real,float imag)
{
re+=real;
im+=imag;
}
void Complejo::Sumar(const Complejo& otro)
{
re+=otro.re;
im+=otro.im;
}
...
Complejo.cpp
EjemploPOO.cpp
EjemploPOO.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
13
int x;
int& y=x;
y` es una reerencia a x`, o sea, es la misma ariable con otro nombre: cualquier cosa que
se haga con y` se esta haciendo con x` y iceersa.
Como parametros de unciones, las ariables de tipo reerencia siren para indicar el
mismo objeto con otro nombre ,algo similar a haber pasado un puntero a la ariable, con la
dierencia de que no hay que acceder con puntero y que ademas esa reerencia es ija, no
se puede hacer que apunte a otra cosa,.
Como alores de salida de unciones, siren para dar una reerencia al alor deuelto. Ln
POO es muy habitual que una uncin pueda deoler una reerencia al propio objeto
,this,, er ejemplo en 2.3.1. Ojo: no deoler una reerencia a una ariable local de la
uncin, porque dicha ariable desaparecera al salir de la uncin.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
14
3. Programacin en entorno Windows
Ll elemento undamental de las aplicaciones de \indows son las entanas. 1odas las
aplicaciones ,o casi todas, incluyen, al menos, una entana. Ll API de \indows dispone de
unciones para la gestin de todas sus uncionalidades.
Dentro de estas uncionalidades estan:
Generar la salida ,dibujar, sobre las entanas. Lxisten un subconjunto de unciones
del API, llamado GDI ,Graphics Deice Interace,, que permite dibujar sobre las
entanas. 1iene la caracterstica undamental de ser independiente del dispositio,
lo que permite a las dierentes entanas compartir del espacio de pantalla, eniar la
salida a impresora u otros dispositios, etc.
Recibir y procesar las entradas del usuario, undamentalmente a tras de pulsacin
de teclas y moimientos y pulsaciones del ratn.
Utilizar entanas especiales con comportamiento predeinido, llamadas controles.
Utilizar datos especiales con inormaciones especicas, como mapas de bits para
representar graicos ,bitmaps,, iconos, mens, cadenas de caracteres, teclas
abreiadas ,aceleradores,, etc. Lstos datos son almacenados como recursos`
asociados a la aplicacin, y pueden ser acilmente utilizados en arias.
3.1 Ventanas
1odas las entanas tienen una serie de propiedades y eentos comunes, entre los que se
pueden destacar:
1ipo objeto Propiedades undamentales Lentos de inters
Ventana Identiicador
1tulo ,caption,
1ipo de entana
Posicin x,y
1amano x,y
,Ls isible
,Lsta habilitada para L,S
,enabled,
,Ls la entana actia
la sido creada
Se ha moido
Se ha cambiado su tamano
Se a a cerrar
Ll ratn se ha moido
Ll ratn se ha pulsado
Se ha pulsado una tecla
lay que redibujarla
.
Lxisten diersas entanas predeinidas de comportamiento particular, que ya tienen
implementadas ciertas uncionalidades especicas para intercambiar datos con el usuario.
Ln general, el uso de estas entanas sera muy cmodo ya que el programador slo tiene
que aportar los datos particulares de cada momento, y no debe preocuparse por
implementar su comportamiento. Lntre ellas caben destacar las siguientes ,recurdese que
heredan todas las propiedades y mtodos de las entanas, y que los eentos basicos: tecla
pulsada, ratn, redibujo, etc. ya esta implementados internamente,:
1ipo objeto Propiedades undamentales Lentos de inters
Botn Se ha hecho click en el botn
Se ha hecho doble-click en el botn
Botn
chequeable
,Lsta seleccionado Se ha cambiado la seleccin
Cuadro de
texto
1exto introducido Se ha cambiado el texto
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
15
Lista de
seleccin
N de opciones
Cadenas con las opciones
Indice de la opcin seleccionada
Se ha cambiado la seleccin
Lista combo Como un cuadro de texto -
lista de seleccin
Como un cuadro de texto - lista de
seleccin
3.2 Servicios del sistema
No toda la uncionalidad del API de \indows esta centrada en las entanas. 1ambin
dispone de unciones para realizar el resto de llamadas necesarias al sistema operatio, entre
las cuales cabe destacar unciones para:
Gestin de L,S a archios, directorios y dispositios.
Creacin y gestin de procesos e hilos, y la sincronizacin entre los mismos.
Gestin de memoria: peticin de asignacin de memoria, comparticin, etc.
Gestin de uncionalidades compartidas entre arios programas: libreras de enlace
dinamico ,DLL,.
Gestin de excepciones.
Comunicaciones en red.
4. Programacin con Ia Iibrera MFC en VisuaI C++
La librera MlC es una librera de clases que encapsula el comportamiento mas complejo
del sistema de entanas, permitiendo al programador escribir nicamente las ariables y
unciones que constituyen la uncionalidad especica de su programa. Por ejemplo, el
comportamiento de la uncin main,,, incluyendo el bucle de procesamiento de mensajes,
esta encapsulado en la clase C\inApp ya escrita, por lo que el programador simplemente
tiene que escribir el cdigo de sericio de los eentos que desea gestionar.
4.1 Tipos de aplicacin
Lxisten mltiples tipos de aspectos que presentan las aplicaciones en entorno \indows,
aunque las mas comunes son las siguientes:
lormato SDI ,Single Document Interace,: una aplicacin que tiene una sola
entana con men y una zona interior en la que se puede dibujar ,ej. Matlab,.
lormato MDI ,Multiple Document Interace,: aplicacin con una entana principal
con los mens, y arias entanas posibles en el interior, donde cada una
normalmente se reiere a un documento dierente ,ej. \ord, Visual C--,.
lormato cuadro de dialogo: aplicacin que tiene el aspecto de un cuadro de
dialogo, con dierentes elementos de interaz ,ej. programas de instalacin,.
Ln lo que sigue se trabajara sobre el caso de una aplicacin basica SDI. Posteriormente se
comentaran las dierencias de los otros casos. Para acilitar la comprensin, se realizara un
programa de ejemplo que dibuje en la pantalla una tabla de datos X,\, siendo los datos
generados por una uncin de calculo cada ez que se pulse una opcin de men.
4.2 Creacin del marco de programa
Ll entorno de programacin proee una orma de generar las clases por deecto. Para ello,
se debe crear un nueo proyecto y seleccionar la opcin MlC App\izard ,exe,.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
16
A continuacin, se debe seleccionar el aspecto de la aplicacin. Como se ha indicado
anteriormente, trabajaremos sobre el caso de una aplicacin SDI.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
1
Las siguientes entanas presentan distintas opciones ,anadir soporte de base de datos, de
controles ActieX, de conexiones de red, etc.,. Para un caso sencillo se pueden aceptar las
selecciones por deecto, excepto en el paso 4, donde se debe seleccionar la patilla
Adanced. para elegir, al menos, la extensin por deecto de los archios de datos
asociados a la aplicacin ,documentos, y el ttulo de la entana principal.
Ln los siguientes pasos se pueden aceptar las opciones por deecto, llegandose al inal en
que se crea el marco del programa.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
18
4.3 Programacin de la arquitectura documento/vista
1ras la ejecucin de los pasos anteriores se ha creado de orma automatica el marco de
nuestro programa con el aspecto SDI y la arquitectura documento,ista. Lste marco de
programa consta de 4 clases undamentales: aplicacin, entana principal, documento y
ista, cada una de ellas con las deiniciones en un archio .h y la parte ejecutia en un .cpp
,er igura anterior,. Ademas de las clases anteriores se ha creado tambin un archio de
recursos ,.rc, donde se puede editar de orma graica los elementos del interaz.
Para continuar, es necesario comprender el ormato de la arquitectura documento,ista
dispuesta por MlC para este caso.
De las 4 clases creadas, 2 son las basicas para el programa: la clase documento ,en el
ejemplo se llama CLjemploDoc,, que deria de la clase CDocument implementada en
MlC, y la clase ista ,en el ejemplo se llama CLjemploView,, que deria de la clase CView
de MlC. Coniene recordar nueamente que se puede obtener ayuda en lnea de las clases
MlC pulsando l1.
Ln la clase documento ,CLjemploDoc, implementaremos, ademas de los elementos que
escribe automaticamente el entorno de programacin, los datos que manejara nuestra
aplicacin y las unciones que los manipulan, excluyendo todo aquello que se reiera a la
interaccin con el usuario.
Ln la clase ista ,CLjemploView, se implementara todo lo relacionado con la isualizacin
e interaccin con el usuario de la aplicacin.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
19
De esta orma, esta arquitectura separa claramente la uncionalidad del programa, esto es,
lo que queremos que haga, calcule, archie, etc., que estara en el documento, de la interaz
del programa, que se ubicara en la ista. Lidentemente, ambos objetos deberan estar
relacionados: la ista debe mostrar los datos del documento, y ademas debe permitir al
usuario modiicarlos de acuerdo con las normas del interaz.
Ln el ejemplo propuesto, sera lgico situar en el documento las tablas de datos X,\, que
es lo que queremos que manipule el programa, mientras que en la ista estaran datos
auxiliares para el dibujo como la escala de los ejes, el color de la pluma de dibujo, etc.
Como norma a aplicar, se puede decir que se deben situar en el documento todos aquellos
datos que deseamos que se almacenen en archio para recuperar el estado del programa,
mientras que se sitan en la ista slo aquellos aspectos que aectan a la isualizacin
instantanea de la aplicacin. Ln el caso de ejemplo, si consideramos que el color de dibujo
es un dato que pueda ser salado y recuperado, esto es, que orma parte de los datos
basicos para que la aplicacin recupere su uncionalidad, debera estar en el documento.
4.3.1 ImpIementacin deI documento
Ln el ejemplo propuesto, se declararan en CLjemploDoc los datos necesarios ,utilizamos
tablas estaticas por mayor comodidad,.
1ambin en el documento se incluiran aquellas unciones que manipulan los datos. Por
ejemplo, la uncin que genera un nueo dato segn el algoritmo deseado ,utilizaremos una
uncin senoidal de amplitud creciente para el ejemplo,. Ln el archio .h` se declara el
prototipo de la uncin perteneciente a la clase documento, y en el .cpp` el cdigo a
ejecutar.
Lxisten unciones pre- declaradas en la clase documento que se deben rellenar: la uncin
OnNewDocument,, sera llamada cada ez que se cree un nueo documento, por lo que se
implementara en ella la inicializacin de los datos, la uncin Serialize,, sera llamada cada
...
class CEjemploDoc : public CDocument
{
protected: // create from serializ ...
CEjemploDoc();
DECLARE_DYNCREATE(CEjemploDoc)
// Attributes
public:
int datosX[500],datosY[500];
int nDatos;
float frec;
// Operations
public:
// Overrides
// ClassWizard generated ...
//{{AFX_VIRTUAL(CEjemploDoc)
public:
virtual BOOL OnNewDocument();
...
} ;
EjemploDoc.h
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
20
ez que el usuario solicite la lectura o almacenamiento de datos en un documento, y en ella
se implementara el cdigo de lectura y escritura en archio ,er ayuda de CArchie,.
...
BOOL CEjemploDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization ...
// (SDI documents will reuse ...
nDatos=0;
frec=10.0F;
return TRUE;
}
//////////////////////////////////////////
CEjemploDoc serialization
void CEjemploDoc::Serialize(CArchive& ar)
{
int i;
char linea[40];
if (ar.IsStoring())
{
// TODO: add storing code here
sprintf(linea,"%d\n",nDatos);
ar.WriteString(linea);
for (i=0;i<nDatos;i++)
{
sprintf(linea,"%5d %5d\n",
datosX[i],datosY[i]);
ar.WriteString(linea);
}
}
else
{
// TODO: add loading code here
ar.ReadString(linea,40);
sscanf(linea,"%d",&nDatos);
for (i=0;i<nDatos && i<500;i++)
{
ar.ReadString(linea,40);
sscanf(linea,"%d%d",
&datosX[i],&datosY[i]);
}
}
}
...
//////////////////////////////////////
// CEjemploDoc commands
#include <math.h>
void CEjemploDoc::CalcNuevoDato()
{
if (nDatos<0 || nDatos>=500)
// Evita salirse de la tabla
return;
datosX[nDatos]=nDatos;
datosY[nDatos]=(int) (nDatos *
sin(6.28*frec*nDatos));
nDatos++;
}
...
class CEjemploDoc : public CDocument
{
protected: // create from serial ...
CEjemploDoc();
DECLARE_DYNCREATE(CEjemploDoc)
// Attributes
public:
int datosX[500],datosY[500];
int nDatos;
float frec;
// Operations
public:
void CalcNuevoDato();
// Overrides
// ClassWizard generated ...
//{{AFX_VIRTUAL(CEjemploDoc)
public:
virtual BOOL OnNewDocument();
...
} ;
EjemploDoc.h EjemploDoc.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
21
4.3.2 ImpIementacin de Ia vista
Ln la clase Vista ,CLjemploView, se almacenaran las ariables y se escribira el cdigo
relacionado con la interaz de usuario. Ln una aplicacin SDI, los elementos basicos de
interaz son la propia entana ,entradas de teclado y ratn, y dibujo de la entana como
salida,, el men de la aplicacin, y las opciones de sistema de la entana ,minimizar,
maximizar, cerrar, cambiar tamano,. De estos elementos, nicamente ariaran de orma
importante de un programa a otro el men de la aplicacin y el dibujo a realizar en la
entana.
Para disenar el men de la aplicacin se utilizara el editor de recursos, que nos permite
anadir las opciones deseadas de men de orma graica iendo el aspecto inal que tendra.
Para el caso del ejemplo, se anadira un men con 2 opciones: cambiar recuencia, ejecutar
un nueo paso. Las iguras siguientes muestran la secuencia de pasos.
1, Seleccionar el editor de recursos ,entana izquierda, y abrir el men principal:
2, lacer doble clic en una opcin de men aca para anadir un nueo men, indicando su
texto en la opcin Caption:
3, lacer doble clic en la primera opcin de submen del anterior para anadir una opcin
de submen, indicando el texto y el nombre de una constante que hara de identiicador ,si
no se introduce el nombre de esta constante, Visual C-- asignara un nombre adecuado
para ella,.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
22
4, Id. para la segunda opcin de submen.
Para adaptar el dibujo de la entana a lo que deseamos, se escribira el cdigo necesario en
la uncin OnDraw,, de la entana, que es llamada de orma automatica cada ez que se
produce un eento que requiere el redibujo de la entana.
Ln la uncin CLjemploView::OnDraw,, se utilizaran 3 objetos undamentalmente:
Ll objeto documento, apuntado por pDoc, donde se encuentran nuestros datos y
unciones de ejecucin.
Un objeto contexto de dispositio ,CDC,, apuntado por pDC, que serira para
realizar todas las operaciones graicas sobre la entana: dibujar lneas, polgonos,
rectangulos, elipses, texto, etc. ,er ayuda de CDC,.
Los objetos base de CLjemploView: CView y principalmente C\nd, que contienen
unciones generales para todo tipo de istas y de entanas ,er ayuda de C\nd,.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
23
4.3.2.J Iunciones y clases para el dibujo
Como se ha indicado anteriormente, la clase CDC es la undamental en lo relatio al dibujo
de la entana. Un CDC encapsula un contexto de dispositio`, ente de dibujo que permite
que las rdenes sean independientes del dispositio y que las traslada al dispositio a que
est ligado ,entana, impresora, etc., de orma transparente para el usuario.
Basicamente, con el objeto de tipo CDC se puede:
Dibujar elementos graicos basicos: lneas rectas, arcos, polilneas, rectangulos,
elipses, texto, bitmaps ,matrices de alores que representan una imagen graica, y
regiones.
Seleccionar las caractersticas de dibujo de los elementos anteriores: pluma para
lneas y bordes de objetos ,pen,, relleno de lneas cerradas ,brush,, uente para
texto ,ont,, juego de colores utilizado ,palette,.
Utilizar arios sistemas de coordenadas y conertir entre unos y otros. Ln el
sistema de coordenadas por deecto, la posicin superior-izquierda de la zona de
dibujo tiene las coordenadas ,0,0,, la coordenada X aanza hacia la derecha y la
coordenada \ hacia abajo.
Lniar la salida a impresora en orma de paginas.
Crear contextos de dispositio compatibles para dibujar en segundo plano.
Ljemplos de unciones de dibujo utilizadas habitualmente de CDC son:
Moe1o,, y Line1o,,, para dibujar una lnea recta desde un punto a otro.
Polyline,, para dibujar de una sola ez un conjunto de rectas.
Arc,, para dibujar un arco.
1extOut,, para dibujar texto en una determinada posicin.
Lllipse,, para dibujar una elipse.
Rectangle,, para dibujar un rectangulo.
Polygon,, para dibujar un polgono cerrado.
Ver la ayuda de CDC ,class members, para conocer la uncionalidad y ormato de estas
unciones.
...
////////////////////////////////////////////////////////
// CEjemploView drawing
void CEjemploView::OnDraw(CDC* pDC)
{
CEjemploDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int i;
pDC->MoveTo(pDoc->datosX[0],300+pDoc->datosY[0]);
for (i=0;i < pDoc->nDatos; i++)
pDC->LineTo(pDoc->datosX[i],300+pDoc->datosY[i]);
char texto[40];
sprintf(texto,N DATOS: %d,pDoc->nDatos);
pDC->TextOut(100,10,texto);
}
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
24
Algunas de ellas necesitan el uso de clases auxiliares, como:
CPoint: encapsula la estructura POIN1 del SDK de \indows, en la que se
almacena la posicin de un punto. 1iene dos ariables miembro, e ,.
CSize: id. para la estructura SIZL del SDK, que se utiliza para el tamano. Variables
miembro c y c,.
CRect: id. para la estructura RLC1, que se utiliza para un rectangulo. Variables
miembro teft, to, rigbt, bottov.
CString: importante clase que encapsula el uncionamiento de una cadena de
caracteres. Lita al programador tratar con la parte de asignacin de memoria, uso
de instrucciones de cadena, etc., encapsulando estas necesidades en el interior de la
clase y oreciendo un interaz mas intuitio. As, por ejemplo, esta clase redeine
los operadores ~, ~~, -, -~, etc. que acilitan mucho el trabajo del programador.
Importante er la ayuda de CString para utilizar todas sus caractersticas. La
siguiente igura muestra un ejemplo en el que se e la mejora que supone.
4.3.2.2 Seleccionando diferentes caracteristicas de dibujo
Ll dibujo de lneas, el relleno de objetos cerrados, y la uente de texto son seleccionables.
Para ello, el contexto de dispositio tiene siempre asociados una pluma ,pen,, un relleno
,brush, y una uente ,ont,, que pueden ser cambiados por el programador. Para
seleccionar caractersticas distintas en cualquiera de estos objetos, se crea un nueo objeto,
se selecciona en el contexto de dispositio, y a partir de ah todo el dibujo se realiza con el
nueo.
Ln MlC, la clase CPen encapsula a una pluma, la clase CBrush a un relleno, y la clase
Clont a una uente. Ll siguiente cdigo muestra como ejemplo la utilizacin de una pluma
distinta en el dibujo deseado. Para ello, se siguen los siguientes pasos ,er ayuda de las
unciones,:
Crear una nuea pluma ,pen,, con las caractersticas: slida, 2 puntos de grosor,
color rojo ,la macro RGB permite crear un color indicando las componentes rojo,
erde y azul con alores entre 0 y 255,.
Seleccionar el objeto pluma creado en el contexto de dispositio, obteniendo una
reerencia a la pluma anterior para recuperarla cuando se acabe.
// Concatenar cadenas con un
// espacio en medio y comparar con
// una constante
CString cad1(NOMBRE),
cad2(APELLIDO1),
cad3(APELLIDO2),
todo;
todo=cad1+" "+cad2+" "+cad3;
if (todo=="PEPE PEREZ PEREZ)
{
...
}
// Concatenar cadenas con un
// espacio en medio y comparar con
// una constante
char cad1[]=NOMBRE,
cad2[]=APELLIDO1;
cad3[]=APELLIDO2;
char *todo;
todo=(char*) malloc(strlen(cad1)+
strlen(cad2)+
strlen(cad3)+3);
strcpy(todo,cad1);
strcat(todo," ");
strcat(todo,cad2);
strcat(todo," ");
strcat(todo,cad3);
if (strcmp(todo,
"PEPE PEREZ PEREZ")==0)
{
...
}
free(todo);
Sin CString Con CString
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
25
Dibujar con la nuea pluma.
Seleccionar el objeto pluma anterior cuando se ha terminado con la nuea.
Lliminar la memoria asignada por \indows al objeto pluma creado.
Se ha incluido tambin el uso de CString para mejorar el tratamiento del texto ,no es
necesario indicar su tamano maximo a priori ni hacer calculos para asignar memoria
dinamica: lo hace la clase CString internamente,.
4.3.2.3 Lscala de dibujo
lay 2 escalas a tener en cuenta para realizar el dibujo en la entana: la escala de las
unidades del documento ,X,\,, y la escala en pixels de la entana de dibujo ,Xp,\p,.
Cuando se quiere dibujar algo de una escala propia, preiamente se tiene que mapear` a la
escala en pixels.
Ll ejemplo muestra una graica X\ que se desea dibujar de recuencia s tiempo, cuyas
unidades son eidentemente muy distintas a pixels:
...
////////////////////////////////////////////////////////
// CEjemploView drawing
void CEjemploView::OnDraw(CDC* pDC)
{
CEjemploDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int i;
CPen pen(PS_SOLID,2,RGB(255,0,0)),*aPen;
aPen=(CPen*) pDC->SelectObject(&pen);
// Ahora todo lo que sigue utiliza la nueva pluma
pDC->MoveTo(pDoc->datosX[0],300+pDoc->datosY[0]);
for (i=0;i < pDoc->nDatos; i++)
pDC->LineTo(pDoc->datosX[i],300+pDoc->datosY[i]);
pDC->SelectObject(aPen);
pen.DeleteObject();
CString texto;
texto.Format(N DATOS: %d,pDoc->nDatos);
pDC->TextOut(100,10,texto);
}
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
26
1odas las rdenes de dibujo en la entana se deben realizar en coordenadas de pixels
,Xp,\p, de la propia entana. Ln muchos casos el dibujo se realiza proporcional al tamano
de entana, para conocerlo, se ejecutara la orden:
CRect rect=GetClientRect();
la cual deuele las dimensiones de la entana de dibujo en el objeto rect.
Ll cambio de escala necesario para dibujar datos que estan en la escala X,\ se muestra en la
igura siguiente:
4.3.2.4 Iunciones auxiliares de la ventana y la vista
Ademas de las unciones de dibujo del CDC, CLjemploView puede utilizar unciones
auxiliares de CView y C\nd, de las que deria. De ellas, seran de la mayor utilidad las de
C\nd. Ls importante er la ayuda de esta clase, porque dispone de muchas y muy ariadas
unciones. Por destacar algunas de las mas tiles para la apariencia graica:
GetClientRect,,, para obtener un rectangulo con las dimensiones de la zona de
dibujo de la entana, con lo cual se puede escalar adecuadamente el dibujo.
MessageBox,,, para presentar una entana de mensaje.
Show\indow,,, para mostrar u ocultar la entana.
Lnable\indow,,, para habilitar o no la entrada ,teclado y ratn, sobre la entana.
Set\indow1ext,,, para cambiar el ttulo ,caption, de la entana.
4.3.3 EnIazando eventos con eI cdigo que Ios sirve
A grandes rasgos, se puede decir que el resto del interaz de usuario sera generado
siriendo los eentos generados por el usuario o el sistema. De ellos, los mas usados seran:
Se ha pulsado una opcin de men.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
2
Se ha pulsado una tecla.
Se ha moido el ratn o se ha pulsado un botn del mismo.
Se ha creado la entana.
Se ha cerrado la entana.
Se ha redimensionado la entana.
la encido un temporizador asociado a la entana.
Para crear las unciones que siren estos eentos y enlazarlas con los mismos recurriremos
a la utilidad Class\izard ,men View.Class\izard, tecla abreiada ctrl.-\,. Ln esta
utilidad se selecciona el panel Message Maps, y se siguen los siguientes pasos:
1. Seleccionar la clase ista ,cuadro combo Class name,, ya que sobre ella
realizaremos las acciones de interaz.
2. Ln la lista de seleccin Object IDs, podremos escoger: identiicadores de
elementos de interaz ,por ejemplo el identiicador de las opciones de men
que anadimos anteriormente,, o bien la clase CLjemploView en tal que
ista. Cuando escogemos alguno de estos elementos, la lista de seleccin
mensajes relejara los eentos que podemos serir para el mismo.
3. Lscogemos uno de los mensajes, y a la derecha se actia el botn Add
lunction, que nos permite anadir una nuea uncin a la clase ista que
sira al eento seleccionado. Ln algunos casos se nos permite introducir el
nombre de la uncin ,nos sugiere un nombre adecuado segn el eento
que se sire,, y en otros ese nombre iene obligado.
4. Por ltimo, el botn Ldit Code nos permite acceder directamente al cdigo
de la uncin elegida en la clase CLjemploView.
Las siguientes iguras muestran los pasos anteriores para dotar de uncionalidad a la
opcin de men CalcularSiguiente que anadimos anteriormente.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
28
Ll Class\izard habra anadido de orma automatica el siguiente cdigo a la clase
CLjemploView:
Ln el archio .h se ha declarado automaticamente la nuea uncin, y en la clase .cpp se ha
declarado el enlace con el comando ,ON_COMMAND, y se ha preparado el cdigo para
que el programador escriba el cuerpo de la uncin.
Ln este ltimo lugar es en el que anadiremos la uncionalidad deseada para esta opcin de
men, que en este caso debe llamar a la uncin CalcNueo,, del documento y a
continuacin orzar el redibujo de la entana con Redraw\indow,, ,si no se hace esto, slo
...
BEGIN_MESSAGE_MAP(CEjemploView, CView)
//{{AFX_MSG_MAP(CEjemploView)
ON_COMMAND(ID_MISOPCIONES_CALCULARSIGUIENTE, OnMisopcionesCalcularsiguiente)
//}}AFX_MSG_MAP
...
/////////////////////////////////////////////////////////////////////////////
// CEjemploView message handlers
void CEjemploView:: OnMisopcionesCalcularsiguiente ()
{
// TODO: Add your command handler code here
}
...
class CEjemploView : public CView
{
...
// Generated message map functions
protected:
//{{AFX_MSG(CEjemploView)
afx_msg void OnMisopcionesCalcularsiguiente ();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
...
EjemploView.h
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
29
se eran los cambios en pantalla cuando \indows detecte que es necesario redibujarla por
otra causa: cambio de tamano, haba sido tapada y se uele a er, etc.,.
4.3.4 Crear y IIamar a cuadros de diIogo
Uno de los modos mas habituales de interaz con el usuario es la presentacin de cuadros
de dialogo para el intercambio de datos. Ln el caso del ejemplo, cuando el usuario
seleccione la opcin de men Cambiar lrecuencia`, la accin mas adecuada sera
presentar un cuadro de dialogo en que se presenta la recuencia actual, se permite
cambiarla, y alidar o cancelar este cambio. A continuacin se muestran los pasos para este
caso, que se resumen en:
Crear un recurso de tipo cuadro de dialogo, de orma graica, incluyendo los
elementos deseados ,controles, en el mismo.
Crear una clase deriada de CDialog ,er ayuda,, de orma automatica, que
encapsule el comportamiento del nueo cuadro de dialogo creado, crear en la nuea
clase, de orma graica, ariables miembro asociadas a los controles introducidos.
Ln la clase ista, crear un objeto del tipo de la nuea clase, inicializar las ariables
miembro, llamar a la uncin DoModal,, para que se ejecute el cuadro de dialogo, y
si la misma deuele IDOK recuperar los alores de las ariables miembro.
4.3.4.J Creando el cuadro de dilogo con el editor de recursos
Ll primer paso sera la creacin del aspecto del cuadro de dialogo, para lo cual se dispone
del editor de recursos, que permite crear el cuadro de dialogo e incluir en el mismo los
controles deseados ,botones, cuadros de insercin de texto, listas de seleccin, etc.,
Para el caso del ejemplo, slo anadiremos un texto ijo y un cuadro de introduccin de
texto. Para seguir la secuencia, recurdese que se abre un men lotante pulsando el botn
derecho del ratn sobre el elemento deseado.
...
/////////////////////////////////////////////////////////////////////////////
// CEjemploView message handlers
void CEjemploView:: OnMisopcionesCalcularsiguiente()
{
// TODO: Add your command handler code here
CEjemploDoc* pDoc=GetDocument();
pDoc->CalcNuevoDato();
RedrawWindow();
}
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
30
1, Crear nueo cuadro de dialogo en el panel Recursos de la entana de proyecto.
2, Ajustar propiedades del cuadro de dialogo, al menos identiicador y ttulo.
3, Anadir los controles deseados, ajustando las propiedades de los mismos. Ls importante
escribir identiicadores que despus nos permitan reconocer acilmente el tipo de control y
su uncionalidad en nuestro dialogo ,no necesario para los controles cuyas caractersticas
no amos a necesitar en tiempo de programacin, por ejemplo los textos estaticos que no
aran,.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
31
4.3.4.2 Creacin de la clase y de las variables miembro asociadas a
controles
Una ez dibujados los controles deseados, se llama a Class\izard ,men Ver .
Class\izard,, el cual preguntara si se desea crear una nuea clase que encapsule el
comportamiento del cuadro de dialogo creado. 1ras contestar airmatiamente y dar un
nombre adecuado a la nuea clase ,ejemplo: CCambiolrecDlg,, se pasa a la pestana
ariables de Class\izard y se asocian nueas ariables con los controles introducidos. Para
el ejemplo, se creara una ariable de tipo loat` asociada al control de texto
IDC_LDI1_lRLCULNCIA.
1, Inocar a Class\izard para crear nuea clase asociada al dialogo.
2, Introducir las ariables miembro asociadas a los controles deseados.
Ln la nuea clase CCambiarlrecDlg se habra creado una ariable loat` llamada m_rec, y
que se asocia automaticamente con el contenido del control.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
32
4.3.4.3 Llamada al cuadro de dilogo
Para llamar al cuadro de dialogo en el momento deseado, esto es, al pulsar la orden de
men Mis Opciones . Cambiar lrecuencia, se anade mediante Class\izard la uncin que
gestionara este eento en la clase CLjemploView ,er apartado 4.3.3,. Ln esta uncin se
escribe el cdigo necesario: creacin de cuadro de dialogo, inicializacin de ariables
miembro, llamada a DoModal,, y recuperacin de ariables miembro si se ha salido del
dialogo con OK:
...
#include "CambiaFrecDlg.h" // Para que conozca a la clase del dilogo
void CEjemploView::OnMisopcionesCambiarfrecuencia()
{
// TODO: Add your command handler code here
CEjemploDoc* pDoc=GetDocument(); // Obtiene puntero al documento
CCambiaFrecDlg dlg; // Crea dilogo (no muestra an)
dlg.m_frec=pDoc->frec; // Inicializa variables del dilogo
if (dlg.DoModal()==IDOK) // Presenta el dilogo. Si termina con
{ // la pulsacin de OK
pDoc->frec=dlg.m_frec; // recupera las variables del dilogo
}
}
...
CCambiaFrecDlg::CCambiaFrecDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCambiaFrecDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCambiaFrecDlg)
m_frec = 0.0f;
//}}AFX_DATA_INIT
}
void CCambiaFrecDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCambiaFrecDlg)
DDX_Text(pDX, IDC_EDIT_FRECUENCIA, m_frec);
//}}AFX_DATA_MAP
}
...
...
////////////////////////////////////
// CCambiaFrecDlg dialog
class CCambiaFrecDlg : public CDialog
{
// Construction
public:
CCambiaFrecDlg(CWnd* pParent = NULL); // standard
constructor
// Dialog Data
//{{AFX_DATA(CCambiaFrecDlg)
enum { IDD = IDD_DIALOG_FRECUENCIA };
float m_frec;
//}}AFX_DATA
...
CambiarFrecDlg.h
CambiarFrecDlg.cpp
CEjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
33
4.3.4.4 Cuadros de dilogo con comportamiento dinmico
Ln ocasiones, desearemos anadir mayores uncionalidades a un cuadro de dialogo, por
ejemplo, que al pulsar una opcin se seleccionen unos elementos del cuadro y se
deseleccionen otros, o que al cambiar un alor se actualicen otros, etc. Ls posible hacerlo
de orma sencilla anadiendo unciones que siran eentos del dialogo. Los pasos son los
mismos que los istos en 4.3.3 para la ista, pero seleccionando la clase de dialogo como
destino.
Como ejemplo, primero anadiremos un botn ,-, que hace que el alor de la recuencia se
incremente en 1:
1, Ln la entana de edicin graica del recurso cuadro de dialogo, anadimos un botn
con identiicador IDC_BU11ON_MAS y texto -` ,er apartado 4.3.4.1,.
2, Ln el Class\izard seleccionamos el panel MessageMaps, clase CCambialrecDlg,
identiicador IDC_BU11ON_MAS, mensaje BN_CLICKLD, y anadimos una
uncin para serir este eento, que llamaremos OnButtonMas,,.
3, Lscribimos el cdigo en esta uncin, que debe incrementar en 1 la ariable
miembro m_rec. Ls importante tener en cuenta que dicha ariable no es
actualizada automaticamente a partir del alor del cuadro de texto, ni el cuadro de
texto se actualiza automaticamente al cambiar el alor de la ariable, sino que es
necesario llamar a la uncin UpdateData,, del dialogo para que se sincronicen los
contenidos. UpdateData,1RUL, actualiza el alor de la ariable con el contenido
del dialogo, mientras que UpdateData,lALSL, actualiza el alor del dialogo con el
de la ariable. Ll cdigo adecuado para la uncin OnButtonMas,, sera, por tanto:
A continuacin, escribiremos el cdigo necesario para eitar que se pueda seleccionar OK
si el alor de la recuencia introducida no es mayor que cero. Para ello, sera necesario poder
acceder al control botn OK`, lo cual se realiza creando una ariable miembro en
Class\izard que sea del tipo Control y no alor:
...
/////////////////////////////////////////////////////////////////////////////
// CCambiaFrecDlg message handlers
void CCambiaFrecDlg::OnButtonMas()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); // m_frec contiene el valor que haya en el dilogo
m_frec++; // m_frec vale 1 ms
UpdateData(FALSE); // Se presenta en el dilogo el nuevo valor de m_frec
}
CambiaFrecDlg.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
34
De esta manera, se ha creado en la clase CCambiarlrecDlg una nuea ariable miembro
llamada m_botonOK` de tipo CButton. Ll tipo depende del tipo de control ,CLdit para
cuadro de texto, CListBox para lista de seleccin, etc.,. Ln la ayuda de cada uno de estos
tipos se pueden er las unciones y ariables miembro sobre las que se puede actuar ,ej: la
uncin AddString,, para un CListBox permite anadir una nuea opcin seleccionable,.
Como estos objetos derian de C\nd, dado que son entanas, tambin se pueden usar las
unciones de C\nd.
Ln nuestro caso, se creara una nuea uncin que sira el eento LN_ClANGL del
identiicador IDC_LDI1_lRLCULNCIA ,cuadro de texto de edicin de la recuencia, de
la clase CCambiarlrecDlg.
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
35
Ll cdigo de esta uncin habilita o inhabilita el control OK, a tras de la ariable
m_botonOK creada anteriormente, en uncin del alor de la ariable m_rec:
4.3.4.S Inicializando controles en la clase dilogo
Como se ha isto, la inicializacin las ariables miembro de la clase dialogo asociadas a los
controles se puede hacer despus de declarar una ariable de la clase dialogo y antes de
llamar a DoModal,,. Sin embargo, las necesarias inicializaciones relacionadas con los
controles ,por ejemplo, anadir entradas a una lista de seleccin, no es posible realizarlas en
ese momento, puesto que antes de llamar a DoModal,, no existe la entana dialogo y por
tanto tampoco ninguno de los controles ,aunque exista una ariable asociada a un control,
no existe an el control en s mismo y por tanto no se pueden utilizar unciones del
mismo,.
Por ejemplo, si se anade al dialogo como se ha isto anteriormente un control de tipo lista
de seleccin ,ListBox, y se ha creado una ariable de tipo Control asociado a l ,CListBox
m_lista,, no sera alido el siguiente cdigo que anade opciones a dicha lista ,er ayuda de
CListBox,:
Para solucionar este problema, cuando se deben inicializar controles se serira el eento
\M_INI1DIALOG del dialogo correspondiente: cuando se alcanza esta uncin ya existe
el dialogo y sus controles, y slo alta que se muestren en pantalla.
...
#include "CambiaFrecDlg.h" // Para que conozca a la clase del dilogo
void CEjemploView::OnMisopcionesCambiarfrecuencia()
{
// TODO: Add your command handler code here
CEjemploDoc* pDoc=GetDocument(); // Obtiene puntero al documento
CCambiaFrecDlg dlg; // Crea dilogo (no muestra an)
dlg.m_frec=pDoc->frec; // Inicializa variables del dilogo
dlg.m_lista.AddString("Opcion 1"); // INCORRECTO: aunque compila bien
dlg.m_lista.AddString("Opcion 2"); // falla en tiempo de ejecucin porque
dlg.m_lista.AddString("Opcion 3"); // no existe an el control asociado
// a m_lista
if (dlg.DoModal()==IDOK) // Presenta el dilogo. Si termina con
{ // la pulsacin de OK
pDoc->frec=dlg.m_frec; // recupera las variables del dilogo
}
}
...
void CCambiaFrecDlg::OnChangeEditFrecuencia()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
UpdateData(TRUE); // m_frec contiene el valor que haya en el dilogo
m_botonOK.EnableWindow(m_frec > 0); // Si m_frec > 0 habilita control OK,
// si m_frec <=0 lo deshabilita.
}
CambiaFrecDlg.cpp
CEjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
36
Si la inicializacin de estos controles es dependiente de alores del documento o de la ista,
se crearan de orma manual ariables en el dialogo que apunten a dichos alores. Lstas
ariables s pueden ser inicializadas antes de la llamada a DoModal,,, y por tanto estaran
disponibles en OnInitDialog,, para inicializar los controles.
4.3.4.6 Cuadros de dilogo predefinidos
Lxisten una serie de cuadros de dialogo que ya implementan uncionalidades tpicas
necesarias en muchos programas, por lo que no es necesario crear el dialogo para estos
casos: simplemente sera necesario el paso de creacin del objeto y llamada a DoModal,,
indicado en 4.3.4.3.
Los cuadros de dialogo predeinidos derian de CCommonDialog. Los mas utilizados son
,er ayuda para cada uno,:
ClileDialog para la seleccin de un archio dentro del entorno de unidades y
carpetas.
ClontDialog para la seleccin de una uente de texto.
CColorDialog para la seleccin de un color.
ClindReplaceDialog para la bsqueda y reemplazo de texto en el documento.
CPageSetupDialog y CPrintDialog para la impresin.
4.3.5 Eventos temporizados
Dentro de los eentos que puede recibir una entana ,en nuestro caso CLjemploView,,
uno de los mas interesantes es el eento de temporizacin. Un temporizador permite
generar un eento a interalos regulares, lo cual puede ser utilizado por una aplicacin para
ejecutar cdigo temporizado, para diidir una operacin larga en otras mas cortas mientras
se pueden serir otros eentos, etc.
Para ello, se crea un temporizador con Set1imer,,, se debe serir el eento \M_1IMLR
de la entana, y se termina el temporizador con Kill1imer,,.
Para ilustrarlo, anadimos una opcin de men a la ista que permita llamar a la uncin
calculo cada, por ejemplo, 0.1 segundos.
Los pasos seran:
1, Anadir opcin Iniciar auto` con el editor de recursos de men, crear con
Class\izard una uncin en la clase ista que sira a esta nuea opcin, y editar el
cdigo de la misma. Ln este cdigo iniciamos un temporizador de 0.1 segundos
,100 milisegundos, que llee el identiicador 1500 ,por ejemplo,.
2, Anadir en Class\izard una uncin On1imer,, para serir el eento \M_1IMLR
de la clase ista. Ln el cdigo de esta uncin se llama a la uncin CalculaNueo,,
del documento.
void CCambiaFrecDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_lista.AddString("Opcin 1");
m_lista.AddString("Opcin 2");
m_lista.AddString("Opcin 3");
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
CambiaFrecDlg.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
3
3, Anadir opcin lin auto` con el editor de recursos de men, crear con
Class\izard una uncin en la clase ista que sira a esta nuea opcin, y editar el
cdigo de la misma. Ln este cdigo paramos el temporizador.
4.3.S.J Lvitando el parpadeo
Un eecto indeseado al redibujar, que aparece especialmente con los eentos temporizados,
es el hecho de que, por deecto, la entana se borra completamente y se redibuja completa
en cada eento de repintado. Lsto hace que, cuando el n de elementos a dibujar en la
entana es grande, se produzca un indeseado de parpadeo.
Lxisten diersas ormas de eitar el parpadeo, de las cuales destacamos dos:
lacer que en el repintado se actualice nicamente una zona de la entana. La
uncin Redraw\indow,, acepta arios parametros ,hemos utilizado hasta ahora
sus alores por deecto,, entre los cuales el 1 es el rectangulo que se quiere
actualizar. Si esta opcin es NULL ,por deecto, se actualiza toda la entana. Si
cambiamos los parametros de la llamada a Redraw\indow,, en la uncin de
sericio del temporizador, de orma que slo se actualice la parte de entana
correspondiente a la nuea zona a dibujar, se elimina el eecto parpadeo ,dejamos
sin actualizar la zona correspondiente al texto de n de dato para que se ea el
eecto: esta zona no se actualiza salo cuando, por ejemplo, minimizamos y
olemos a restaurar la entana, en cuyo caso la uncin OnDraw,, ha sido llamada
para toda la entana,.
...
void CEjemploView::OnMisopcionesIniciarauto()
{
// TODO: Add your command handler code here
SetTimer(1500,100,NULL);
}
void CEjemploView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CEjemploDoc* pDoc=GetDocument();
pDoc->CalcNuevoDato();
RedrawWindow();
CView::OnTimer(nIDEvent);
}
void CEjemploView::OnMisopcionesPararauto()
{
// TODO: Add your command handler code here
KillTimer(1500);
}
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
38
La posibilidad anterior elimina el parpadeo, pero an se ejecutaran todas las
rdenes de OnDraw,, cada ez que se llame a Redraw\indow,, aunque solo se
actualice la zona indicada en el rectangulo. Otra opcin puede ser crear un contexto
de dispositio temporal y dibujar sobre l la parte a actualizar, dejando en
OnDraw,, el trabajo para cuando hay que redibujar todo. Ln este caso, el cdigo
sera:
Importante notar que, en cualquiera de las 2 opciones, es necesario saber cmo a a hacer
OnDraw,, el trabajo para seleccionar la zona correcta o dibujar en el sitio adecuado. Por
ello, es importante hacer unciones auxiliares ,crear manualmente su prototipo en
CLjemploView.h y escribir manualmente el cdigo en CLjemploView.cpp, nicas para
asegurar que en todos los casos se dibuja lo mismo.
...
void CEjemploView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CEjemploDoc* pDoc=GetDocument();
pDoc->CalcNuevoDato();
CDC* pDC=GetDC();
CPen pen(PS_SOLID,2,RGB(255,0,0)),*aPen;
aPen=(CPen*) pDC->SelectObject(&pen);
if (pDoc->nDatos >= 2)
{
pDC->MoveTo(pDoc->datosX[pDoc->nDatos-2],300+pDoc->datosY[pDoc->nDatos-2]);
pDC->LineTo(pDoc->datosX[pDoc->nDatos-1],300+pDoc->datosY[pDoc->nDatos-1]);
}
pDC->SelectObject(aPen);
pen.DeleteObject();
ReleaseDC(pDC);
CView::OnTimer(nIDEvent);
}
...
void CEjemploView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CEjemploDoc* pDoc=GetDocument();
pDoc->CalcNuevoDato();
int minY,maxY;
minY=__min(pDoc->datosY[pDoc->nDatos-2],pDoc->datosY[pDoc->nDatos-1]);
maxY=__max(pDoc->datosY[pDoc->nDatos-2],pDoc->datosY[pDoc->nDatos-1]);
CRect r(pDoc->datosX[pDoc->nDatos-2]-1,300+minY-1,
pDoc->datosX[pDoc->nDatos-1]+1,300+maxY+1);
RedrawWindow(&r);
CView::OnTimer(nIDEvent);
}
EjemploView.cpp
EjemploView.cpp
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
39
4.4 Programando aplicaciones MDI y basadas en dilogo
A partir de lo isto anteriormente es sencillo pasar a programar aplicaciones con otros
aspectos, como las de mltiples documentos ,MDI,, las basadas en cuadro de dialogo, o las
basadas en istas especiales.
Para una aplicacin MDI se dispondra de mltiples objetos documento y ista, que
pueden pertenecer a la misma o distintas clases, pero el uncionamiento es muy
similar para cada uno. Cuando se cambia el contenido del documento se suele
llamar a UpdateAllViews,, en lugar de Redraw\indow,, para que se actualicen
todas las istas.
Una aplicacin basada en dialogo se programa igual que el cuadro de dialogo que se
ha isto en 4.3.4 y siguientes. 1odos los datos son almacenados en la clase deriada
de CDialog, y normalmente no se anade ninguna uncionalidad de dibujo propia,
sino que se utiliza el comportamiento por deecto de los controles. Se dispone
ademas de una uncin OnIntialUpdate,, en la que se inicializa todo.
1ambin es posible crear aplicaciones SDI o MDI que incluyan istas con
uncionalidades especicas: CScrollView para una ista con barra de
desplazamiento, ClormView para una ista en la que se pueden insertar controles,
CLditView para una ista en la que se puede editar texto, etc. Para ello, se
selecciona la clase base de la ista en el ltimo paso de la creacin del proyecto ,er
igura en pagina 18,, y se debe consultar la ayuda de la clase deseada para utilizar su
uncionalidad adicional.
4.5 Utilizar hilos de procesamiento
Cuando se debe realizar un procesamiento largo, durante el tiempo que ste dure la
aplicacin no estara en disposicin de recibir y procesar otros eentos, y por tanto no
recibe entradas de usuario, no se redibuja, etc.
Para eitar esto, se puede lanzar el procesamiento en un 2 hilo de ejecucin. Lste hilo se
ejecuta de orma concurrente con el principal, de orma que el tiempo de procesador es
diidido entre ambos: el hilo principal contina siriendo eentos del usuario, mientras que
el secundario a procesando lo que se desee. Ls \indows quien decide qu tiempo a
concediendo a cada uno, sin bloquear ninguno de los dos.
Para crear un 2 hilo utilizar la uncin Create1hread,,. Ver ayuda para la orma de uso de
esta uncin. Un ejemplo para crear un hilo que tenga acceso al documento:
UNIVLRSIDAD DL OVILDO
Departamento de Ingeniera Llctrica,
Llectrnica, de Computadores y Sistemas
40
...
DWORD WINAPI FuncionLarga (LPVOID lpParameter)
{
CEjemploDoc* pDoc=(CEjemploDoc*) lpParameter;
// Procesamiento
...
return valor;
}
void CEjemploView::OnLanzarFuncionLarga()
{
// TODO: Add your message handler code here and/or call default
CEjemploDoc* pDoc=GetDocument();
DWORD id;
if (CreateThread(NULL,65536,FuncionLarga,(LPVOID) pDoc,0,&id)==NULL)
{
MessageBox("No puedo lanzar funcin larga");
Return;
}
// El hilo ha sido lanzado: se ejecuta FuncionLarga de forma concurrente al
// bucle de mensajes del hilo principal
}
EjemploView.cpp

You might also like