
...el poder de lo simple...
Abril.14.2010
Aplicacion
dirigida
por eventos con interfaz gráfica
Qué es una aplicación
Lote, Batch
o de Consola ?
Es una aplicación formada por un solo algoritmo que comanda la
secuencia de acciones del computador. En ella están prescritas el tipo
y el momento en que deben ocurrir acciones externas para proporcionar
datos a la aplicación. El agente externo con el que interactúa,
generalmente un usuario final, no tiene más que atender los
requerimientos del programa en el orden y tipos exigidos. El programa
es un dictador que no admite que el usuario tome la iniciativa. Al
ejecutarse efectúa las instrucciones prescritas y termina.
Qués es una aplicación
dirigida
por eventos ?
Es una aplicación que permanece abierta espectante a acciones externas
y ante las cuales reacciona en consecuencia. Las acciones externas son
conocidas como eventos. Generalmente los eventos los desencadena un
usuario final al manipular la interfaz gráfica de la aplicación. Las
ocurrencias de los eventos son establecidos por el agente externo a la
aplicación o usuario en el
momento que lo desee y el tipo que quiera debe existir entre
los tipos de eventos previstos por el
programador. Es una gran diferencia con
las aplicaciones batch donde tanto el tipo de evento y el momento se su ocurrencia
son establecidos por el
programador pues es él quien en el único algoritmo ordena cuando deben
ocurrir los
eventos y de cual tipo.
En
una aplicación orientada por eventos el programador establece los tipos
de eventos que permitirá escuchar la aplicación y diseña los
correspondientes algoritmos que los atenderán o que reaccionarán ante
su ocurrencia. Tales algoritmos son conocidos como controladores
o manejadores
de eventos pues su función es generar una consecuencia o reacción ante
la ocurrencia de un evento en particular activado en el entorno.
Entonces una aplicación bajo ésta modalidad estará formada por muchos
algoritmos especializados en funciones particulares que serán
ejecutados en el momento necesario generalmente como reacción a las
iniciativas del usuario. La aplicación inicia pero no termina
automáticamente sino por la voluntad del usuario generalmente. Ella al
iniciar su funcionamiento queda espectante a las acciones del usuario o
del entorno.
Manejo de eventos en una aplicación
Cómo lograr facilmente incorporar la infraestructura de la plataforma
para el manejo de eventos en una aplicación ?
Se puede hacer creando una clase que represente la aplicación y heredando la
infraestructura ya programada en la clase Form de la
plataforma .NET
Debido a que las máquinas físicas son únicas en una instalación pero
son usadas por varias aplicaciones es necesaria la coordinación de su
uso. Ésta función la desempeña el Sistema Operativo encargándose de
detectar las acciones externas en cuanto a tipo, momento de ocurrencia
y destinatario. Luego envía el mensaje apropiado a la cola de mensajes
de la aplicación destinataria para que ella los vaya tomando de allí y
los vaya procesando. Lo anterior significa que en un ambiente de
multiprogramación, donde están corriendo varios programas, se forma
entre el Sistema Operativo y las aplicaciones un diálogo de intercambio
de datos.
La creación y disparo de eventos puede ocurrir en cualquier aplicación.
Miraremos primero, por ser lo fundamental, una forma de atender
mensajes enviados por el Sistema Operativo ante la presencia de los
principales eventos ocurridos en la máquina física.
Un evento es un suceso que ocurre en el entorno donde
funciona una aplicación y para su atención se debe programar
en ella un método
que controle las acciones necesarias para responderle a cada tipo de evento
que se necesite. A diferencia de la programación secuencial, batch por
lotes o tipo consola (en la que el programador exige una secuencia
estricta de aparición de los eventos), no se sabe cual será el orden de
aparición de ellos pues normalmente son el usuario o el sistema
operativo quienes los generan según su intención y
necesidades. La aplicación debe adoptar, entonces, la forma de
intérprete o de máquina
de estados para que esté atenta a reaccionar según sea el
caso. En éste tipo de aplicaciones es el usuario quien toma la
iniciativa. Cuando se ejecuta la aplicación (se ejecuta su método constructor) queda
espectante a lo que pueda ocurrir en su entorno y reaccionar ejecutando
el método apropiado
que debe haber sido programado para ello.
El sistema operativo ya existe pero debe invocar
un método
(enviar un mensaje
a la aplicación) que solo ahora la persona programa.
Recuérdese la forma de enviar un mensaje a un
objeto, es decir ordenarle al objeto ejecute uno de sus
algoritmos o métodos
en particular:
Objeto.AlgoritmoSinArgumentos
o
Objeto.Algoritmo(lista
de argumentos separados con comas)
Primero haga la siguiente reflexión: El Sistema Operativo fue
construido hace años, nuestra aplicación solo ahora: Cómo hacer que se
comuniquen si el primero "no sabe"
cómo se llaman nuestros algoritmos
o métodos que
debe echar a andar para atender los respectivos eventos ?
Se logra así:
En el Sistema Operativo se establece un protocolo
de comunicación y en la aplicación se usa ese protocolo.
1. El Sistema Operativo detecta la ocurrencia del evento
2. El Sistema Operativo detecta que viene dirigido a nuestra aplicación
(digamos que es Mi Clase)
3. El Sistema Operativo envía un mensaje con los detalles
del evento: Mi Clase.Nombre_del_método(doy
tal,
doy Pascual)
4. El mensaje queda en la cola de mensajes de nuestra aplicación en
espera de ser atendido
Por ello el programador debe hacer dos cosa cada que
desee que la aplicación atienda, controle o maneje un tipo de evento en
particular:
1. Elaborar el método o
algoritmo (mensaje
que la aplicación entenderá) que se ejecutará ante la
aparición de un tipo de evento .
2. Inscribir ese método
como un controlador o manejador
dentro de la aplicación para que el
sistema operativo sepa qué invocar.
Para lo primero debe seguirse un protocolo o firma
del método
que case con lo que ya existe programado en el Sistema Operativo.
Constará de un nombre y dos parámetros de entrada pues él enviará
información a la aplicación sobre el control en el que ocurrió
el evento y un
paquete con datos relevantes a ese tipo de evento. La
forma de los métodos manejadores de eventos será, entonces:
Nombre_del_método(deme
NC, deme detalles es un TipoDeArgumentosDeEvento)
{
/* ...aquí irá la lógica del control y puede utilizar la
información enviada en detalles por el Sistema Operativo....
(el TipoDeArgumentosDeEvento
que se recibe varía dependiendo del tipo de evento) */
}
Para lo segundo, debe instruir al Sistema Operativo
sobre el control donde interesa la
ocurrencia del evento, el tipo
de evento y el
método que lo atenderá, mediante el uso del
método Lexico llamado manejador,
así por ejemplo cuando exista el botón BOT en la
aplicación Mi Clase y se desee atender el evento Click con el
algoritmo MiAlgoritmo
se programará en su constructor:
Mi Clase .manejador(BOT.
Click, MiAlgoritmo)
Hay muchos eventos ya reconocidos por el sistema
operativo y quizás los más utilizados sean:
Paint :
Pintura se genera cada vez que el S.O. detecta la necesidad de
restaurar la imagen de un formulario
KeyDown :
TeclaPresionada por el usuario (o simulada por algún programa)
MouseDown
: Un botón del ratón ha sido presionado
(o simulado).
Tick :
Un temporizador ha generado un aviso o alarma
MouseUp :
Un botón del ratón ha sido liberado (o simulado).
MouseMove :
El ratón ha sido movido (o simulado).
Click
:
Se ha pulsado con un botón del ratón sobre un control.
...
|
Recuerde para cada tipo de evento que
quiera controlar:
1. Utilizar el siguiente protocolo cada vez que vaya a
programar un algoritmo controlador o manejador
de un tipo de evento:
Nombre_del_algoritmo_manejador(deme
Dónde_ocurrió_el_evento,
deme detalles_del_evento
es un TipoDeArgumentosDeEvento)
{
.....aquí irá
la lógica que reacciona, controla o maneja el evento
}
2. Registrar ante el
sistema operativo en el algoritmo constructor de la clase el Nombre_del_algoritmo_manejador que haya establecido
para reacionar, controlar o manejar un tipo de evento:
Mi Clase .manejador(Objeto_donde_el_evento_se_controlará. Tipo_de_evento, Nombre_del_algoritmo_manejador)
(antes recuerde
Cómo hacer una clase ?)
Un ejemplo:
Se controlará con el
algoritmo mi_controlador_de_teclado el tipo de evento KeyDown cuando ocurra en la
aplicación ventana, se recibirá del Sistema
Operativo un objeto que llamaremos chismoso y trae
los detalles del evento que, en éste caso, es del tipo KeyEventArgs.
El control simplemente será mostrar cuando hayan pulsado una de las 7
teclas A B 1 2 Flech-dereca Flecha-izquierda Esc:
clase
ventana
derivada_de
Form
{
publicos:
mensajes:
mi_controlador_de_teclado(entra
objeto_enviador, entra
chismoso
es un
KeyEventArgs)
{
es
chismoso.KeyCode=Keys.A
? si: muestre "Pulsada la tecla A"
es
chismoso.KeyCode=Keys.B
? si: muestre "Pulsada la tecla B"
es
chismoso.KeyCode=Keys.D1
? si: muestre "Pulsada la tecla 1"
es
chismoso.KeyCode=Keys.D2
? si: muestre "Pulsada la tecla 2"
es
chismoso.KeyCode=Keys.Right
? si: muestre "Pulsada Flecha Derecha"
es
chismoso.KeyCode=Keys.Left
? si: muestre "Pulsada Flecha Izquierda"
es
chismoso.KeyCode=Keys.Escape
?
si: {
muestre
"Pulsada la tecla Esc ==> cerraré la aplicación"
ventana.Close
}
}
ventana
{
copie " Mi quinta ventana" en
ventana.Text
ventana.
manejador(sale
ventana.
KeyDown,
sale
mi_controlador_de_teclado)
}
}
Ejemplo:
Cómo manejar el evento Paint
(pintura) ?
/*
Mob122_ControlEventoPaint.lx */
clase ventana derivada_de
Form
publicos:
el objeto graficador es un Graphics
no_crear
el objeto lápiz es un Pen(doy
Color.Green, doy 2)
el objeto pincel es un SolidBrush(sale
Color.Blue)
el objeto pincel2 es un SolidBrush(sale
Color.White)
el objeto tipo_de_letra es un Font(sale
"Verdana", sale 20, FontStyle.Regular)
mensajes:
mi_controlador_de_pintura(entra
objeto_enviador, entra chismoso es un
PaintEventArgs)
{
copie chismoso.Graphics en graficador
/* Aquí se programan
las acciones pictóricas necesarias */
graficador.DrawLine(doy lápiz, doy 20,
doy 30, doy 77, doy 88)
graficador.DrawString( sale "Hola
amigos", sale tipo_de_letra, sale pincel, sale 22, sale 62 )
graficador.DrawString( sale "Hola
amigos", sale tipo_de_letra, sale pincel2, sale 20, sale 60 )
}
ventana
{
copie " Mi segunda ventana" en
ventana.Text
ventana.manejador(sale "
ventana.
Paint",
sale "
mi_controlador_de_pintura")
}
Ejemplo:
Cómo reaccionar frente al evento MouseDown
?
clase
ventana derivada_de
Form
{
publicos:
mensajes:
mi_controlador_de_raton(entra
objeto_enviador, entra chismoso es un
MouseEventArgs)
{
es chismoso.Button=MouseButtons.Left ? si: muestre "Pulsado el botón
izquierdo"
es chismoso.Button=MouseButtons.Right ? si: muestre "Pulsadael botón
derecho"
es chismoso.Button=MouseButtons.Middle ? si: muestre "Pulsada el botón
central"
}
ventana
{
copie " Mi sexta ventana" en ventana.Text
ventana.manejador(sale "
ventana.
MouseDown",
sale "
mi_controlador_de_raton")
}
}
Ejemplo:
Cómo controlar el evento Tick
de un temporizador ?
clase
ventana derivada_de
Form
{
publicos:
el objeto
temporizador
es un Timer
mensajes:
mi_controlador_de_temporizador(entra
objeto_enviador, entra chismoso es
un EventArgs)
{
muestre "Ya fuí avisado por el temporizador"
copie falso en
temporizador.
Enabled
ventana.Close
}
ventana
{
copie " Mi séptima ventana" en ventana.Text
ventana.manejador(sale "
temporizador.
Tick",
sale "
mi_controlador_de_temporizador")
copie 5000 en
temporizador.Interval
copie verdadero en
temporizador.Enabled
}
}
Ejemplo:
Cómo controlar el evento Click
de un botón
?
clase
Botarchi derivada_de
Form
publicos
el objeto
botón
es un
Button
mensajes
Botarchi
{
Botarchi.manejador(
botón.
Click,
creararchivo)
Botarchi.AgregarControl(
botón)
}
creararchivo(deme
nn, deme chisme es un EventArgs)
{
el objeto archisalida es un StreamWriter("ArchivoTexto.txt")
archisalida.WriteLine("Línea 1")
archisalida.WriteLine("Línea 2")
archisalida.WriteLine("Línea 3")
archisalida.Close
System.Diagnostics.Process.Start("ArchivoTexto.txt", "")
}
Ejemplo:
Cómo programar en Lexico un Skin (piel, máscara o fachada) ?
clase
skin derivada_de
Form
publicos
el objeto boton es un Button
el objeto pincel es un SolidBrush(doy Color.Blue)
mensajes
pulsado(deme
nn, deme detalles es un EventArgs)
{
muestre "Cliqueado el botón, ciao...."
skin.Close
}
skin
{
copie "Salir" en boton.Text
copie Color.Yellow en boton.BackColor
skin.AgregarControl(doy boton)
skin.manejador(doy
boton.Click,
doy
pulsado)
copie Color.Peru en skin.
BackColor
copie Color.Peru en skin.
TransparencyKey
el objeto fondo es un Bitmap(doy "transparente.PNG")
fondo.
MakeTransparent
copie fondo en skin.
BackgroundImage
copie
FormBorderStyle.
None en skin.
FormBorderStyle
}
Ejemplo:
Cómo agregar un menú
a una ventana clásica ?
clase
Editor derivada_de
Form
privados:
el objeto
menu
es un
MainMenu
los objetos archivo, edicion, proceso, ayuda son
MenuItem
el objeto salir es un MenuItem
publicos:
mensajes:
Editor
{
copie "EL" en Editor.text
copie "&Archivo" en archivo.Text
menu.MenuItems.Add(archivo)
copie "&Edición" en edicion.Text
menu.MenuItems.Add(edicion)
copie "&Proceso" en proceso.Text
menu.MenuItems.Add(proceso)
copie "&Ayuda" en ayuda.Text
menu.MenuItems.Add(ayuda)
copie menu en Editor.menu
Editor.manejador("
archivo.
Click",
"
clic_archivo")
Editor.manejador("
edicion.
Click",
"
clic_edicion")
Editor.manejador("
proceso.
Click",
"
clic_proceso")
Editor.manejador("
ayuda.
Click",
"
clic_ayuda")
}
clic_archivo(entra
enviador, entra ch es un EventArgs)
{
muestre "archivo"
}
clic_edicion(entra
enviador, entra e es un EventArgs)
{
muestre "edicion"
}
clic_proceso(entra
enviador, entra e es un EventArgs)
{
muestre "proceso"
}
clic_ayuda(entra
enviador, entra e es un EventArgs)
{
muestre "ayuda"
}
Ejemplo:
Cómo animar un rectángulo ?
clase
ventana derivada_de
Form
publicos:
el objeto temporizador es un Timer
el objeto x es una cantidad
mensajes:
mi_controlador_de_temporizador(entra
objeto_enviador, entra chismoso es
un EventArgs)
{
copie x + 1 en x
ventana.Refresh
}
mi_controlador_de_pintura(entra
objeto_enviador, entra chismoso es un
PaintEventArgs)
{
el objeto g es un Graphics no_crear
copie chismoso.Graphics en g
el objeto crayola es un Pen(sale color.Gray, sale 2)
g.DrawRectangle(sale crayola, sale x, sale 10, sale 40, sale 20)
}
ventana
{
copie " Temporizador" en ventana.Text
ventana.manejador(sale "
temporizador.
Tick",
sale "
mi_controlador_de_temporizador")
ventana.manejador(sale "
ventana.
Paint",
sale "
mi_controlador_de_pintura")
copie verdadero en temporizador.Enabled
copie 0 en x
}
Ejemplo:
Cómo generar un movimiento oscilatorio ?
clase
ventana derivada_de
Form
publicos:
el objeto temporizador es un Timer
los objetos x, ancho_del_recorrido son cantidades
el objeto sentido es un caracter
mensajes:
mi_controlador_de_temporizador(entra
objeto_enviador, entra chismoso es
un EventArgs)
{
es sentido="derecho" ?
si: es x<ancho_del_recorrido ?
si: copie x + 1 en x
no:copie
"izquierdo" en sentido
no: es x>0 ?
si: copie x-1 en x
no:copie "derecho" en sentido
ventana.Refresh
}
mi_controlador_de_pintura(entra
objeto_enviador, entra chismoso es un
PaintEventArgs)
{
el objeto g es un Graphics no_crear
copie chismoso.Graphics en g
el objeto crayola es un Pen(sale color.Gray, sale 2)
g.DrawRectangle(sale crayola, sale x, sale 10, sale 40, sale 20)
}
ventana
{
copie " Temporizador" en ventana.Text
ventana.manejador(sale "
temporizador.
Tick",
sale "
mi_controlador_de_temporizador")
ventana.manejador(sale "
ventana.
Paint",
sale "
mi_controlador_de_pintura")
copie verdadero en temporizador.Enabled
copie 0 en x
copie 80 en ancho_del_recorrido
copie "derecho" en sentido
}
Ejemplo:
Cómo crear un trazo con el ratón ? (corre tambien sobre Windows Mobile)
clase
trazador derivada_de system.windows.forms.
Form
publicos:
los objetos GX, GY son Collections.
ArrayList
el objeto l es un Pen(Color.Blue, 2)
los objetos i, x, y son cantidades
mensajes:
trazador
{
copie "trazador" en trazador.text
trazador.Manejador("
trazador.
Paint",
"
pintura")
trazador.Manejador("
trazador.
MouseDown",
"
ratón")
}
/**********************************************/
pintura(deme
nn, deme ch es un PaintEventArgs)
variando i desde 0 hasta GX.Count-1 haga:
ch.Graphics.DrawEllipse(l,
System.Convert.ToInt32(GX[i]), System.Convert.ToInt32(GY[i]), 3, 3)
ratón(deme
nn, deme ch es un MouseEventArgs)
{
GX.Add(ch.X)
GY.Add(ch.Y)
trazador.Refresh
}
Ejemplo:
Cómo minimizar una ventana ?
clase v
derivada_de
Form
publicos
mensajes
teclas(entra
nn, entra ch es un KeyEventArgs)
{
es ch.KeyCode=Keys.Escape ? si: v.Close
es ch.KeyCode=Keys.Down ?
si: {
muestre "OJO: minimizará"
copie FormWindowState.Minimized en v.WindowState
}
}
v {
copie "
========> Use la Flecha Hacia abajo y Esc"
en v.Text
v.manejador(doy "
v.
KeyDown",
doy "
teclas")
}
Ejemplo:
Cómo manipular características de ventana ?
Ejemplo:
Cómo maximizar una ventana y conocer tamaños ?
/*
Con base en (Alejandro Rúa)
http://ojarami.com/riosur.net/modules.php?name=Forums&file=viewtopic&p=557#557
La clase SystemInformation entrega información sobre la
configuración del entorno del sistema actual
http://msdn.microsoft.com/es-es/library/system.windows.forms.systeminformation(VS.80).aspx
*/
clase ventana derivada_de
Form
publicos:
mensajes:
ventana {
/*Establecemos el estado inicial de la ventana
como maximizada*/
copie FormWindowState.maximized en
ventana.WindowState
/*Obtenemos la resolución actual del monitor*/
muestre
"# monitores= ", SystemInformation.MonitorCount,
"\nAncho monitor= ", SystemInformation.PrimaryMonitorSize.Width,
"\nAlto monitor= ",
SystemInformation.PrimaryMonitorSize.Height,
"\nAncho ventana maximizada= ",
SystemInformation.PrimaryMonitorMaximizedWindowSize.Width,
"\nAlto ventana maximizada= ",
SystemInformation.PrimaryMonitorMaximizedWindowSize.Height
}
Ejemplo:
Cómo abrir una segunda ventana transparente para ayudas ?
/*
Con base en
http://ojarami.com/riosur.net/modules.php?name=Forums&file=viewtopic&p=1300#1300
*/
clase a derivada_de
Form
publicos
el objeto p es una SolidBrush(doy Color.Green)
el objeto f es una Font(doy "Arial", doy 20)
el objeto op es una cantidad
mensajes
pintura(deme
nn, deme ch es un PaintEventArgs)
{
ch.Graphics.DrawString(doy "haga varios Clicks aquí", doy f, doy p, doy
20, doy 20)
}
suba (deme
nn, deme ch es un MouseEventArgs)
{
copie op+5 en op
copie op/100 en a.Opacity
}
a
{
copie "Clicks en el área de usuario" en a.Text
a.manejador(doy "
a.
Paint",doy
"
pintura")
a.manejador(doy "
a.
MouseDown",doy
"
suba")
copie 15 en op
copie op/100 en a.Opacity
copie Color.Yellow en a.BackColor
copie FormWindowState.maximized en a.windowState
}
/****************************************/
clase aplicación derivada_de
Form
publicos
el objeto b es un Button
mensajes
aplicación
{
copie "Click en Botón para ayuda" en aplicación.Text
copie "Ayuda" en b.Text
aplicación.AgregarControl(b)
aplicación.Manejador(
b.
Click,
abrir_ayuda)
}
abrir_ayuda(deme
xx, deme det es un EventArgs)
{
el objeto ayuda es un a
ayuda.Show
}
Ejemplo:
Cómo colocar N etiquetas ?
clase
ventana derivada_de
Form
publicos:
mensajes:
ventana
{
el objeto N es una cantidad
entre N
copie N.DemeCaracteres # " etiquetas !" en ventana.Text
el objeto i es una cantidad
variando i desde 1 hasta N haga
{
el objeto e es un Label
ventana.agregarcontrol(e)
copie i.DemeCaracteres en e.Text
el objeto sitio es un Point(10, 25*i)
copie sitio en e.Location
}
muestre "El ArrayList Controls tiene ", ventana.Controls.Count, "
controles"
}
Ejemplo:
Cómo controlar el evento Click
en N
botones ?
clase
ventana derivada_de
Form
publicos:
mensajes:
ventana
{
el objeto N es una cantidad
entre N
copie N.DemeCaracteres # " botones !" en ventana.Text
el objeto i es una cantidad
es N<27 ? si:
variando i desde 1 hasta N haga
{
el objeto e es un Button
ventana.agregarcontrol(e)
copie i.DemeCaracteres en e.Text
el objeto sitio es un Point(10, 25*i)
copie sitio en e.Location
copie Color.FromArgb(255, 0, 0,
10*(i-1)) en e.BackColor
copie Color.Yellow en e.ForeColor
ventana.manejador(
e.
Click,
lePegaron)
}
muestre "El ArrayList Controls tiene ", ventana.Controls.Count, "
controles"
}
lePegaron(deme
nombreControl,
deme chisme es un EventArgs)
{
muestre "Le pegaron al ",
nombreControl.
ToString
}
Ejemplo:
Cómo conocer la hora ?
/*
http://msdn.microsoft.com/es-es/library/system.datetime(VS.80).aspx
*/
clase ventana derivada_de
Form
publicos:
el objeto segundos es una cantidad
el objeto t es un Timer
mensajes:
ventana
{
ventana.manejador(
t.
Tick,
ya)
copie 1000 en t.Interval
t.Start
}
ya(deme
xx, deme yy es un EventArgs)
{
copie DateTime.Now.Second en segundos
copie DateTime.Now.ToString en ventana.Text
copie ventana.Text # " --> " # DateTime.Now.Second.ToString #
"=" # segundos.DemeCaracteres en ventana.Text
}
Ejemplo:
Cómo validar (no admitir entrada numérica) ?
Ejemplo:
Cómo utilizar ícono y cursor ?
/*
http://ojarami.com/riosur.net/modules.php?name=Forums&file=viewtopic&p=309#309
*/
clase v derivada_de
Form
publicos
el objeto ic es un Icon(sale "C:\\Archivos de
programa\\riosur-junio-15-2009\\riosur\\iconos\\lx.ico")
el objeto icur es un Cursor(sale "C:\\WINDOWS\\Cursors\\pen_i.cur")
el objeto g es un Graphics no_crear
mensajes:
pinte(entra
Q, entra CH es un PaintEventArgs)
{
copie CH.Graphics en g
g.DrawIcon(sale ic, sale 100, sale 200)
}
v
{
v.manejador(sale
v.
Paint,
sale
pinte)
copie ic en v.Icon
copie icur en v.Cursor
}
Ejemplo:
Cómo suprimir parpadeo utilizando un PictureBox ?
clase
ventana derivada_de
Form
publicos:
los objetos grupoX, grupoY son ArrayList
los objetos i, x, y, ancho son cantidades
el objeto lápiz es un Pen (doy Color.Black)
el objeto graficador es un Graphics no_crear
el objeto bitmap es un Bitmap(sale 1024, sale 768)
el objeto BMPgraficador es un Graphics no_crear
el
objeto cuadro es un
PictureBox
/*NUEVO*/
mensajes:
algoritmo_pintura(entra
E, entra chismoso es un PaintEventArgs)
{
copie chismoso.Graphics en graficador
graficador.DrawImage(sale bitmap, sale 0, sale 0)
}
algoritmo_movido_raton(entra
E, entra chismoso es un MouseEventArgs)
{
copie chismoso.X-10
en x
copie chismoso.Y-30
en y
grupoX.RemoveAt(doy
0)
grupoY.RemoveAt(doy
0)
grupoX.Add(doy x)
grupoY.Add(doy y)
BMPgraficador.Clear(sale color.White)
variando i desde 0 hasta grupoX.Count-1 haga:
{
copie 2*i en ancho
copie grupoX[i] en x
copie grupoY[i] en y
BMPgraficador.DrawEllipse(sale lápiz, sale x, sale y, sale ancho, sale
ancho)
}
copie bitmap en
cuadro.Image
/*NUEVO*/
ventana.Refresh
}
ventana
{
copie " mover el
mouse" en ventana.Text
ventana.manejador(sale "
ventana.
Paint",
sale "
algoritmo_pintura")
ventana.manejador(sale "
cuadro.
MouseMove",
sale "
algoritmo_movido_raton")/*NUEVO*/
variando i desde 0
hasta 50 haga:
{
grupoX.Add(doy i)
grupoY.Add(doy i)
}
el objeto tamaño es un Size(doy 1024, doy
768)
/*NUEVO*/
copie tamaño en
cuadro.Size
/*NUEVO*/
ventana.AgregarControl(sale
"cuadro")
/*NUEVO*/
copie
Graphics.FromImage(sale bitmap) en BMPgraficador
}
Ejemplo:
Cómo programar persistencia de objetos ?
/*
http://msdn.microsoft.com/es-co/library/ms229335(VS.80).aspx
*/
clase figura
{
privados
los objetos x, y, Id son cantidades
/*el objeto color es un System.Drawing.Color */
el objeto lápiz es un System.Drawing.Pen(doy color.Black)
el objeto pincel es un System.Drawing.SolidBrush(doy color.Black)
el objeto letra es un System.Drawing.Font(doy "Arial", doy 12,
FontStyle.Regular)
el objeto nombre es un caracteres
publicos
mensajes
figura(deme xe, deme ye, deme num)
{
copie xe en x
copie ye en y
copie num en Id
copie Id.DemeCaracteres en nombre
}
figura nop
píntese(deme g es un System.Drawing.Graphics)
{
g.DrawRectangle(doy lápiz, doy x, doy y, doy 40, doy 20)
g.DrawString(doy nombre, doy letra, doy pincel, doy x, doy y)
}
deme_posicion(doy x, doy y) nop
vaya_a(deme xe, deme ye)
{
copie xe en x
copie ye en y
}
deme_sus_datos(doy x, doy y, doy Id) nop
}
/****************************************************************^^^^************/
clase ventana derivada_de
Form
{
publicos:
los objetos xfig, yfig, x_del_clic, y_del_clic, i, a, b, xt, yt, total
son cantidades
los objetos d1, d2, d3 son cantidades
el objeto con_arrastre es un caracteres
el objeto grupo es un System.Collections.ArrayList
los objetos graficador, otrog son System.Drawing.Graphics no_crear
/*el objeto color es un System.Drawing.Color */
el objeto lapiz es un System.Drawing.Pen(sale color.Black)
/*el objeto tipo_boton es una System.Windows.Forms.MouseButtons */
el objeto bitmap es un System.Drawing.Bitmap (doy 1024, doy 768)
el objeto picture es un System.Windows.Forms.PictureBox
el objeto actual es una figura no_crear
mensajes:
clic_en_boton_del_raton(entra
enviador, entra raton es un System.Windows.Forms.MouseEventArgs)
{
es raton.Button=MouseButtons.Left ?
si: variando i desde 0 hasta grupo.Count-1 haga:
{
el objeto yy es una figura no_crear
copie grupo[i] en yy
yy.deme_posicion(deme xfig, deme yfig)
es (raton.x > xfig) & (raton.x < xfig+40)
& (raton.y > yfig) & (raton.y < yfig+20)
?
si:{
copie grupo.Count en i /* ...para obligar a suspender el ciclo pues ya
sabe cual figura es */
copie yy en actual
copie "si" en con_arrastre
copie raton.x - xfig en x_del_clic
copie raton.y - yfig en y_del_clic
}
}
es raton.Button=MouseButtons.Right ?
si:{
copie raton.X en a
copie raton.Y en b
copie total + 1 en total
el objeto nuevo es una figura(doy a, doy b, doy total)
grupo.Add(doy nuevo)
}
ventana.Refresh
}
movido_el_raton(entra
enviador, entra raton es un System.Windows.Forms.MouseEventArgs)
{
es con_arrastre="si" ?
si:{
copie raton.x - x_del_clic en xfig
copie raton.y - y_del_clic en yfig
actual.vaya_a(doy xfig, doy yfig)
ventana.Refresh
}
}
soltado_el_boton_del_raton(entra
enviador, entra raton es un System.Windows.Forms.MouseEventArgs)
{
copie "no" en con_arrastre
}
pintar(entra
sender, entra chismoso es un System.Windows.Forms.PaintEventArgs)
{
/*copie chismoso.Graphics en graficador */
graficador.Clear(doy color.Yellow)
variando i desde 0 hasta grupo.Count-1 haga:
{
el objeto xx es una figura no_crear
copie grupo[i] en xx
xx.píntese(doy graficador)
}
copie bitmap en Picture.Image
}
cerrando(entra
enviador, entra ch es un System.ComponentModel.CancelEventArgs)
{
el objeto arch es un System.IO.StreamWriter(doy "Archivo con
objetos.txt")
variando i desde 0 hasta grupo.Count-1 haga:
{
el objeto ss es una figura no_crear
copie grupo[i] en ss
ss.deme_sus_datos(deme d1, deme d2, deme d3)
arch.WriteLine(doy d1)
arch.WriteLine(doy d2)
arch.WriteLine(doy d3)
}
arch.Close
}
ventana
{
copie " Clic derecho: crea nuevo rectángulo. Arrastre con click
izquierdo presionado" en ventana.text
ventana.manejador(sale "
picture.
Paint",
sale "
pintar")
ventana.manejador(sale "
picture.
MouseDown",
sale "
clic_en_boton_del_raton")
ventana.manejador(sale "
picture.
MouseMove",
sale "
movido_el_raton")
ventana.manejador(sale "
picture.
MouseUp",
sale "
soltado_el_boton_del_raton")
ventana.manejador(
ventana.
Closing,
cerrando)
copie "no" en con_arrastre
el objeto lector es un System.IO.StreamReader(doy "Archivo con
objetos.txt")
los objetos t1, t2, t3 son caracteres
mientras lector.Peek >0 haga:
{
copie lector.ReadLine en t1
copie lector.ReadLine en t2
copie lector.ReadLine en t3
copie t1.DemeCantidad en d1
copie t2.DemeCantidad en d2
copie t3.DemeCantidad en d3
el objeto hoy es una figura(doy d1, doy d2, doy d3)
grupo.Add(doy hoy)
}
lector.Close
copie grupo.Count en total
copie Graphics.FromImage(doy bitmap) en graficador
ventana.AgregarControl(Doy "picture")
el objeto tamaño es un System.Drawing.Size(doy 1024, doy 768)
copie tamaño en picture.Size
/*
EL OBJETO piopio es un "System.Diagnostics.Process"
piopio.Start(doy "Archivo con objetos.txt")
*/
}
}
Ejemplo:
Cómo detectar evento ocurrido en otras ventanas dependientes ?
clase
auxiliar derivada_de
Form
publicos
mensajes
auxiliar(deme nombre es un caracter) copie ":) soy " # nombre en
auxiliar.Text
/***********************************************************/
clase v derivada_de
Form
publicos
el objeto otra es una auxiliar("Uno")
el objeto aquella es una auxiliar("Dos")
el objeto ésta es una auxiliar("Tres")
mensajes:
v
{
copie "Soy la ventana principal" en v.Text
otra.Show aquella.Show ésta.Show
v.Manejador(
otra.
MouseDown,
avisar)
v.Manejador(
aquella.
MouseDown,
avisar)
v.Manejador(
ésta.
MouseDown,
avisar)
}
avisar(deme
nc, deme ch es un MouseEventArgs)
{
copie "punto (" # ch.X # ", " # ch.Y # ") en la otra " # nc.ToString en
v.Text
}
Ejemplo:
Cómo desplazar continuamente un grupo de varias imágenes ?
clase Di derivada_de Form
publicos:
el objeto T es una Timer
el objeto ima es un ArrayList
los objetos x0, i, ancho son cantidades
mensajes:
Di{
Di.Manejador(T.Tick, Avance)
Di.Manejador(Di.Paint, Pinte)
copie 0 en i, x0
copie 50 en ancho
/*Creo las imágenes para no usar ya existentes*/
los objetos f1, f2, f3, f4, f5 son Bitmap(ancho, 100)
los objetos g1, g2, g3, g4, g5 son Graphics no_crear
copie g1.FromImage(f1) en g1
copie g1.FromImage(f2) en g2
copie g1.FromImage(f3) en g3
copie g1.FromImage(f4) en g4
copie g1.FromImage(f5) en g5
g1.FillRectangle(Brushes.Red, 0, 0, 49, 99)
ima.Add(f1)
g2.DrawEllipse(Pens.Blue, 0, 0, 49, 99)
ima.Add(f2)
g3.FillEllipse(Brushes.Green, 0, 0, 49, 99)
ima.Add(f3)
g4.DrawRectangle(Pens.Black, 20, 20, 29, 29)
ima.Add(f4)
g5.DrawLine(Pens.Peru, 0, 0, 49, 99)
ima.Add(f5)
T.Start
}
Avance(deme cc, deme ch es un EventArgs)
{
es x0 > -ancho ?
si: copie x0 - 1 en x0
no: {ima.Add(ima[0]) ima.RemoveAt(0) copie 0 en x0}
Di.Refresh
}
Pinte(deme cc, deme ch es un PaintEventArgs)
{
variando i desde 0 hasta ima.Count-1 haga:
{
el objeto imagen es un Bitmap(1, 1)
copie ima[i] en imagen
ch.Graphics.DrawImage(imagen, x0 + i*ancho, 50)
}
}
Ejemplo:
Cómo hacer ZOOM a una colección de puntos ?
clase V derivada_de Form
Publicos
los objetos x, y, dx, dy son arraylist
los objetos punto, paso, Npasos, xc, yc, aux, i, xt, yt, dxt, dyt son cantidades
El objeto b es un Button
mensajes
V{
V.manejador(v.Paint, pinte)
V.manejador(v.MouseDown, raton)
V.manejador(b.Click, boton)
v.AgregarControl(b)
copie "ZOOM" en b.Text
copie "Mouse (LEFT: nuevo punto; RIGTH: listo !)" en v.Text
entre Npasos
}
pinte(deme cc, deme ch es un paintEventArgs )
variando i desde 0 hasta x.count-1 haga:
{
copie X[i] en xt
copie Y[i] en yt
ch.graphics.drawEllipse(pens.black, xt, yt, 1, 1)
}
raton(deme cc, deme ch es un MouseEventArgs )
{
es ch.Button=MouseButtons.left?
si: {
x.Add(ch.X)
y.Add(ch.Y)
}
no: v.calculeDeltas
v.Refresh
}
boton(deme cc, deme ch es un EventArgs )
{
v.recalcule
v.refresh
}
calculeDeltas
{
copie 0 en xc, yc
variando i desde 0 hasta x.Count-1 haga:
{
copie x[i] en xt
copie xt + xc en xc
copie y[i] en yt
copie yt + yc en yc
}
copie xc/x.count en xc
copie yc/y.count en yc
variando i desde 0 hasta x.Count-1 haga:
{
copie x[i] en xt
copie y[i] en yt
dx.add((xt - xc)/Npasos)
dy.add((yt - yc)/Npasos)
}
}
recalcule
variando i desde 0 hasta x.Count-1 haga:
{
copie x[i] en xt
copie y[i] en yt
copie dx[i] en dxt
copie xt + dxt en aux
x.removeAT(i)
x.insert(i, aux)
/* copie dyt[i] en dyt No puede aplicar indice con [] a una expresión de tipo RIOSUR.Cantidad: dyt[i] !*/
copie dy[i] en dyt
copie yt + dyt en aux
y.removeAT(i)
y.insert(i, aux)
}
Ejemplo:
Cómo simular que el usuario presionó una tecla ?
/*
Modificado de versión lx2:
http://ojarami.com/riosur.net/modules.php?name=Forums&file=viewtopic&p=1584#1584
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys(VS.71).aspx
*/
clase SendKeys01 derivada_de Form
publicos:
mensajes:
teclado(deme ee, deme paquete es un KeyEventArgs)
{
muestre "Pulsada la tecla ", paquete.KeyCode,"\n...ó... me estás engañando ?"
}
raton(deme ee, deme paquete es un MouseEventArgs)
{
SendKeys.Send(doy "a")
}
SendKeys01
{
copie "1. Pulse una tecla...2. Haga un click" en SendKeys01.text
SendKeys01.manejador(doy SendKeys01.KeyDown, doy teclado)
SendKeys01.manejador(doy SendKeys01.MouseDown, doy raton)
}
Ejemplo:
Cómo simular una colisión con ángulo de incidencia ?
clase dir derivada_de Form
publicos:
los objetos x, y, alfa, velocidad, radianes, límite son cantidades
el objeto t es un Timer
el objeto sentido es un caracter
mensajes:
avisado(deme ee, deme paquete es un EventArgs)
{
es sentido = "derecha"?
si: es x < límite ?
si: {
copie x + velocidad*Math.Cos(radianes) en x
copie y + velocidad*Math.Sin(radianes) en y
}
no: {
copie "izquierda" en sentido
copie (180-alfa)*Math.PI/180 en radianes
copie radianes.DemeCaracteres en dir.Text
}
no: {
copie x + velocidad*Math.Cos(radianes) en x
copie y + velocidad*Math.Sin(radianes) en y
}
dir.Refresh
}
pinte(deme ee, deme paquete es un PaintEventArgs)
{
paquete.Graphics.DrawEllipse(Pens.Red, x, y, 2, 2)
paquete.Graphics.DrawLine(Pens.Black, límite, 40, límite, 260)
}
dir
{
copie 55 en alfa
dir.manejador(dir.Paint, pinte)
dir.manejador(t.Tick, avisado)
copie 270 en límite
copie 200 en x
copie 40 en y
copie 5 en velocidad
copie alfa*Math.PI/180 en radianes
copie radianes.DemeCaracteres en dir.Text
copie 100 en t.Interval
t.Start
copie "derecha" en sentido
}
Ejemplo: Cómo maximizar una ventana ? ?
clase v derivada_de Form
publicos
mensajes
v copie
FormWindowState.Maximized en v.WindowState
Ejemplo:
Cómo sensar el teclado cuando un control tiene el foco de atención ?
clase v derivada_de Form
publicos
los objetos bot1, bot2 son Button
mensajes
t(deme nn, deme ch es un KeyEventArgs)
{
muestre "Tecla pulsada: ", ch.KeyCode
}
v{
copie " Tiene botones y....sí sensa teclas con el foco en algún botón. Use Tab para cambiar el foco" en v.Text
/*v.manejador(doy "v.KeyDown", doy "t") SOBRA*/
v.AgregarControl(bot1)
v.manejador(bt1.KeyDown, t)
el objeto tamaño es un Size(doy 40, doy 20)
el objeto posición es un Point(doy 100, doy 0)
copie tamaño en bot2.Size
copie posición en bot2.Location
v.AgregarControl(bot2)
v.manejador(bot2.KeyDown, t)
}
Ejemplo:
Cómo usar la rueda del ratón ?
/*
http://msdn.microsoft.com/es-es/library/system.windows.forms.control.mousewheel(v=VS.80).aspx
http://msdn.microsoft.com/es-es/library/system.windows.forms.mouseeventargs.delta(v=VS.80).aspx
*/
clase v derivada_de Form
publicos
los objetos i, t son cantidades
mensajes
v{
es SystemInformation.MouseWheelPresent = verdadero ?
si: muestre "SI tiene rueda el ratón"
no: muestre "NO tiene rueda el ratón"
v.Manejador(v.MouseWheel, ratón)
copie 0 en i
}
ratón(deme NC, deme detalles es un MouseEventArgs)
{
copie i + 1 en i
copie detalles.Delta.ToString # " ==> " # i.DemeCaracteres en v.Text
}
Ejemplo:
Cómo hacer una clase ?
NNNN