Escolar Documentos
Profissional Documentos
Cultura Documentos
Introduccin................................................... 9
1.1. Introduccin ........................................... 10
1.2. Consideraciones previas .................................. 10
1.2.1. Versiones de Delphi 5 .............................. 10
1.2.2. Requerimientos de Delphi 5 ......................... 11
1.3. Instalacin de Delphi 5 .................................. 11
2. El entorno................................................. 15
2.1. Introduccin ............................................ 15
2.2. Elementos iniciales ...................................... 15
2.2.1. Ventana principal .................................. 15
2.2.2. La Paleta de componentes ........................... 17
2.2.3. El formulario ...................................... 19
2.2.4. El Inspector de objetos ............................ 19
2.2.5. El men principal .................................. 20
2.3. El Depsito de objetos ................................... 20
2.4. Obtener ayuda ........................................... 21
2.5. Creacin de la interfaz de un programa .................... 21
2.5.1. La ventana del programa ............................ 22
2.5.2. La rejilla de puntos ............................... 23
2.5.3. Insercin de componentes ........................... 24
2.5.4. Manipulacin de los componentes .................... 25
2.5.5. Modificacin de propiedades ........................ 26
2.5.6. Uso de los eventos ................................. 27
2.5.7. Edicin de cdigo .................................. 28
2.5.8. Ejecucin de un programa ........................... 31
3. Proyectos.................................................. 32
3.1. Introduccin ............................................ 32
3.2. Gestin del proyecto ..................................... 32
3.2.1. El proyecto por defecto ............................ 32
3.2.2. Uso del Gestor de proyectos ........................ 33
3.2.3. Proyectos predefinidos ............................. 35
3.3. El archivo de proyecto ................................... 36
3.4. Archivos de formulario ................................... 37
3.5. Mdulos de cdigo ........................................ 38
3.6. Grupos de proyectos ...................................... 38
3.7. Otros elementos de un proyecto ............................ 39
4. Fundamentos de Object Pascal............................... 40
4.1. Introduccin ............................................ 40
4.2. Estructura general ....................................... 40
4.2.1. El punto y el punto y coma ......................... 41
4.2.2. Mdulos y la clusula Uses ......................... 41
4.3.2. Tipos .............................................. 42
4.3.3. Declaracin de variables ........................... 44
4.3.4. Matrices ........................................... 44
4.3.5. Definir nuevos tipos ............................... 46
4.3.6. Constantes y literales ............................. 51
53
54
55
56
56
57
58
59
63
64
64
67
69
69
71
73
74
74
76
76
77
77
78
80
81
84
84
84
85
86
87
88
89
90
91
91
92
92
93
93
94
95
95
95
95
139
139
140
141
142
142
143
144
146
146
147
147
148
149
149
150
151
152
153
153
153
154
154
156
158
160
161
161
162
162
165
165
165
166
166
168
169
170
170
172
174
175
178
180
180
181
182
186
188
188
188
189
191
191
192
192
193
195
196
197
198
199
200
200
200
201
203
203
203
203
204
205
205
206
206
207
208
208
209
209
210
210
211
212
214
215
217
221
221
221
222
223
223
223
224
226
227
228
228
228
229
229
233
233
233
234
235
235
237
238
240
240
241
241
241
242
242
243
246
246
247
247
248
248
248
249
249
250
250
251
251
251
252
253
253
253
254
254
254
255
Introduccin
Todo comenz con el oscuro y difcil mundo del lenguaje de mquina y
luego el ensamblador. Por entonces la programacin de las computadoras
era privativa
de especialistas y cientficos. Era tan complicado
programar y tan difcil acceder a una computadora que solo unos pocos
podan hacerlo. Un programa que resolviese un problema medianamente
complejo requera de la escritura de muchas lneas de cdigo lo que
haca que fuese difcil no solo crearlo sino tambin el mantenerlo y
mejorarlo. Como suele suceder, la evolucin, no se detuvo y se fueron
mejorando los lenguajes, aparecieron los llamados entornos de
desarrollo integrado que incluyen editor, compilador o interprete y
debugger. Ya hoy contamos con los llamados entornos visuales de
programacin que se clasifican dentro de la cuarta generacin y que
permiten al programador una mayor concentracin en la resolucin de
los problemas que se le plantean y una menor perdida de tiempo en el
diseo de las interfaces para el acceso de los usuarios y la escritura
de cientos de lneas de cdigo. Estos nuevos entornos de programacin
le permiten a los programadores crear aplicaciones utilizando tcnicas
como la de arrastrar y soltar, aadiendo iconos que representan
objetos, modificando sus propiedades y escribiendo algo de cdigo. La
posibilidad de reusar componentes realizados previamente as como la
de usar los fabricados por otros son una expresin de los niveles de
reusabilidad que redundan en un acortamiento del ciclo de desarrollo.
Delphi califica como uno de estos nuevos lenguajes visuales y sin
dudas lo hace muy bien permitiendo el desarrollo rpido de
aplicaciones de alta complejidad con una interface grfica funcional y
de un calidad grfica importante. Disponible inicialmente para las
plataformas Windows y recientemente, con el proyecto Kylix, tambin
para las del tipo Linux. Basado en un compilador de indudable calidad
es ahora posible desarrollar aplicaciones multiplataforma pues el
cdigo, siempre que no utilice funciones especficas de la API de
windows, puede ser compilado y ejecutado bajo plataforma linux. La
versin 5.0 que es en la que se basa este libro nos permite crear
aplicaciones
para
Internet
e
Intranets,
servicios
locales
y
distribuidos, y acceso a una amplia gama de Bases de Datos personales
o del tipo Cliente/Servidor. En fin si usted decide crear aplicaciones
de calidad que no simplemente funcionen sino que saquen partido a su
sistema operativo, Delphi 5.0 es la herramienta adecuada y en este
libro podr encontrar los fundamentos necesarios para ponerse en
marcha.
1. Instalacin
1.1. Introduccin
El formato de distribucin en el que se encuentra Delphi 5 es el CD,
soporte que permite almacenar, por ejemplo, los ms de 400 megabytes
que ocupa la versin Enterprise, en la cual se incluye Delphi 5,
Interbase Server, InstalIShield, TeamSource, los archivos imagen que
permiten ejecutar todo ello desde el propio CD y mltiples archivos
con informacin diversa. La ocupacin real en nuestro disco no ser
tan elevada, ya que no tenemos por qu instalar todas las opciones;
podemos dejar las partes que nos interesen en el CD, sin instalarlas
en nuestro sistema.
2.2.3. El formulario
La ventana que aparece aproximadamente en el centro de la pantalla,
segn se ha mostrado en la figura 2.1, y que tiene por ttulo Form1,
recibe el nombre de formulario. Una formulario es una ventana que en
una aplicacin Delphi acta como contenedor, en el cual se irn
insertando los componentes que sean necesarios para solicitar datos,
mostrar informacin o realizar cualquier otra tarea.
Durante la ejecucin, un formulario se comporta como cualquier otra
ventana Windows, es decir, se mostrar con un ttulo, unos botones que
le permiten maximizar, minimizar o cerrar la ventana y un rea de
trabajo o rea cliente en la que se encontrarn los controles con los
que interactuar el usuario del programa. En realidad, todos estos
elementos son configurables y, mediante las propiedades oportunas,
podremos alterar el ttulo de la ventana, la existencia o no de los
citados botones, etc.
Habitualmente en un proyecto Delphi existe ms de un formulario, dando
as
lugar
a
un
programa
que
utiliza
ms
de
una
ventana.
Posteriormente, en el captulo 8, aprenderemos a gestionar un proyecto
de estas caractersticas.
2.2.4. El Inspector de objetos
Con este nombre se conoce a la ventana que inicialmente aparece en la
parte izquierda de la pantalla, justo debajo de la ventana principal y
a la izquierda del formulario. En el Inspector de objetos encontramos
bsicamente tres elementos diferentes: la lista de componentes, en la
parte superior, la pgina de propiedades y la pgina de eventos.
La lista desplegable existente en la parte superior del Inspector de
objetos, la cual podremos abrir pulsando el botn que hay en el
extremo derecho, contiene el nombre de cada uno de los componentes que
existen en el formulario sobre el que estamos trabajando en ese
momento. Al seleccionar cualquiera de esos componentes se mostrara en
la parte superior no slo su nombre sino tambin su tipo. En la figura
2.1 puede ver que el componente seleccionado es Form1, cuyo tipo es
TForm1.
Los componentes Delphi son elementos genricos que han de servir para
cualquier aplicacin, por lo que han de ser flexibles en ciertos
aspectos, permitiendo su personalizacin. La pgina Properties del
Inspector de objetos muestra las propiedades del componente que
tengamos seleccionado, as como los valores que actualmente contienen
dichas propiedades. Alterando el valor de una propiedad podemos
modificar el ttulo del formulario, conseguir que no aparezcan los
botones de minimizar o maximizar, etc. La pgina Events es la que
contiene los nombres de los eventos soportados por el componente, as
como los nombres de los procedimientos que se ejecutarn al generarse
un
evento
apropiado
para
la
determinado
Para ello haremos uso de algunas opdones, como New Form o Add To
Project y, adems, utilizaremos el Gestor de proyectos de Delphi.
Para hacer aparecer la ventana del Gestor de proyectos, que se muestra
en la figura 3.2, deberemos utilizar la opcin Project Manager del
men View, a no ser que en el rea de botones de acciones rpidas
exista un botn que nos permita realizar esa misma funcin. La ventana
mostrada consta, bsicamente, de una lista jerrquica en la que se
enumeran los proyectos existentes y los elementos de cada uno de
ellos. En la parte superior tenemos unos botones que nos permitirn
aadir nuevos proyectos, eliminar cualquiera de los existentes o
activar el seleccionado en ese momento. Tambin puede seleccionarse un
proyecto directamente, desde la lista desplegable que hay a la
izquierda de los botones.
En la barra de estado, situada en la parte inferior, podemos ver el
nombre del archivo en que est contenido el elemento seleccionado,
incluyendo el camino completo en el que se encuentra en disco. Por
cada una de los elementos se indica el nombre del mdulo de cdigo, el
nombre del formulario, en caso de que dicho mdulo est asociado a
una, y por ltimo el camino en que se encuentra el elemento.
Pulsando el primer botn existente en la parte superior podremos
aadir un nuevo proyecto al grupo actual. Esto nos permite trabajar
simultneamente con varios proyectos, lo cual es muy til cuando
existen dependencias entre ellos. Si abrimos el men emergente
correspondiente a un proyecto, pulsando el botn derecho del ratn
tras haber situado correctamente el puntero, encontraremos una primera
opcin, Add, que nos permite aadir cualquier mdulo o formulario ya
existente en disco, simplemente facilitando el camino y nombre. La
accin contraria, eliminar un elemento del proyecto, la podemos
efectuar seleccionando en la lista el elemento que deseamos borrar y
seleccionando la opcin Remove from project de su men emergente.
con
un
tipo
de
letra
resaltado
para
cdigo,
por
ejemplo,
seran
un
Program Prueba;
Begin
ShowMessage('Hola') ;
End.
En este programa existen una serie de palabras reservadas, que en el
Editor de cdigo de Delphi aparecern en negrita. Estas palabras son
Program, Begin o End, reconocidas directamente por el lenguaje Object
Byte
Shortint
Smallint
Word
Integer
LongInt
LongWord
Cardinal
Int64
Boolean
ByteBool
WordBool
LongBool
Single
Double
Real
Extended
Comp
Char
AnsiChar
WideChar
String
ShortString
AnsiString
PChar
PansiChar
PwideChar
Pointer
Variant
deberemos
elemento.
utilizar
el
ndice
ndices
que
correspondan
dicho
de
de
un
de
la
relacin
existente
entre
dos
el segundo.
o igual que
el
el segundo.
o igual que
el
A este tipo de expresiones, en las cuales se trabaja tan slo con los
valores True y False, se las denomina expresiones lgicas o booleanas.
Para componerlas usaremos los operadores lgicos que se muestran en la
tabla 4.4, que por regla general formarn parte de una expresin ms
compleja en la que finalmente se obtendr un valor de tipo Boolean.
Operador
Not
And
Or
Xor
Const
Cadenal = 'Cadena 1.';
Cadena2 = 'Cadena 2.';
Var
Cadena: String;
begin
Cadena := Cadenal + Cadena2;
ShowMessage(Cadena) ;
Operadores entre bits
Estos operadores son tiles cuando se necesita manipular los bits
individuales de un dato, que habr de ser necesariamente un tipo
entero. En Delphi, desarrollando un programa Windows, sern muy pocas
las ocasiones en las que se necesiten este tipo de operaciones.
Los operadores de manipulacin de bits actan de forma individual
sobre cada uno de los bits de los operandos, generando un resultado
del mismo tipo. En la tabla 4.5 se enumeran estos operadores,
indicndose la operacin que lleva a cabo cada uno de ellos. Observe
que los primeros cuatro operadores son los mismos que anteriormente
vimos para construir expresiones lgicas.
Operador
Not
And
Or
Xor
Shr
Shl
N := 5;
PunteroN^ := 5;
Las dos asignaciones son equivalentes y, de hecho, al asignar un valor
a N tambin lo estaremos asignando al valor a donde apunta PunteroN ya
que, en realidad, existe un slo valor entero al que estamos haciendo
referencia con dos variables.
4.5.5. Orden de prioridad
Cuando se escriben expresiones de una cierta complejidad, en la que
intervienen mltiples operadores incluso de tipos distintos, hay que
tener en cuenta un factor al que se denomina orden de prioridad o
preferencia de los operadores. Ser este factor el que determine el
orden en que se irn evaluando las diferentes subexpresiones,
generando resultados parciales que, a su vez, intervendrn como
operandos en otras expresiones, hasta finalmente generar un nico
resultado.
El orden de prioridad de los operadores de Object Pascal es el que se
indica en la tabla 4.7. Dicho orden puede ser alterado siempre que nos
interese mediante el uso de parntesis. Cualquier subexpresin que
est contenida entre parntesis ser evaluada antes que cualquier otra
que no lo est. Si existen varias subexpresiones entre parntesis,
stas sern evaluadas de izquierda a derecha. Tambin est permitido
el uso de varios niveles de parntesis, de tal forma que la evaluacin
siempre comenzar por el nivel ms interior.
Nivel
Operadores
1
2
3
4
Not, @
And, Shl, Shr, *, /, Div y Mod
Or, Xor, + y =, <, <=, >, >=, <>, in
if N > 5 Then
ShowMessage('Invalido');
Aqu se ha usado lo que se conoce como identacin, escribiendo la
llamada a ShowMessage() algo ms adentro que la palabra If. Esto hace
que visualmente sea muy rpido darse cuenta de que esa lnea es
dependiente de la anterior y que, en este caso concreto, no se
ejecutar siempre, sino slo cuando la expresin sea cierta.
En el caso que se ha puesto como ejemplo tan slo se ejecuta una
sentencia cuando la condicin se cumple. En la prctica, es posible
que necesitemos ejecutar mltiples sentencias. En este caso tendremos
que crear un bloque, mediante las palabras Begin y End, delimitando
las sentencias que se habrn de ejecutar. A continuacin puede ver un
fragmento de cdigo en el que adems de mostrarse un mensaje, en caso
de que la condicin se cumpla, tambin se modifica el valor de N.
If N > 5 Then
Begin
ShowMessage('invalido');
N := 0;
End;
Las sentencias que en nuestro programa existan tras el condicional If
sern ejecutadas siempre, independientemente de que el resultado de la
expresin sea cierto o falso. Est claro que si detrs del cdigo
anterior escribimos cualquier otra sentencia, sta no se ver afectada
por la condicin, al encontrarse fuera del bloque.
A veces, sin embargo, puede interesamos que una o varias sentencias se
ejecuten slo en caso de que el resultado de la expresin sea falso.
Suponga que deseamos completar el cdigo de los ejemplos anteriores,
de tal forma que se muestre un mensaje si el valor es invlido y otro
cuando sea vlido. El siguiente cdigo podra parecer adecuado, pero
su funcionamiento no ser el esperado.
If N > 5 Then
ShowMessage('Invalido');
{ Esta sentencia se ejecutar siempre }
ShowMessage('Valido') ;
La segunda llamada a ShowMessage() se realizar siempre, por lo que
aun cuando N sea mayor que cinco y se haya mostrado el primer mensaje,
a continuacin se mostrar el segundo mensaje. La solucin a este
problema la encontraremos en la palabra Else, que como parte de una
sentencia condicional es la encargada de ejecutar el cdigo que le
sigue slo en caso de que la expresin haya sido False. De esta
manera, lo nico que necesitamos es realizar la modificacin
siguiente.
If N > 5 Then
ShowMessage('Invalido')
Else
ShowMessage('Valido');
Observe que se ha eliminado el punto y coma que haba tras la primera
llamada a ShowMessage(), ya que delante de la palabra Else no debe
existir punto y coma. Ahora el resultado de la ejecucin de este
cdigo s ser el esperado.
No existe ninguna restriccin en cuanto al
ir tras la palabra Then o la palabra Else,
vez otra sentencia de tipo condicional.
decisiones anidadas, como la que se muestra
If N > 5 Then
ShowMessage('Invalido')
Else If N > 3 Then
ShowMessage('Casi valido')
Else
ShowMessage('Valido');
Al crear construcciones de este tipo hemos de tener en cuenta que la
parte Else del condicional siempre pertenece al ltimo If que se haya
escrito, debindose delimitar adecuadamente, en caso necesario, cada
uno de los bloques a ejecutar mediante las palabras Begin y End.
Decisiones mltiples con operando comn
Cuando en
veces la
operandos,
propuesto
decisiones
Case..Of.
Case N 0f
0..3: ShowMessage('Vlido');
4, 5: ShowMessage('Casi vlido')
Else ShowMessage('Invlido');
End;
Si el valor N est comprendido entre cero y tres se mostrar el primer
mensaje, si es cuatro o cinco el segundo y en caso contrario el
tercero. Observe que el primer valor de la lista es un subrango y el
segundo una enumeracin. Obviamente tambin podemos disponer valores
simples, siempre que stos sean del mismo tipo que el selector,
debiendo ambos siempre pertenecer al grupo de los escalares.
4.6.2. Bucles
Un bucle es una estructura de control de repeticin que nos permite
ejecutar una misma sentencia mltiples veces. El nmero de veces que
se ejecuta un bucle puede ser conocido de antemano, en cuyo caso se
suele usar un bucle por contador, o bien no serlo, utilizndose
entonces un bucle condicional.
Al igual que ocurre con las sentencias condicionales que hemos
conocido en el punto anterior, podemos asociar varias sentencias a un
bucle delimitando un bloque, para lo cual dispondremos la palabra
Begin antes de la primera sentencia ejecutable y la palabra End detrs
de la ltima.
Bucles por contador
Para crear un bucle de este tipo usaremos la instruccin For,
existente tambin en otros lenguajes, como BASIC o C. A este bucle se
le llama as por estar controlado mediante una variable numrica, que
actuar como contador y cuyo identificador facilitaremos tras la
palabra For.
El nmero de veces que se repetir el bucle depender de los valores
inicial y final que asignemos al contador, sabiendo que ste se ir
incrementando o decrementando en una unidad a cada vuelta. La
estructura general de este tipo de bucle sera la siguiente:
For Contador := Inicio To Fin Do
SentenciaAEjecutar;
En caso de que el valor de inicio sea mayor que el de fin y, por
tanto,
el
contador
deba
ir
decrementndose
en
lugar
de
incrementndose, cambiaremos la palabra To por DownTo.
El contador de un bucle de este tipo debe ser necesariamente de tipo
escalar y haberse declarado como una variable local al bloque en el
que se va a ejecutar el bucle. Es decir, si vamos a crear un bucle en
Var
N: Integer;
begin
N := Cuadrado(8);
end;
5. Fundamentos de la Programacin Orientada a Objeto
5.1 Introduccin
Objetos, objetos y ms objetos, vivimos en un mundo de objetos. La
Programacin Orientada a Objetos no es nada nuevo, surgi hace ya
varios aos aunque por entonces no pudo, por sus necesidades de
potencia de computo, desplazar a la llamada programacin convencional.
Lenguajes como SIMULA y SmallTalk se consideraron entre los pioneros
en esta tendencia y comenzaron a brindar a los programadores nuevas y
deseadas caractersticas como robustez, verdadera modularidad y reuso,
as como un importante acercamiento entre el oscuro mundo de los bits
y el real mundo de los objetos. Hacia finales de los 80 el desarrollo
de la potencia de computo y la complejidad del software creci
trayendo consigo un redespertar en esta tendencia y provocando que
lenguajes de los llamados convencionales como C y Pascal se les
incluyera la posibilidad de los objetos surgiendo los llamados
Leguajes Hbridos como el popularsimo C++ y el Object Pascal motivo
de estudio en este libro.
El hecho de que muchos de nosotros trabajemos con objetos no quiere
decir que estemos programando Orientado a Objetos. Hay una diferencia
sustancial entre Programar usando objetos y Programar Orientado a
Objetos. En Visual Basic, por ejemplo, se suele trabajar con un
montn de objetos (Componentes) sin que ello signifique que estamos en
presencia de un lenguaje orientado a objetos. El lector podr
preguntarse entonces: cundo, realmente, programamos orientado a
objetos? Programamos orientado a objetos cuando somos capaces de
modelar el problema que se nos presenta en trminos de objetos y sus
relaciones. Es decir cuando cada entidad en nuestro software es un
objeto que brinda determinados servicios estrictamente definidos
siendo adems responsable de su integridad y funcionamiento ante
condiciones anormales.
5.3 Clases.
La Programacin Orientada a Objetos descansa en el concepto de clase.
Conceptualmente llamamos clase a un tipo de dato abstracto y su
parcial o total implementacin. Hablando menos formalmente una clase
es una plantilla que describe la representacin de un tipo de objeto y
su comportamiento, Consecuentemente, las clases definen las
propiedades y el comportamiento de conjuntos de objetos. Veamos, por
ejemplo, la declaracin de la clase Empleado atendiendo al ejemplo de
Tipo de Dato Abstracto visto anteriormente.
type
Empleado =
class
private
Nombre: string;
Edad: byte;
FechaIE: string;
Salario: real;
Cargo: string;
public
constructor Create( ANombre:string; AEdad:byte;
AFechaIE:string; ASalario:real; ACargo:string);
function CalculaSalario: real;
end;
5.4 Objetos
Ya hablamos previamente de instancias de la clase empleado y de sus
datos reales, es a estas intancias a lo que se le denomina objetos.
Un objeto es, por tanto, una instancia de la clase a la que se le
asocia un estado determinado relacionado con el valor de sus
propiedades.
En el fragmento de cdigo siguiente y a modo de ejemplo declaramos un
par de objetos (instancias) de la clase empleado:
...
var
Secretaria: Empleado;
Director: Empleado;
begin
// Creacin del objeto secretaria.
Secretaria := Empleado.Create(Neli, 20, 23/4/2000, 250.50,
Secreataria);
// Creacin del objeto director.
end;
Tenemos hasta ahora dos conceptos fundamentales de la programacin
orientada a objetos, los conceptos de clase y objeto. La programacin
orientada
a objetos es entonces la implementacin de tipos de datos
abstractos, es decir, la implementacin de clases. Vale preguntarse
ahora cmo interactan los objetos?
5.5 Mensajes
En la programacin orientada a objetos un programa no es ms que una
coleccin de objetos interactuantes. Esa interaccin se produce a
travs de mensajes.
Un mensaje es un pedido al objeto de que ejecute uno de sus mtodos y
consta de nombre del objeto y nombre del mtodo a ejecutar. Un mensaje
podra ser Secretaria calclese el salario lo que en Object Pascal
sera :
...
Salario := Secretaria.CalculaSalario;
...
Donde secretaria es el nombre del objeto y CalculaSalario es el
nombre del mtodo invocado. Ver un programa como una coleccin de
objetos que interactan entre s envindose mensajes y cambiando su
estado durante la ejecucin es en extremo importante para poder
entender como funciona el paradigma de los objetos.
5.6 Relaciones
Supongamos, con propsitos ilustrativos, que queremos construir un
programa de dibujo y consideremos dos clases inicialmente, la clase
Punto y la clase crculo:
type
Punto =
class
private
x, y: real;
public
constructor Create( Ax, Ay: real );
procedure SetX( Ax: real );
// Cambia los valores de x
procedure SetY( Ay: real );
// Cambia los valores de y
end;
Crculo =
class
private
x, y, Radio: real;
public
constructor Create(
procedure SetX( Ax:
procedure SetY( Ay:
procedure SetRadio(
end;
Type
Rectngulo =
Class
Private
VSI: Punto;
// Vrtice superior izquierdo
VID: Punto;
// Vrtice inferior derecho
public
Constructor Create( xsi, ysi, xii, yii: real );
End;
5.7 Herencia
Con la herencia podemos hacer uso de la relacin del tipo es un.
Hagamos entonces que el crculo herede del punto.
...
type
Punto =
class
private
x, y: real;
public
constructor Create( Ax, Ay: real );
procedure SetX( Ax: real );
// Cambia los valores de x
procedure SetY( Ay: real );
// Cambia los valores de y
end;
Circulo =
class( Punto )
private
Radio: real;
public
constructor Create( Ax, Ay, ARadio: real );
procedure SetRadio( ARadio: real );
valores del radio.
end;
// Cambia los
Ntese que esta vez para definir la herencia se aade entre parntesis
a la palabra reservada class el nombre de la clase de la cual queremos
heredar y de esta manera:
Circulo =
class(Punto)
end;
La clase crculo por tanto, hereda todas la propiedades y mtodos de
la clase punto siendo innecesario rescribirlos. A nivel de objetos
ahora podemos usar el crculo como si fuese un punto:
var
C: Circulo;
begin
...
C := Circulo.Create(2,2,8);
C.SetX( 7 );
heredado del punto
C.SetY( 5 );
heredado del punto
C.SetRadio( 10 );
end.
le
en
es
le
5.8 Polimorfismo
El polimorfismo le permite a una entidad ya sea una variable, una
funcin u objeto, adoptar una variedad de representaciones. Un ejemplo
sencillo de polimorfismo en variables ocurre en un lenguaje que no es
fuertemente tipificado cuando utilizamos las siguientes sentencias:
...
i = 49
...
i = i + 1
I = casa
Para las funciones ocurre cuando tenemos una funcin que realiza
diferentes tareas bajo un mismo nombre. A esto se le suele llamar
sobrecarga de funciones, veamos un ejemplo.
Supongamos que tenemos una funcin rea que calcula el rea de un
crculo. El cdigo del ejemplo est escrito atendiendo a la sintaxis
de c++ por ser este un lenguaje que soporta sobrecarga de funciones.
rea de un
...
double area( double a, double b )
{
return a * b;
};
Debido a que la lista de parmetros de la funcin es diferente el
compilador puede deducir el uso correcto de la funcin chequeando los
tipos reales de estos.
...
double ac;
double ar;
ac = area( 4.6 );
correspondiente al crculo.
ar = area( 6.8, 90 );
correspondiente al rectngulo.
...
public
public
function Punto.area;
begin
Result := 0;
end;
...
virtual;
override;
function Circulo.area;
begin
Result := 3.14*Radio*Radio;
end;
...
La inclusin de la palabra virtual a continuacin de la funcin area
del punto significa que el cdigo de dicha funcin se anexar en
tiempo de ejecucin del programa. Lo mismo ocurre con lo herederos
de la clase punto que reimplementen esa funcin haciendo uso de la
sentencia override. Sin una declaracin del tipo virtual en este caso
sera imposible ejecutar un cdigo como este:
...
var
i: byte;
P: Punto;
C: Circulo;
List: TList;
begin
P := Punto.Create(2,2);
C := Circulo.Create(3,3,10);
List := TList.Create;
List.Add( P );
List.Add( C );
for i := 0 to List.Count - 1 do
begin
writeln( Punto(List.Items[i]).Area );
end;
readln;
end.
Ntese que para este ejemplo hemos utilizado la clase TList incluida
en la unit classes de la versin 5.0 de Delphi que permite manipular
una lista polimrfica (Objetos diferentes) y que contiene una
propiedad llamada items por la que se puede acceder a los objetos en
su interior mediante un ndice (Ejemplo: List.Items[1] accede al
objeto # 1). A la lista se le han insertado mediante el mtodo
List.Add
un
objeto
Punto
y
uno
Crculo.
La
lnea
writeln(
Punto(List.Items[i]).Area ); es la que exhibe el comportamiento
polimrfico. Cuando en la ejecucin se recorre la lista primero se
imprimir 0 que es el resultado de invocar la funcin area del punto y
luego 314 como resultado de invocar la funcin rea para el circulo.
La sentencia Punto( List.Items[i].Area ) hace lo que se llama una
reinterpretacin de tipos permitiendo que todo objeto de la lista se
interprete como una instancia de Punto o descendiente de este en el
rbol jerrquico.
El Polimorfismo es entonces en trminos de objetos la posibilidad de
que la variable que representa la instancia (en el ejemplo anterior
6.4. Propiedades
Desde el punto de vista del usuario de un componente, que es el
nuestro, las propiedades son como los miembros de un registro, es
decir, son elementos pertenecientes a un objeto. Por tanto, para
acceder a una propiedad de un componente usaremos la notacin que ya
conocemos, en la cual el punto acta como separador entre el nombre
del componente y el de la propiedad.
Aunque la mayora de las propiedades son de lectura y escritura,
existen algunas que son de slo lectura y, ms raramente, algunas de
slo escritura. Tambin hay que distnguir entre las propiedades que
Begin
With UnaForm Do
Begin
Nombre := 'Pedro Garca';
Direccion := 'Avda. de la Paz, 24';
Telefono := '348123';
Personal := True;
End;
6.4.2. Posicin y dimensiones del componente
Tal y como se comentaba al principio de este captulo, vamos a conocer
a continuacin las propiedades ms habituales de \a mayora de los
componentes, lo que nos permitir, en captulos posteriores, tratar
los elementos especficos de cada componente sin necesidad de repetir
varias veces lo mismo. Comencemos tratando las propiedades en las que
se almacena la informacin de posicin y dimensiones del componente.
Todos los componentes estn colocados en una determinada posicin del
formulario, incluso aquellos que en ejecucin no estarn visibles. La
posicin de un componente se almacena en las propiedades Left,
columna, y Top, fila. El contenido de estas dos propiedades ser un
nmero entero cuya unidad de medida es el punto de pantalla, que
contiene la coordenada horizontal y vertical, respectivamente, en que
se haya situado el componente. Estas coordenadas son relativas al
espacio o superficie del formulario, en el cual el punto 0,0 es la
esquina superior izquierda.
Los componentes visuales, a los que se conoce como controles, adems
de una posicin tambin cuentan con un tamao, segn el cual ocupan un
espacio ms o menos amplio en el formulario. El ancho y alto del
control, expresado tambin en (puntos, se almacena en las propiedades
Width y Height, respectivamente.
Cuando en la fase de diseo se mueve o modifica el tamao de un
componente,
automticamente
se
actualiza
el
contenido
de
las
propiedades que se acaban de citar. De igual forma, puede editar el
contenido de estas propiedades, en el Inspector de objetos,
modificando la posicin y las dimensiones del componente.
Aunque el punto en el que aparece un control y su tamao es algo que
se suele fijar durante el diseo, tambin podemos alterar estas
propiedades durante la ejecucin. De esta forma, con una simple
asignacin,
podemos
establecer
la
posicin
y
dimensiones
del
componente.
En caso de que la aplicacin que se desarrolla vaya a utilizarse en
distintos sistemas, usando diferentes resoluciones de pantalla, adems
de unas dimensiones fijas, facilitadas en las propiedades Width y
Height, tambin pueden establecerse unos lmites de tamao. Esta es la
finalidad de la propiedad Constraints que, como ver en el Inspector
Contenido
Color
Height
Name
Pitch
Size
Style
Button1.SetFocus;
Los controles en un formulario cuentan, adems de con una posicin y
unas dimensiones, con un orden en el eje Z o de profundidad, segn el
cual al superponer dos o ms controles unos aparecen sobre otros. Este
orden, establecido en modo de diseo, puede ser modificado en
ejecucin mediante los mtodos BringToFront() y SendToBack(). El
primero de ellos lleva el control al primer nivel, situndolo sobre
todos los dems, mientras que el segundo tiene el efecto contrario, y
sita el control debajo de todos los dems.
7. Componentes ms habituales
7.1. Introduccin
Los primeros cinco captulos de esta gua han servido para sentar las
bases necesarias para comenzar a desarrollar programas con Delphi. En
este captulo vamos a conocer los componentes ms habituales de
Delphi, aquellos que se utilizan con ms frecuencia en la mayora de
las aplicaciones.
Partiendo de que ya conocemos las propiedades, eventos y mtodos ms
comunes, cuya existencia o disponibilidad podemos comprobar en el
Inspector de objetos y ayuda de Delphi, acometeremos directamente las
particularidades de cada uno de los componentes, tras lo cual se
propondr un ejemplo prctico de su uso.
Tipo de borde
Sin
borde.
La
ventana
no
puede
ser
redimensionada, adems no tendr barra de ttulo
ni botones en la parte superior.
Borde simple que no permite redimensionar.
Borde grueso que permite redimensionar.
Borde grueso que no permite redimensionar.
Borde simple que no permite redimensionar y que
cuenta con una barra de ttulo ms pequea.
Borde grueso que permite redimensionar y que
cuenta con una barra de ttulo ms pequea.
fijado
fijada
en
la
en
el
disponible en
wsMinimized.
pantalla,
wsMaximized,
Constante
wsNormal
wsMaximized
wsMinimized
bien
en
forma
de
icono,
Estado inicial de la
ventana
Normal
Maximizada
Minimizada
caNone
caHide
caFree
caMinimize
CanClose := False;
end;
Al ejecutar el programa observe que en la parte superior aparecen las
dimensiones del formulario, ya que el evento OnResize se produce cada
vez que sta cambia de tamao, hecho que ocurre tambin en el momento
en que el formulario es creado. Si modifica el tamao del formulario
podr comprobar que los valores de las propiedades Width y Height son
mostrados en la barra de ttulo. Haga doble clic sobre el formulario
para comprobar que el evento OnDbIClick funciona adecuadamente. Por
ltimo pulse sobre el botn de cierre y conteste negativamente a la
pregunta de si desea salir. Como ver, la ventana no se cierra, ya que
al asignar el valor False al parmetro CanClose del evento
OnCloseQuery lo estamos impidiendo.
Se
denomina
botn
por
defecto
a
aquel
que
ser
pulsado
automticamente, generando el correspondiente evento OnClick, en el
momento en que pulsemos la tecla <Intro>, independientemente del
control que est activo en ese mo-mento. De esta forma, podemos
encontramos en un control TEdit, por ejemplo introduciendo un valor, y
pulsar la tecla <Intro> para pulsar el botn por defecto.
Para que un botn acte como botn por defecto habremos de dar el
valor True a la propiedad Default. Por defecto el valor de esta
propiedad es False, lo cual es lgico, ya que no tendra sentido la
existencia de mltiples botones por defecto en el mismo formulario, ya
que al pulsar la tecla <Intro> no se sabra cul pulsar.
El botn de cancelacin es aquel que se pulsa, adems de por los
mtodos normales, mediante la tecla <Esc>. Para que un botn acte
como botn de cancelacin deberemos dar el valor True a la propiedad
Cancel, que por defecto es False.
7.3.4. En la prctica
Para ver en funcionamiento el uso del control TButton, vamos a
insertar en un formulario un control TEdit, cuyas caractersticas
conoceremos posteriormente, y tres controlesTButton, con los ttulos y
teclas de acceso rpido que se pueden ver en la figura 7.2. El primer
botn no tiene ninguna caracterstica especial, mientras que el
segundo es el botn por defecto, para lo cual hemos dado el valor True
a la propiedad Default, y el tercero es el botn de cancelacin, por
lo cual la propiedad Cancel tiene ese mismo valor.
Figura 7.2. Aspecto del formulario con los tres controles TButton
Una vez que haya insertado los cuatro componentes, los haya situado
adecuadamente
y
asignado
los
valores
correspondientes
a
las
propiedades Caption, Default y Cancel, vamos a proceder a la escritura
del cdigo que se habr de ejecutar con la pulsacin de cada uno de
los botones.
Como lo nico que deseamos comprobar es cul de los tres botones se ha
pulsado, bastar con mostrar una ventana con un mensaje que bien
podra ser el propio ttulo del botn. Para mostrar esta ventana
usaremos el procedimiento ShowMessage() que conocimos anteriormente.
ver
que
los
Constante
taLeftJustify
taRightJustif
y
taCenter
A la izquierda
A la derecha
Al centro
Indica
Se permiten tanto maysculas como
minsculas.
Todas las letras son convertidas a
maysculas.
Todas las letras son convertidas a
minsculas.
Barras de desplazamiento a
mostrar
Ninguna
Vertical
Horizontal
Vertical y Horizontal
Memol.Lines.LoadFromFile( 'memo.txt' );
end;
Una vez escrito el cdigo ya puede ejecutar el programa e introducir
cualquier texto en el TMemo, que podr guardar en un archivo,
recuperar y eliminar pulsando los botones adecuados. En la figura 7.5
se muestra el aspecto del programa en funcionamiento, mostrando un
texto recuperado del archivo MEMO.TXT.
Estado del
control
Activado
Desactivado
Indeterminado
En modo de diseo basta con hacer doble clic sobre la propiedad tems
para abrir el editor especfico con el que cuenta, aadiendo los
ttulos de las opciones que deseemos mostrar. En ejecucin, podremos
usar los mtodos Add(), Append(), Insert() y Clear() para aadir o
eliminar elementos.
Los elementos existentes en un control TRadioGroup se numeran con un
ndice, cuyo punto de partida es el cero. Este ndice nos servir para
saber qu opcin es la que est activa o bien para establecerla,
mediante la propiedad Itemindex. Este mtodo de activar una opcin o
comprobar qu opcin es la que est activa es mucho ms eficiente que
el visto anteriormente para el control TRadioButton, en el que era
necesario ir comprobando el valor de la propiedad Checked de cada
control hasta saber cul de ellos era el que estaba activo.
En caso de que el nmero de elementos contenidos en el grupo sea muy
extenso, podemos optar por dividirlos en varias columnas. Para ello
bastar con que asignemos a la propiedad Columns el nmero de columnas
que deseamos.
7.9.2. En la prctica
Con el fin de ver en la prctica cmo podemos utilizar un control
TRadioGroup, vamos a insertar en un formulario dos controles de este
tipo, asignando a la propiedad Items los elementos que se pueden ver
en la figura 7.8. El primero contiene las opciones de tipo de borde
para el formulario, mientras que el segundo almacena las opciones
relativas a los estados de la ventana. El orden en que se han
dispuesto estos valores no es aleatorio, corresponde al orden que
ocupa cada una de las constantes en las enumeraciones TFormBorderStyle
y TWindowState.
Figura 7.8. Aspecto del formulario con los dos controles TRadioGroup
parmetros,
elimina
todas
las
cadenas
LoadFromFile():
Este
mtodo
es
complementario
al
anterior,
permitiendo recuperar la lista de elementos del archivo cuyo nombre se
facilita como parmetro.
Aunque mediante los mtodos Add(), lnsert(), Move() y Exchange() es
posible establecer la posicin de cada uno de los elementos segn nos
interese, dicha posicin tambin depender del valor que tenga la
propiedad Sorted del control TListBox. Si dicha propiedad tiene el
valor True los elementos de la lista estarn ordenados, de tal forma
que, por ejemplo, al aadir un nuevo elemento ste no va al final de
la lista, sino a la posicin que le corresponde segn el orden
establecido.
7.10.2. Elementos seleccionados
En una lista puede haber seleccionado un slo elemento o varios,
dependiendo del valor que asignemos a la propiedad MultiSelect. Por
defecto esta propiedad contiene el valor False, indicando as que no
es posible seleccionar varios elementos. Dndole el valor True
activaremos esta posibilidad.
end;
Inicialmente el botn Borrar estar desactivado, activndose slo
cuando al pulsar sobre la lista seleccionemos un elemento. Por ello
deberemos controlar el evento OnClick deI TListBox, asignando a la
propiedad Enabled del botn el valor True o False, dependiendo de que
exista o no un elemento seleccionado en ese momento, lo que sabremos
inspeccionando el valor de la propiedad Itemindex, que deber ser
distinto de -1.
{ Al pulsar en la lista }
procedure TForml.ListBox1Click(Sender: TObject);
begin
{ Activamos o desactivamos el botn de Borrar segn haya o no
seleccionado un elemento }
Button1.Enabled := ListBox1.Itemindex <> -1;
end;
Una vez que el botn est activado podremos pulsarlo, provocando el
borrado del elemento seleccionado en la lista. Para ello bastar con
realizar una llamada al mtodo Delete() de la propiedad tems, pasando
como parmetro el ndice del elemento a borrar, que al ser el elemento
seleccionado encontraremos en la propiedad tem ndex.
{ Al pulsar el botn Eliminar }
procedure TForml.Button2Click(Sender: TObject);
begin
{ Eliminamos el elemento seleccionado }
ListBoxI.Items.Delete(ListBox1.Itemindex);
{ y desactivamos el botn de borrar }
Button2.Enabled := False;
end;
El cdigo asociado al botn Vaciares el ms simple, ya que consta de
una simple llamada al mtodo Clear(), que elimina todo el contenido
del objeto TStrings, o lo que es lo mismo, de la lista.
{ Al pulsar el botn Vaciar }
procedure TForml.Button3Click(Sender: TObject);
begin
{ Dejamos vaca la lista }
ListBox1.Items.Clear;
end;
Por ltimo tendremos que controlar la pulsacin sobre el TCheckBox,
activando o desactivando el orden de los elementos en la lista. Para
ello bastar con asignar a la propiedad Sorted el valor que contenga
la propiedad Checked del TCheckBox, como puede ver a continuacin.
( Al activar o desactivar la opcin Ordenada }
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
{ Damos el valor adecuado a la propiedad Sorted }
ListBox1.Sorted := CheckBox1.Checked;
end;
Al ejecutar el programa lo primero que deber hacer ser aadir
algunos elementos a la lista, introduciendo un texto en el TEdit y
pulsando la tecla <Intro>. A continuacin puede pulsar sobre el
TCheckBox para activar la ordenacin de los elementos. Si deja
activada esta opcin, al aadir nuevos elementos stos se colocarn
directamente en las posiciones que le correspondan segn el orden
establecido. Pruebe tambin a seleccionar un elemento de la lista,
momento en que se activar el botn Borrar, y eliminarlo.
Tipo de biselado
bvNone
bvRaised
bvLowered
Ninguno
Resaltado
Hundido
begin
{ Segn el punto en que se haya soltado }
If x < 50 Then
{ establecemos una alineacin u otra }
Panel1.Align := alLeft
Else If X > Width - 50 Then
Panel1.Align := alRight
Else If Y < 50 Then
Panel1.Align := alTop
Else If Y > Height - 50 Then
Panel1.Align := alBottom;
end;
El evento OnDragOver se produce cuando un objeto est siendo
arrastrado sobre un control. En este caso, el evento lo recibe el
formulario cuando el panel se arrastra sobre el. En el mtodo asociado
a este evento primero comprobamos si el objeto que est siendo
arrastrado, que se recibe en el parmetro Source, es del tipo TPanel,
para lo cual utilizamos el operador Is. En caso afirmativo damos el
valor True al parmetro variable Accept, indicando as que aceptamos
ese objeto. Esto provoca que el icono del puntero del ratn cambie,
indicando la nueva situacin.
Cuando el objeto es soltado, el control que lo recibe, que en este
caso es el formulario, provoca un evento OnDragDrop. En ese momento
comprobamos el punto en que ha sido soltado el panel y, de acuerdo con
l, asignamos un valor u otro a la propiedad Align, haciendo que el
TPanel se ajuste al margen apropiado.
Ejecute el programa, en cuyo formulario tan slo existe el panel en la
parte inferior. Pnchelo y arrstrelo hasta los bordes del formulario,
soltndolo en cada uno de ellos. Podr comprobar cmo automticamente
se ajusta al margen que corresponda. En la figura 7.11 puede ver el
programa en ejecucin.
Figura a dibujar
Rectngulo
Cuadrado
Rectngulo
con
redondeadas.
Cuadrado
con
redondeadas.
Elipse.
Crculo.
las
las
esquinas
esquinas
Tipo de trazo
psSolid
psDash
psDot
Slido.
Guionado.
Punteado.
Guionado
y
punteado
alternativamente.
Guionado
y
punteado
alternativamente.
Ninguno.
Slido en el interior de la
figura.
psDashDot
psDashDotDot
psClear
psInsideFrame
Trama de relleno
Slida.
Ninguna.
bsHorizontal
bsVertical
bsFDiagonal
BsBDiagonal
bsCross
bsDiagCross
Lneas horizontales.
Lneas verticales.
Lneas diagonales en sentido \.
Lneas diagonales en sentido /.
Lneas
horizontales
y
vertivales cruzadas.
Lneas diagonales cruzadas.
del
el
de
&Salir, y
espacio en
ver como
entre las
Adems de las letras que precedemos con un signo & en los ttulos de
las opciones y que pueden ser utilizadas conjuntamente con la tecla
<Alt> para acceder de una forma ms rpida, cada opcin puede contar
adems con una tecla "caliente" o de acceso rpido.
Sitese en la opcin &Recuperar y a continuacin despliegue la lista
adjunta a la propiedad ShortCut, en el Inspector de objetos. Ver
aparecer una serie de teclas y combinaciones de tecla. Seleccione la
combinacin <Control+C>, que aparecer indicada en el men a la
derecha de la opcin. De igual forma puede asociar una tecla de acceso
rpido a las dems opciones.
Opciones con ms opciones
Ciertas opciones de un men pueden dar acceso a otras listas de
opciones, lo cual se indica mediante una flecha apuntando hacia la
derecha. El ejemplo ms cercano lo podemos encontrar en la opcin
Reopen del men File de Delphi.
Para aadir una lista de opciones a una opcin del men deberemos
pulsar la combinacin <Control+Flecha der>, o bien desplegar el men
emergente y seleccionar la opcin Crate Submenu. En cualquiera de los
dos casos se abrir una nueva lista a la derecha de la que ya
tenamos, en la que podemos introducir las opciones que deseemos.
Respuesta a la seleccin de una opcin
Al igual que un botn o una lista, un men genera un evento OnClick
cuando se selecciona una cierta opcin. Para acceder al cdigo del
mtodo asociado a una de las opciones existentes, lo nico que tenemos
que hacer es seleccionarla durante el diseo en el mismo formulario,
tras haber cerrado el Editor de mens. Tambin podemos hacer doble
clic sobre la opcin deseada en el propio Editor de mens, continuando
posteriormente con la tarea de diseo.
Observe que cada una de las opciones de
diferente, concretamente de tipo TMenultem,
propio evento, lo cual es lgico, ya que de
que buscar alguna forma de saber qu opcin es
un men es un objeto
y por tanto genera su
lo contrario tendramos
la que" se seleccion.
al
formulario,
un
botn
7.18.3. En la prctica
El uso de los mens de opciones es muy simple, ya que prcticamente no
cuentan con ningn elemento adicional a los que ya conocemos.
Practique diseando diversos mens, tanto de tipo TMainMenu como
TPopupMenu, y escribiendo algo de cdigo asociado al evento OnClick de
cada opcin, con el fin de comprobar su funcionamiento.
8. Depuracin y excepciones
8.1. Introduccin
Mientras se desarrolla y ejecuta una aplicacin, generalmente surgen
errores que le impiden funcionar en la forma en que nosotros
esperbamos. Los errores posibles los podemos agrupar en tres bloques:
errores de compilacin, errores de ejecucin y errores lgicos.
Los errores de compilacin, como su propia denominacin indica, son
detectados por Delphi en el momento en que se compila el programa. En
estos casos no se permite la ejecucin, y en la parte inferior de la
Ventana de cdigo se abre una lista con la descripcin del error o
errores encontrados, permitindonos el desplazamiento a la lnea
apropiada. Estos errores se producen cuando se teclea mal un
identificador, una expresin no es vlida, hemos olvidado cerrar unos
parntesis, etc.
Por su parte, los errores de ejecucin no son detectables durante la
compilacin y surgen de forma espordica mientras el programa se
ejecuta. Si no est adecuadamente controlado, un error de ejecucin
puede terminar interrumpiendo la ejecucin de la aplicacin. Estos
errores se producen, por ejemplo, cuando se intenta abrir un archivo y
ste no existe, se realiza una conversin no vlida, etc. Para
controlar estos errores tendremos que conocer y controlar excepciones,
un tema que trataremos ms adelante en este captulo.
El tercer grupo de errores, a los que llamamos lgicos, no son
detectados por Delphi durante la compilacin ni tampoco por el
programa durante la ejecucin. Estos errores no hacen nada incorrecto
sintcticamente hablando pero, sin embargo, impiden que el programa
funcione de forma normal. Errores de ese tipo se producen cuando en
una expresin se ha usado la variable que no corresponda, se llama a
un procedimiento o funcin con un parmetro que no se esperaba, etc.
El nico mtodo por el cual podemos detectar y encontrar estos
errores, aparte de la propia intuicin, consiste en llevar a cabo una
sesin de depuracin.
para
poder
pasar a la
encontramos.
sentencia
siguiente
del
mismo
bloque
en
el
que
nos
9.1. Introduccin
Los ejemplos que se han propuesto hasta ahora, en captulos
anteriores, han sido tan simples que estaban compuestos de slo un
formulario. En la prctica, la mayora de los programas se sirven de
mltiples ventanas, lo podemos ver, por ejemplo, en Delphi. Por regla
general siempre existe una ventana principal, en la que se encuentra
el men de opciones, y una serie de ventanas accesorias que pueden
estar visibles siempre o slo cuando son necesarias. En el captulo
anterior, por ejemplo, vimos cmo podamos abrir ventanas con puntos
de parada, visualizadores, una pila de llamadas, etc., ventanas que
habitualmente no estn visibles a diferencia del formulario, el Editor
de cdigo o el Inspector de objetos.
Un programa puede utilizar mltiples ventanas simplemente para
solicitar una determinada informacin, como puede ser el nombre del
archivo que se desea recuperar o el color que se quiere utilizar, o
bien para facilitar la edicin de mltiples documentos. Las ventanas
del primer tipo se suelen construir como cuadros de dilogo, nombre
con el que se conoce a aquellas ventanas que no pueden ser
redimensionadas, no cuentan con botones de maximizar o minimizar y que
adems son modales, no permitiendo seguir trabajando con la aplicacin
hasta en tanto no son cerradas. Un cuadro de dilogo es lo que
aparece, por ejemplo, cuando seleccionamos la opcin de abrir un
proyecto existente. En caso de que el programa sea capaz de permitir
el trabajo con mltiples documentos de forma simultnea, stos puebien
en una interfaz de documento mltiple, que se conoce como MDI. Delphi
utiliza una ventana independiente para cada formulario y para el
cdigo, Microsoft Word 97, por ejemplo, usa una interfaz MDI.
opcin Use Unit del men File, que nos mostrar una ventana en la que
podremos seleccionar directamente el mdulo a usar.
9.2.1. El formulario principal del programa
En un proyecto tan slo puede existir un formulario principal, que es
aquella que se muestra inicialmente cuando se ejecuta el programa. Por
defecto el formulario inicial es aquel que exista al comenzarse el
proyecto o el que se insert en primer lugar si es que el proyecto
estaba vaco.
Realmente el formulario principal no cuenta con ninguna diferencia
especial respecto a los otros formularios y cualquiera de ellos puede
actuar como formulario principal. Para establecer el formulario
principal del proyecto deberemos utilizar la opcin Options del men
Project, que dar paso a una ventana como la que se muestra en la
figura 9.1. En esta ventana existe una lista desplegable, en la parte
superior, en la que podremos indicar qu formulario actuar como
principal.
siendo
Significado
ofAllowMultiSelect
ofCreatePrompt
ofFileMustExist
ofHideReadOnly
ofNoChangeDir
ofNoValidate
ofOverWritePrompt
ofReadOnly
ofPathMustExis
ofShowHelp
Significado
Mostrar slo tipos de letras con conjunto de
caracteres Windows.
Mostrar las opciones de tachada, subrayada y
color del texto.
Mostrar slo tipos de letras de espaciado fijo.
Avisar al usuario en caso de que seleccione un
tipo de letra no disponible.
Limitar el tamao de la letra al rango facilitado
en MinFontSize y MaxFontSize.
No seleccionar un tipo de letra inicial.
Mostrar slo tipos de letra no vectoriales.
Mostrar slo tipos de letra escalables.
No mostrar tipos de letras que sean simulaciones.
No seleccionar un tamao de letra inicial.
No seleccionar un estilo inicial.
Igual a fdNoOEMFonts.
Mostrar un botn de ayuda.
Mostrar slo tipos de letra TrueType.
fdWysiwyg
en
end;
Como puede ver, seleccionamos inicialmente en el cuadro de dilogo el
tipo, tamao y estilo de letra del propio botn, mostrando a
continuacin la ventana que puede ver en la figura 9.3. En caso de que
se pulse el botn Aceptar, se asigna al botn la propiedad Font del
cuadro de dilogo, aplicando as la seleccin que hayamos efectuado.
Constante
Significado
cdShowHelp
cdFullOpen
cdPreventFullO
pen
anterior el componente
el cdigo asociado al
como se muestra a
cuadro de dilogo de
el color del fondo del
Se imprimir
Todo el documento.
La parte del documento que est seleccionada.
Un rango de pginas.
Significado
poHelp
poPageNums
poSelection
poPrintToFile
poWarning
Significado
frDown
frFindNext
frHideMatchCase
frDisableMatchCase
frHideWholeWord
frDisableWholeWord
frHideUpDown
frMatchCase
frWholeWord
frReplace
frReplaceAll
frShowHelp
Puesto que este formulario va a ser una ventana hija MDI, deberemos
dar el valor fsMDIChild a la propiedad FormStyle, Por lo dems, no
tendremos que alterar ninguna propiedad ms del formulario.
Para visualizar y permitir la edicin del texto insertaremos en el
formulario un control TMemo, que ocupar todo el espacio disponible en
la ventana, por lo que daremos el valor alClient a la propiedad Align.
Este control contar con una barra de desplazamiento vertical, siendo
preciso, por tanto, modificar la propiedad ScrollBars seleccionando el
valor ssVertical. Tambin modificaremos la propiedad WantTabs,
asignndole el valor True.
9.4.3. El cdigo del formulario principal
Procedamos ahora con la escritura del cdigo necesario para hacer que
nuestro programa funcione segn el diseo que estamos esbozando. Lo
primero que tendremos que hacer es utilizar la opcin Use Unit del
men File, para aadir al mdulo de cdigo del primer formulario una
referencia a la segunda, lo que nos permitir acceder a la definicin
de TForm2.
El ttulo de cada una de las ventanas hija ser algo que
estableceremos durante la ejecucin. En caso de que la ventana se cree
abrindose un archivo existente, el ttulo ser el nombre del archivo.
Si, por el contrario, la ventana se ha creado vaca, asignaremos como
ttulo la palabra Nuevo, seguida de un nmero que se ir incrementando
secuencialmente. Este contador lo declararemos al nivel de mdulo,
delante de cualquier mtodo.
Var
Contador: Integer;
Creacin de un nuevo archivo
La primera opcin que encontramos en el men Archivo es la opcin
Nuevo, cuya finalidad es crear una ventana hija vaca, permitindonos
as la creacin de un nuevo archivo de texto. Seleccione esta opcin
en el formulario, durante el diseo, para abrir el Editor de cdigo
por el mtodo correspondiente, en el que escribiremos el cdigo que se
muestra a continuacin.
{ Al pulsar la opcin Muevo }
procedure TForm1.Nuevo1Click(Sender: TObject);
begin
{ creamos un nuevo formulario bijo }
With TForm2.Create(Self) Do
Begin
{ Incrementamos el contador }
Inc(Contador);
{ Establecemos el titulo }
Caption := 'Nuevo ' + IntToStr(Contador);
Show; { y la mostramos }
End;
End;
Bsicamente creamos el formulario, con una llamada al consructor
Create(), asignndole a continuacin un ttulo y mostrndolo, con una
llamada al mtodo Show(). Observe que los formularios hijos MDI se
visualizan como ventanas no modales, ya que de lo contrario no sera
posible cambiar de un documento a otro en ejecucin.
Guardar un archivo
La opcin Guardar del men Archivo no debe estar accesible en caso de
que no exista actualmente una ventana hija abierta, ya que de lo
contrario se podra llamar al mtodo correspondiente cuando en
realidad la operacin no puede llevarse a cabo. Con el fin de que esta
opcin aparezca activada o desactivada segn proceda/ vamos a hacer
doble clic en el men Archivo, desde el Editor de mens, para abrir el
mtodo correspondiente al evento OnClick de este men, que se produce
cuando accedemos a l para desplegarlo. En este mtodo insertaremos
una sentencia, como puede ver a continuacin, en la que asignaremos a
la propiedad Enabled de la opcin el valor True o False, dependiendo
de que exista o no un formulario hijo activo en ese momento.
{ Al desplegar el men Archivo }
procedure TForm1.Archivo1Click(Sender: TObject);
begin
{ Desactivamos la opcin Guardar en caso de que no existe una
ventana hija activa }
Guardar1.Enabled := ActiveMDIChild <> Nil;
end;
Si la opdn Guardar est activa y la seleccionamos, lo primero que
tendremos que hacer ser solicitar un nombre de archivo, para lo cual
utilizaremos el componente TSaveDialog. A continuacin obtendremos una
referencia a la ventana hija que est activa en ese momento, mediante
la propiedad ActiveMDIChild, realizando la necesaria conversin al
tipo TForm2. Esto nos permitir acceder al control TMemo que contiene
el texto y realizar una llamada al mtodoSaveToFile().
A continuacin asignaremos a la propiedad Caption del formulario el
nombre del archivo seleccionado y, por ltimo, daremos el valor False
a la propiedad Modified del control TMemo, para indicar que no se ha
modificado desde la ltima grabacin. El mtodo completo es el que se
muestra a continuacin.
{ Al pulsar la opcin Guardar }
procedure TForm1.Guardar1Click(Sender: TObject);
begin
{ Si se selecciona un nombre de archivo }
If SaveDialog1.Execute Then
del
men
File,
que
que
que
al
los
por
ser
esa
posiblemente
que se trate
que deseamos
tipo antiguo
la necesaria
La modificacin del contenido de una tabla es una tarea muy simple con
el Database Desktop. Inicialmente nos encontramos en el modo de
visualizacin, por lo que podemos movemos por la tabla pero no
realizar tareas de edicin, tales como modificar un dato, aadir un
nuevo registro o borrar un registro existente. Para pasar al modo de
edicin bastar con pulsar la tecla <F9> o el botn que est en el
extremo derecho de la parte superior de la ventana.
10.5.1. Edicin de datos
Encontrndonos en el modo de edicin, lo cual est indicado por el
botn citado anteriormente y un pequeo letrero en la barra de estado,
en la parte inferior de la ventana, podemos realizar diversas tareas
de edicin con la tabla que tenemos abierta.
Para aadir un nuevo registro deberemos desplazamos hasta el final de
la tabla, pulsando la <Flecha abajo> cuando nos encontremos en el
ltimo registro. Esto provocar que se aada un registro en blanco, en
el que podremos introducir los valores que deseemos de forma
inmediata.
Si deseamos insertar un registro en una posicin determida, en lugar
de hacerlo al final de la tabla, deberemos situarnos en el punto que
nos interese, pulsando a continuacin la tecla <Insert>, que abrir un
espacio vaco desplazando todos los registros inferiores. Hecha esta
operacin, podemos introducir los valores para el registro de igual
forma que hacamos en el caso anterior. Tenga en cuenta que si la
tabla tiene un ndice activo, el orden de los registros vendr
determinado por el valor de los campos que forman parte de ese ndice,
por lo que dar igual el punto en donde lo insertemos o aadamos.
Tambin podemos, encontrndonos en el modo de edicin eliminar
registros de la tabla. Para ello lo primero que deberemos hacer es
situamos sobre el registro a borrar, pulsando a continuacin la
combinacin de teclas <Ctrol+Supr>. A diferencia de otras operaciones,
como la modificacin de un campo, el borrado de un registro no puede
deshacerse posteriormente con el comando Undo del men Edit.
A la hora de modificar un campo de un registro ya existente, podemos
optar por introducir un nuevo valor, eliminando el anterior, o bien
por modificar el dato que se muestra. Por defecto la ventana de
edicin se encuentra en un modo que permite que las teclas de cursor
sean usadas para desplazarse al campo anterior o siguiente. En este
modo, la introduccin de un valor en un campo elimina el contenido
anterior. Podemos pasar al modo de edicin de campo pulsando la tecla
<F2>, o el penltimo botn de la barra, de tal forma que las teclas de
cursor permitan el desplazamiento por los caracteres del campo,
facilitando as la modificacin de un valor.
10.6. Consultas
La seleccin de una tabla con la nica finalidad de ver su contenido
tiene como consecuencia la visualizacin de todos sus campos y todos
sus registros, es decir, se muestra toda la informacin que contiene
la tabla. A veces, sin embargo, podemos necesitar recuperar slo
algunos de los datos con el fin, por ejemplo, de generar un cierto
listado o informe. En estos casos lo que se hace es disear y ejecutar
una consulta.
Database Desktop soporta dos tipos de consultas diferentes, a las que
se denomina QBE (Query By Example) y SQL (Structured Query Language).
La primera de ellas, ms simple e intuitiva, se basa en la composicin
de la consulta a partir de unos datos facilitados como ejemplo. La
segunda, mucho ms conocida, se basa en el uso del lenguaje de
consulta de bases de datos SQL, un estndar prcticamente general.
10.6.1. Construccin de una consulta QBE
Para crear una consulta QBE tendremos que seleccionar la opcin New
del men File, eligiendo la opcin QBE Query del submen adjunto. Esto
nos llevar a una ventana en la que tendremos que seleccionar la tabla
sobre la que se va a realizar la consulta, para lo cual podemos partir
por especificar el alias, pulsando seguidamente sobre la tabla
deseada. Hecho esto aparecer una ventana, como la mostrada en la
figura 10.10, en la cual podremos componer la consulta.
11.1. Introduccin
Habiendo diseado la estructura de la base de datos que necesitamos
para nuestra aplicacin y definido las tablas que la vayan a
conformar, usando el Database Desktop, estaremos ya preparados para
usar dichas tablas en nuestros programas, para lo cual necesitaremos
conocer los componentes enlazados a datos de Delphi.
En la Paleta de componentes de Delphi existe una pgina, llamada Data
Access, que contiene componentes no visuales de acceso a bases de
datos. Estos componentes nos servirn, por ejemplo, para crear un
enlace entre una tabla de la base de datos y nuestro programa, o para
crear y ejecutar una consulta. A la derecha de esa pgina existe otra,
llamada Data Controls, en la que encontraremos los controles enlazados
a datos, una serie de componentes visuales cuya finalidad es mostrar y
permitir la modificacin de los datos que se almacenan en cada campo.
11.3.Tablas y consultas
Acabamos de ver lo fcil que resulta crear en Delphi un programa para
manipular los datos de una tabla, sin necesidad de escribir nada de
cdigo y tan slo con unas pocas operaciones de ratn, ya que
prcticamente tampoco hemos tenido que edificar propiedades. Esta
simplicidad, sin embargo, no est reida con la flexibilidad y la
potencia, y los componentes de bases de datos de Delphi cuentan con
ambas caractersticas.
11.3.1. El componente TTabIe
Desde un programa Delphi podemos acceder a los datos de una sla
tabla, a todos sus datos, o bien a datos parciales de una o ms
tienen
correspondencia
con
TDBNavigator o TDBControlGrid.
ningn
control
normal,
como
es
TIntegerField
TSmallIntField
TWordField
TStringField
TFloatField
TBCDField
TBooleanField
TDateTimeField
TDateField
TTimeField
TBlobField y TBytesField
TVarBytesField
TMemoField
TGraphicField
los
mtodos
AsString,
AsBoolean,
tambin puede
anteriormente.
ser
cancelada
mediante
el
mtodo
Cancel()
visto
end;
Lo primero que hacemos es eliminar cualquier contenido de la lista,
realizando una llamada al mtodo Clear() de la propiedad Items. Esto
evitar que en la lista se acumulen resultados de varias bsquedas. A
continuacin nos desplazamos hasta el primer registro de la tabla y
usamos el mtodo FindKey() para buscar la provincia introducida en el
TEdit. En caso de que se encuentre una coincidencia, aadimos el
nombre del registro encontrado a la lista, avanzando al registro
siguiente con una simple llamada al mtodo Next(). Estas dos ltimas
sentencias se repetirn continuamente, hasta en tanto no se encuentre
una editorial diferente o se llegue al ltimo registro de la tabla.
12. Creacin de Informes
12.1. Introduccin
En Delphi 5 el diseo de informes se basa en el uso de los componentes
QuickReport, que encontraremos en la pgina QReport de la Paleta de
componentes. Mediante estos componentes es posible disear un informe
fcilmente, utilizando un formulario para la composicin visual. La
ventaja de QuickReport frente a otras herramientas de diseo de
informes se trata de un conjunto de componentes VCL y, como tal su
cdigo pasa a formar parte de nuestro propio programa sin necesidad
as de tener que distribuir aplicaciones separadas. Adems, la
generacin de un informe con QuickReport es ms rpida, ya que no es
necesaria la ejecucin de un programa independiente.
lo largo de este captulo vamos a aprender a usar los componentes
QuickReport para generar informes simples. Los datos que utilizaremos
sern los de la tabla de libros que se cre
como ejemplo en el
captulo 9 y se ha usado en diversos ejemplos del 10.
Pulsando el botn Preview se har una vista previa del informe, como
se observa en la figura 12.2, vaca puesto que an no se han insertado
datos en el informe, aunque ya contamos con una serie de botones que
nos permiten ajustar la visualizacin e imprimir el informe.
Figura 12.2.
Tipo de seccin
rbTitle
rbPageHeader
rbDetail
rbChild
rbPageFooter
rbSummary
rbGroupHeader
rbGroupFooter
rbColumnHeader
rbOverlay
de
su
tipo,
puede
tomar
una
Informacin a mostrar
Hora de impresin del informe.
Fecha de impresin del informe.
Fecha y hora de impresin del informe.
Nmero de pgina actual.
Ttulo del informe.
Nmero total de registros en el informe.
Nmero de registro actual.
forma, es el equivalente
captulo anterior.
al
control
TShape
que
conocimos
en
un
Segn el valor que asignemos a la propiedad Shape, que ser uno de los
que se enumeran en la tabla 12.3, aparecer en el informe una figura u
otra. El borde e interior de la figura puede tener un color u otro y
un tipo de relleno u otro, dependiendo de las propiedades Brush y Pen,
cuyo funcionamiento tambin conocemos.
Constante
Figura a dibujar
qrsRectangle
qrsCircle
qrsVertLine
qrsHorLine
qrsTopAndBottom
qrsRightAndLeft
Rectngulo
Crculo.
Una lnea vertical.
Una lnea horizontal.
Lneas horizontales arriba y abajo.
Lneas verticales a la izquierda y derecha.
13.1. Introduccin
Una de las caractersticas de Delphi 5 es su total soporte para los
controles avanzados de Windows 95/98 y NT, que bsicamente realzan la
interfaz y facilitan su uso. Estos componentes los encontramos en la
pgina Win32 de la Paleta de componentes y vamos a conocer los ms
importantes a lo largo de este captulo.
y Adems de en Windows 95/98, muchos de estos componentes tambin
podrn utilizarse en Windows NT 3.51 si tiene instalada la nueva
interfaz, as como en la versin 4.0, que utiliza ya el nuevo aspecto
creado por Microsoft en Windows 95.
Tipo de marca
Ninguna.
Automtica.
Manual.
las
marcas
{ Al pulsar el TButton }
procedure TForm1.Button1Click(Sender: TObject);
begin
// Fijamos el valor mximo
ProgressBar1.Max := StrToInt(Edit1.Text);
// Activamos el TTimer y desactivamos el TButton
Timer1.Enabled := True;
Button1.Enabled := False;
end;
Para evitar que se puedan introducir valores no numricos, lo cual
causara un error de conversin al utilizar la funcin StrTolnt(),
controlaremos cada pulsacin de tecla que se produzca en el TEdit,
aprovechando para ello el evento OnKeyPress. En el mtodo asociado a
este evento comprobaremos si el carcter pulsado es un dgito
numrico, ignorndolo en caso contrario.
{ Con cada pulsacin en el TEdit }
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
// Ignorar cualquier pulsacin que no sea un dgito numrico o
// la tecla de borrado
If Not (Key In ['0'..'9', #8]) Then
Key := #0;
end;
Una vez que el proceso est puesto en marcha, cada vez
que el TTimer genere un evento deberemos incrementar el indicador de
estado del proceso, para lo cual bastar una llamada al mtodo
StepIt(). A continuacin comprobaremos si hemos llegado al final del
proceso, caso ste en el que desactivaremos el TTimer, activaremos de
nuevo el TButton y daremos el valor cero a la propiedad Position del
TProgressBar, como puede ver en el cdigo siguiente.
{ Con cada evento del TTimer }
procedure Tform1.Timer1Timer(Sender: TObject);
begin
With ProgressBar1 Do
Begin
StepIt; // Incrementamos el proceso
If Position = Max Then // Si ya se ha completado
Begin
Position := 0; // Ponemos a cero la posicin
// Desactivamos el TTimer y reactivamos el TButton
Timer1.Enabled := False;
Button1.Enabled := True;
End;
End;
end;
13.5.4. En la prctica
Con el fin de ver en la prctica cmo podemos usar un control
THeaderControl en nuestros programas, vamos a desarrollar un ejemplo
en el cual usaremos la superficie del formulario como rea de trabajo,
listando en ella el contenido de la tabla de alumnos que utilizbamos
en los ejemplos de los dos captulos anteriores.
Definiremos una cabecera con tres secciones, en las cuales mostraremos
el Nombre, sexo y provincia de cada alumno. Estas tres secciones se
podrn redimensionar durante la ejecucin, permitiendo que el usuario
adecu su anchura segn desee.
Puesto que vamos a usar el formulario como si de un papel se tratase,
imprimiendo datos en su superficie, vamos a cambiar el color de fondo
haciendo que ste sea blanco. Por tanto, deber asignar el valor
clWhite a la propiedad Color.
Inserte en el formulario un componente TTable, asignando los valores
adecuados a las propiedades DatabaseName y TableName para poder
acceder a la tabla de alumnos. D tambin el valor True a la propiedad
Active. Puesto que no vamos a usar ningn control de base de datos, no
necesitaremos insertar un componente TDataSource. Con el fin de poder
acceder directamente a los objetos TField que representan a cada
campo, haga doble clic sobre el TTable, para abrir el Editor de
campos, pulse la combinacin <Control+A> y aada todos los campos a la
lista.
Tan slo existir un componente ms en el formulario, un control
THeaderControl. Edite la propiedad Sections definiendo las tres
secciones citadas antes, de tal forma que el formulario quede
aproximadamente como se muestra en la figura 13.6.
SetLength(Cadena, Length(Cadena)-1);
Canvas.TextOut(X, Y, Cadena);
Inc(X, HeaderControl1.Sections[1].Width);
{ volvemos a repetir, en este caso con la provincia }
Cadena := Table1Provincia.Value;
While Canvas.TextWidth(Cadena) >
HeaderControl1.Sections[2].Width Do
SetLength(Cadena, Length(Cadena)-1);
Canvas.TextOut(X, Y, Cadena);
Next; // Pasamos al registro siguiente
// e incrementamos la coordenada vertical
Inc(Y, Canvas.TextHeight(Cadena));
Until EOF; // Repetir hasta mostrar todos los registros
End;
end;
Cada vez que modifiquemos durante la ejecucin el ancho de una de las
secciones o bien las dimensiones del formulario, el contenido de sta
deber ser dibujado de nuevo. Para forzar esta accin realizaremos una
llamada al mtodo Invalidate() del formulario siempre que se produzcan
los evento OnResize y OnSectionResize, como puede ver a continuacin.
{ Al modificar el ancho de una seccin )
procedure TForm1.HeaderControl1SectionResize (HeaderControl:
THeaderControl;Section: THeaderSection);
begin
Invalidate; // Invalidamos el contenido del formulario
end;
{ Al modificar l tamao del formulario }
procedure Tform1.Form1Resize(Sender: TObject);
begin
Invalidate; // Tambin invalidamos su contenido
end;
Al ejecutar el programa los datos se mostrarn con el ancho prefijado
en la fase de diseo, pero bastar con que tome uno de los extremos de
cada seccin para poder ampliarla o reducirla. En la figura 13.7 puede
ver el aspecto que muestra el programa tras algunos ajustes durante la
ejecucin.
de
corresponda
segn
el
iconos
Modo de visualizacin
vsIcon
vsSmallIcon
vsList
vsReport
ArDefault
ArAlignBottom
ArAlignLeft
ArAlignRight
ArAlignTop
nombre del
edad, sern
esta forma
cada uno de
RichEdit1.SetFocus;
end;
Al ejecutar el programa podr utilizar un atributo normal, con letra
negrita, con letra cursiva o con una combinacin de ambas. Observe que
la activacin o desactivacin de estos atributos slo afecta al texto
que se escriba a continuacin, o bien al que haya seleccionado en ese
momento.
14.1. Introduccin
En ocasiones, al disear las interfaces de una aplicacin y escribir
el cdigo asociado, se repiten algunas operaciones comunes en el
desarrollo. Los cuadros de dilogo suelen incluir algunos conjuntos de
botones comunes, ciertas acciones estn accesibles desde diferentes
puntos del programa, etc. Delphi 5 pone a nuestra disposicin diversos
mtodos para reutilizar el trabajo, evitando as la repeticin de
procesos con la consecuente prdida de tiempo en ellos.
men emergente
uno de ellos y
para elegir la
ShowHint.
Puesto que lo que nos interesa es ver cmo utilizar una lista de
acciones, no la finalidad en s de las propias acciones, haga doble
clic sobre cada elemento del TActionList insertando cualquier cdigo,
por ejemplo una llamada al mtodo ShowMessage() para indicar que se ha
seleccionado la opcin.
procedure TForm1.CopiarExecute(Sender: TObject);
begin
ShowMessage('Copiar');
end;
procedure TForm1.CortarExecute(Sender: TObject);
begin
ShowMessage('Cortar');
end;
procedure TForm1.PegarExecute(Sender: TObject);
begin
ShowMessage('Pegar');
end;
Llegados a este punto, ya puede ejecutar el programa y ver el
resultado. Observe que las opciones tanto del men principal como del
men emergente muestran a su izquierda los mismos iconos que hay en la
barra de botones. Los botones de la barra, por su parte, muestran como
mensaje de ayuda el ttulo de las opciones del men. Todas estas
opciones y botones comparten el mismo cdigo, ya que estn asociadas a
las mismas acciones.
Figura 14.8. La Paleta de componentes tiene una pgina con los marcos
Tenga en cuenta que al reutilizar un marco no slo consigue incluir un
componente formado de otros, sino tambin todo el cdigo asociado que
haya podido escribir. Es decir, no se trata tan sol de componer una
plantilla de controles para despus insertarlos con mayor facilidad,
sino de reutilizar una funcionalidad completa.
14.3.4. Un ejemplo
Utilizar los marcos es algo bastante sencillo. Para comprobarlo,
inicie un nuevo proyecto y, a continuacin, cree un nuevo marco
insertando en l dos etiquetas de texto y una lista combinada, como se
mostr anteriormente. Asigne a la propiedad Items de la lista
combinada los nombres de los meses. Abra la pgina de eventos en el
Inspector de objetos y, teniendo seleccionada la lista combinada, haga
doble clic sobre el evento OnClick, introduciendo el cdigo siguiente:
procedure TfrmSeleccionMes.cbMesesClick(Sender: TObject);
Const
DiasMes: Array[0..11] of Smallint =
(31,28,31,30,31,30,31,31,30,31,30,31);
begin
LbDias.Caption:=IntToStr(DiasMes[cbMeses.ItemIndex])+' das';
end;
Figura 15.1
Dentro de la formulario New Items elija Component y aparecer un nuevo
formulario en el que se mostrarn los siguientes campos:
SysUtils,
type
TRealEdit = class(TEdit)
Classes,
Graphics,
Controls,
Forms,
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TRealEdit]);
end;
end.
Observe
que
delphi
incluye
automticamente
el
procedimiento
RegisterComponents que registrar el componente en el entorno
permitiendo su visualizacin en la paleta de componentes y su edicin
con el Object Inspector.
Una vez aqu podemos comenzar a aadir las propiedades y los mtodos
que formarn parte del nuevo componente o modificar comportamientos
heredados de la superclase.
En ocasiones nos preguntaremos cul ser un buen ancestro para nuestro
nuevo
componente
con
el
objetivo
de
sacar
mejor
partido
a
funcionalidades ya existentes. He aqu varias normas:
);
);
override;
write SetMinVal;
write SetMaxVal;
FMaxVal := AMaxVal;
end;
procedure TRealEdit.DoExit;
var
Value: real;
Code: integer;
begin
Val( Text, Value, Code );
if (code = 0) and ( Value>=FMinVal ) and (Value<=FMaxVal)
then inherited DoExit
else
begin
application.messagebox('El
valor
del
campo
es
incorrecto',
'Error', MB_OK);
SetFocus;
end;
end;
procedure Register;
begin
RegisterComponents('Samples', [TRealEdit]);
end;
...
Lo interesante de la implementacin es la reimplementacin del
procedimiento DoExit. Por definicin el procedimiento DoExit heredado
se invoca cuando se produce un evento del tipo OnExit. Este ltimo se
produce siempre que un componente visual pierde el foco es decir deja
de estar activo. El nuevo DoExit de nuestro componente permite que una
vez que el mismo pierde el foco, se compruebe que se ha editado
realmente un nmero real y que este se encuentra en el rango entre el
valor de MinVal y MaxVal. De cumplirse la condicin anterior se
ejecuta el DoExit heredado causando un comportamiento normal, de lo
contrario se muestra un cuadro de mensaje indicando el error y se le
regresa el foco al componente en cuestin.
interface
uses
Classes;
type
TFaC = class(TComponent)
private
FFValue: real;
function GetValueInCelcius: real;
protected
public
property Celcius: real read GetValueInCelcius;
published
property Farenheit: real read FFValue write FFValue;
end;
procedure Register;
implementation
function TFaC.GetValueInCelcius: real;
begin
Result:=(5*(FFValue-32))/9;
end;
procedure register;
begin
registercomponents('Samples', [TFaC]);
end;
end.
Observe que en el ejemplo anterior hemos heredado de TComponent por
tratarse de un componente no visual.
Nota: Es una buena idea antes de comenzar hacer una copia de seguridad
del archivo COMPLIB.DCL para evitar posibles problemas derivados de
fallos al compilar.
propiedades
debe
dar
respuesta
dos
aspectos
para
escribir
un
editor
de
de
de
la
de
Tipo
Clase base para todos los editores de
propiedades
Byte, word, integer, Longint
TCharProperty
Char
TEnumProperty
Tipos enumerados
TSetProperty
TFloatProperty
TStringProperty
TClassProperty
TMethodProperty
TComponentProperty
Sets
Single, Double, Extended, Comp, Currency
Strings
Cualquier objeto
Cualquier mtodo (eventos)
Para propiedades que hacen referencia a
componentes
Registrar el
Library(VCL)
editor
de
propiedades
en
la
al
Visual
editor
de
Component
Ms
adelante
profundizaremos
en
todos
aspectos
segn
vayamos
desarrollando distintos editores, pero ahora ha llegado del momento de
crear nuestro primer editor de propiedades.
Insert('B',Result,1);
end;
...
end.
De la implementacin de esta funcin la parte ms importante es la
primera lnea:
Num:=GetOrdValue
Necesitamos obtener el valor que tiene en ese momento la propiedad
para trabajar sobre l. Para ello utilizamos el mtodo GetOrdValue,
definido de nuevo en TPropertyEditor, el cul se encarga de devolver
el valor de la propiedad en forma de ordinal (integer). De forma
anloga,
existen
los
mtodos
GetFloatValue,
GetMethodValue,
GetVarValue,
etc.
para
utilizar
con
el
tipo
de
propiedad
correspondiente.
Una vez almacenado el valor de la propiedad en la variable Num,
comienza la conversin del valor de decimal a binario, la cul es
fcil de entender. Es bueno notar que el nmero mximo de digitos
binarios soportados es 16, margen ms que suficiente para la mayora
de aplicaciones. Por ltimo tenemos que devolver un valor de tipo
string como resultado de la funcin. Para ello vamos almacenando en la
variable Result el string a devolver. Para finalizar, anteponemos la
letra 'B' a la cadena para indicar que se trata de base binaria. Y eso
es todo en lo que a esta funcin respecta. De este modo, cuando el
inspector de objetos deba mostrar el valor de la propiedad, llamar a
el mtodo GetValue el cul le devolver el string correspondiente.
Pero nos queda la otra mitad: estara bien que pudiramos introducir
el valor de la propiedad tanto en decimal como en binario segn nos
interesase pues vamos a ello.
Para conseguir esta funcionalidad debemos implementar (override) el
mtodo SetValue, definido de nuevo en la clase TPropertyEditor. Cuando
el usuario entra un nuevo valor usando el inspector de objetos, este
llama al mtodo SetValue, el cul debe efectuar la traduccin inversa
a la efectuada por el mtodo GetValue. Es decir, debe convertir el
string que contiene el nuevo valor de la propiedad al tipo de datos de
dicha propiedad. En nuestro caso, el string vendr en base decimal o
binaria (en este ltimo caso, la primera letra de la cadena ser una
'B') y habr que convertirlo a base decimal. Para ello implementaremos
el mtodo SetValue de la siguiente forma:
...
type
TBinIntegerProperty = class(TIntegerProperty)
public
function GetValue : string; override;
procedure SetValue(const Value : String); override;
end;
procedure Register;
implementation
...
procedure TBinIntegerProperty.SetValue(const Value : String);
Var
i, Total, Longitud : integer;
NumText : string;
begin
if UpperCase(Value[1])='B' then
begin
NumText:=Copy(Trim(Value),2,Length(Trim(Value))-1);
NumText:=Copy('0000000000000000',1,16-Length(NumText)) + NumText;
Total:=0;
for i:=1 to Length(NumText) do
begin
if not (NumText[i] in ['0','1']) then
raise EPropertyError.Create(NumText[i] + ' is not a valid
binary digit')
else if NumText[i]='1' then
Total:=Total+Bits16[i];
end;
SetOrdValue(Total);
end
else
SetOrdValue(StrToInt(Value));
end;
...
end.
En la implementacin de este mtodo primero comprobamos si el usuario
ha introducido el nuevo valor de la propiedad en base decimal o en
base binaria. En el primer caso, tan slo hay que convertir el string
a integer mediante la funcin StrToInt(Value) y, a continuacin,
utilizar
el
mtodo
SetOrdValue
para
almacenar
el
valor
correspondiente. De forma anloga, segn el tipo de la propiedad,
existen los mtodos SetFloatValue, etc.
En el caso de que la primera letra de la cadena sea una 'B', se
convierte la cadena con el valor binario a base decimal y se vuelve a
utilizar el mtodo SetOrdValue para almacenar el valor en la
propiedad.
Una vez implementados estos dos mtodos (GetValue y SetValue) ya
tenemos nuestro editor de propiedades terminado; tan slo nos queda un
pequeo, pero indispensable paso, registrarlo en la VCL.
Type
TMiComponente = class(TComponent)
...
property PropiedadBinaria : integer read FPropBin write FPropBin;
...
end;
...
clusula
editor.
uses
las
unidades
correspondientes
segn
donde
sites
el
unit BinaryPropEd;
interface
uses DsgnIntf;
type
TBinIntegerProperty = class(TIntegerProperty)
public
function GetValue : string; override;
procedure SetValue(const Value : String); override;
end;
procedure Register;
implementation
Const
Bits16 : Array [1..16] of Integer =
(32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1);
function TBinIntegerProperty.GetValue : string;
Var
Num, i : integer;
begin
Num:=GetOrdValue;
Result := '0000000000000000';
for i := 1 to 16 Do
if ( Num >= Bits16[i] ) Then
begin
Num := Num - Bits16[i];
Result[i] := '1';
end;
if ( Num > 0 ) Then
raise EPropertyError.Create('Error converting
'+IntToStr(GetOrdValue) + ' to binary');
Insert('B',Result,1);
end;
procedure TBinIntegerProperty.SetValue(const Value : String);
Var
i, Total, Longitud : integer;
NumText : string;
begin
if UpperCase(Value[1])='B' then
begin
NumText:=Copy(Trim(Value),2,Length(Trim(Value))-1);
NumText:=Copy('0000000000000000',1,16-Length(NumText)) + NumText;
Total:=0;
Comunidad Borland
http://community.borland.com
Adems de la informacin sobre Delphi que puede encontrarse en
http://www.borland.com, Borland cuenta con una sitio especfico para
desarrolladores. En el podr encontrar una comunidad centrada en
Delphi, con artculos de los especialistas ms conocidos, noticias y
todo tipo de recursos tiles.