Está en la página 1de 125

Delphi paso a paso (I)

Por Vladimir Algara

Cada vez menos, tratamos de discutir cmo o por qu tenemos que introducirnos en Windows, slo queda por dilucidar cundo y con qu herramienta. Para quienes trabajaban en Clipper el salto evidente pareca ser Visual Objects, para los eternos "xBaseros" la balanza se inclinaba hacia Visual FoxPro, para los de Ceros el Visual C++, etc. Actualmente, a mi entender, existen cinco grandes herramientas para trabajar bajo Windows, que enumero alfabticamente para no levantar sospechas: Delphi, Visual Basic, Visual C++, Visual FoxPro y Visual Objects. Todas ellas podran someterse a examen y, unas u otras saldran bien o mal paradas segn el baremo aplicado. No cabe la menor duda de que cada programador pretende conseguir unas metas concretas, pero lo que tambin es cierto es que para conseguir estas metas el camino debera ser lo menos escabroso posible. Segn estas dos premisas se podra hacer una primera divisin de esas cinco herramientas; en dos grandes grupos, uno que simbolizara la potencia del producto (en el que se valorara total potencia OOP -fundamental-, tipificacin de variables, implementacin DDE entre aplicaciones, manejo gil de los datos almacenados en archivo de bases de datos, acceso sin trabas al API de Windows, manipulacin de los 32 bits de Windows 95, as como otras de menos importantes, pero que vinieran a engordar la bonanza del producto, como accesibilidad a controles OLE y controles de Windows 95, etc.) y otro su facilidad de manejo. Por potencia: Por facilidad de uso:

Delphi, Visual C++ (ordenados alfabticamente) y, un poquitn ms alejado, Visual Objects. Delphi, Visual Basic y Visual FoxPro (ordenados alfabticamente por fabricante, Borland y Microsoft).

Dado que se ordene como se ordene siempre es Delphi quien encabeza las listas, en esta primera entrega se comienza un deambular (por no decir curso) a travs de las facilidades de uso y potencia que Delphi 2.0 (32 bits) ofrece a los desarrolladores que quieran programar bajo Windows y an no sepan con qu hacerlo.

Caractersticas de Windows
Para empezar debemos dejar claros varios conceptos, no siempre evidentes para usuarios DOS.

El Sistema Operativo
El crecimiento del hardware ha marcado las pautas del software. Entornos de trabajo como Windows son impensables en mquinas de bajas prestaciones.

DOS es un sistema operativo de pocos recursos y, por consiguiente, rpido. Sin embargo es excesivamente artesanal, pues todo control, toda validacin, todo supuesto error ha de ser previsto por el programador, no por el sistema operativo (como por ejemplo Windows ). Adems, Windows dota de grandes recursos con apenas codificacin.

La multitarea
Windows es un sistema que permite realizar varias tareas a la vez; por ejemplo, una persona puede estar ejecutando una aplicacin y mandando por mdem un archivo a otra estacin
1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

remota. Esta potencia hay que tenerla en cuenta a la hora de disear las aplicaciones, pues esa segunda tarea puede ser, nuevamente, la propia aplicacin. Incluso dentro de una aplicacin, se puede hacer que un proceso se lance un nmero indefinido de veces (aplicaciones MDI), sin menoscabo de lo ya ejecutado. La comunicacin entre aplicaciones y/o procesos se puede efectuar a travs de cuatro grandes caminos: el uso del portapapeles (cortar y pegar), la tcnica de Drag&Drop (arrastrar y soltar), el intercambio dinmico de datos (enlaces DDE) y las incrustaciones OLE.

Los eventos
Por medio de los sucesos acaecidos en la vida de una aplicacin, sta le brinda al sistema una informacin; el sistema los lleva a cabo. Esta comunicacin aplicacin-sistema es fcilmente asimilable por una mente DOS, pero lo que puede no serlo tanto es la informacin que genera el sistema y que nuestra aplicacin tiene la potestad de utilizar o no. Como se aprecia es una comunicacin de dos direcciones y, adems, constante.

La gestin de memoria
Windows reutiliza y compacta la memoria segn sus necesidades. Cuando se cierra alguno de los programas que se mantienen abiertos Windows se encarga de liberar la memoria ste utilizaba, manipulando los datos y cdigo a su conveniencia y optimizando al mximo la ubicacin de los segmentos de memoria. Asimismo, el uso de las libreras de enlace dinmico (DLL) permite: Cargar y descargar la librera en tiempo de ejecucin (enlace dinmico) Que varios programas distintos accedan a una misma DLL sin que ocurran conflictos (independencia del ejecutable). Que una DLL est confeccionada en un lenguaje y sea aprovechada desde otro (independencia del lenguaje).

Las herramientas visuales


Dado que Windows es un entorno grfico, el diseo de ventanas (con una lgica similar en todos los lenguajes), iconos, cursores, etc., se realiza por medio de las herramientas que los distintos lenguajes proporcionan, por lo que los programadores pueden dedicar menos tiempo al diseo final y ms al buen funcionamiento del algoritmo interno.

Por qu Delphi
La eleccin de un lenguaje u otro, lo expuse al principio, dependen de muchos factores determinantes. Entre toda la oferta, y teniendo en cuenta que yo previamente trabajaba en Clipper y que saba algo (no gran cosa) de Turbo Pascal, tena dos claros candidatos, Visual Objects (con el que efectivamente empec debido a mi herencia) y Delphi. Con Visual Objects he pasado alegras y penurias, y si bien es una de las arquitecturas ms slidas, no posee un entorno amable. Con l tengo la seguridad de que cualquier cosa la voy a poder llevar a cabo, pero no s cunto voy a tener que invertir en tecnologa ni en tiempo. Con Delphi y Visual C++ tengo esa misma potencia, pero con ambos dispongo de infinita ms flexibilidad, tengo la posibilidad de no ser artesano

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

(aunque puedo serlo), de no depender de la feliz idea, de la posibilidad de ser ms tonto, qu gusto! Como no s C, ni BASIC y quera olvidarme del @...SAY, mi suerte estaba echada. Voy a intentar comentar las facilidades de uso de Delphi 2.0 e intentar abordar, a lo largo de las distintas entregas, las operaciones ms comunes a la hora de desarrollar una aplicacin para Windows.

El entorno
Los requerimientos
De todos los paquetes, tambin Delphi es el que menos requerimientos hardware necesita. Aunque puede realizar una instalacin compacta de unos 20Mb cuando se quiere cargar todo (aunque no se utilice en la vida) se necesitan alrededor de 60 Mb. Al producto, en tiempo de desarrollo, le hacen falta un mnimo de 4 Mb de memoria (lo que es justo y necesario para Windows 95) aunque con ms va mejor, claro; 8 Mb es una cifra con la que nos podemos empezar a sentir a gusto. Visual Objects, Visual FoxPro, etc. necesitan 8 Mb para empezar a hablar y 16 para empezar a sentirse a gusto, Visual C++ fija el mnimo en 16 Mb y 20Mb para un buen hacer.

La mesa de trabajo
Se entiende por mesa de trabajo el lugar donde se encuentran todas las piezas disponibles para la confeccin de una aplicacin. En Delphi se advierten cinco grupos de elementos claramente diferenciados. -

El men principal. En l se recogen todas las opciones que se pueden realizar desde Delphi: empezar un nuevo trabajo, imprimir el que est en curso, compilar, ejecutar, acceder a la ayuda dependiendo del contexto en el que nos encontremos, etc. La barra de herramientas. Conjunto de iconos que simbolizan las operaciones ms comunes. La que se ve en la figura 1 no es la que ofrece Delphi por defecto, sino una configurada al gusto del consumidor (o sea, al mo). La paleta de controles. Coleccin de los elementos que se pueden ubicar en las ventanas de una aplicacin. Se trata de una coleccin de carpetas (tabs), cada una de ellas, a su vez, con una coleccin de controles al uso. Este elemento y los dos anteriores se pueden ver en la figura 1.

Figura 1: Men principal, barra de herramientas y paleta de controles.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

El inspector de objetos. Ventana donde se permite modificar en fondo y forma el control ubicado en la ventana, o la propia ventana. Dado que un control (o la ventana) est sujeto a sus caractersticas y a los eventos que se pueden producir en l, el inspector de objetos posee dos carpetas (tabs) para cada una de las operativas. Ver figura 2.

Figura 2: El inspector de objetos

Ventana de trabajo (la que se ver en la aplicacin una vez que la echemos a andar) y cdigo asociado a esa ventana. Ver figura 3

Figura 3: Ventana Form1

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Los archivos y la OOP


La unidad de trabajo en cualquier aplicacin hecha desde Delphi es el proyecto (Project). Dentro de un proyecto se almacenan los formularios (cada ventana de la aplicacin es un formulario) o unidades (units) que utilizar nuestra aplicacin. Dada la arquitectura de Delphi todo se entiende como OOP, incluso los mencionados formularios son una instanciacin de la clase TForm. Pero, antes de asustar al personal con tanto OOP para arriba y para abajo, veamos en qu se traduce eso a la hora de implementar un programa. La respuesta es sencilla, una ventana se manipular como un objeto, y, como tal, llevar un nombre puesto por m. Por ejemplo, si la ventana queremos que se llame Lucero, acudiremos a la propiedad Name en el inspector de objetos y cambiaremos Form1 por Lucero. Este cambio provoca la siguiente modificacin automtica:

Lucero: TLucero

Aadindose una lnea donde se dice:

TLucero = class(TForm) . . . var Lucero: Tlucero;

Eso quiere decir que la ventana creada, se llame como se llame, es una instanciacin de la clase padre TForm, que, como tal, tiene todas sus caractersticas. Seguidamente se define la variable Lucero de esa clase recin creada Una vez en este punto, sabemos que el objeto Lucero (la ventana) se compondr de un ancho, de un alto, de una posicin de comienzo, de un ttulo (caption), de un botn de cierre (aspa en Windows 95) o no, etc. Todos estos datos de los objetos vienen meridianamente explicados en la ayuda que acompaa a Delphi; as, por ejemplo, si se desea saber ms sobre el dato caption de la ventana Lucero, buscaremos caption en la ayuda en lnea (Contents en Help). Aparecer la descripcin de la figura 4.

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 4: Ayuda sobre el dato caption

La informacin aportada en esta ventana del Help, adems de la descripcin, es el componente al que pertenece (TForm), un ejemplo de uso (zona sensible example), temas relacionados (zona sensible see also) y tipo de dato que contiene (property caption: string;) en nuestro caso una cadena de caracteres. El caption, como ya se sabe, corresponde al ttulo de la ventana. Existen dos formas de alterar su contenido, una por medio de la propiedad caption del inspector de objetos y otra mediante programa:

Lucero.caption := Ttulo de ventana

Intuitivamente se puede interpretar este cdigo de la siguiente manera. El objeto Lucero tiene un dato llamado caption (al cual accedo mediante la sintaxis Lucero.caption) que modifico sin ms que asignar un dato acorde a su tipo (segn rezaba la ayuda, este tipo es carcter). Usando el operador de asignacin (:=) almaceno la cadena entrecomillada.

El cdigo fuente
Una interesante posibilidad, sobre todo al comienzo, consiste en ver qu cdigo se va generando para la ventana en curso, adems del siempre disponible del proyecto. Para ello pinchamos en dicha ventana con el botn derecho del ratn (izquierdo para los zurdos) y elegimos, en el men local, verlo en forma de cdigo fuente. All habr una lnea similar a la de ms arriba. Es ms, cualquier cambio en esta lnea tambin afectar al contenido que visualiza el inspector de objetos. Para regresar a la ventana se vuelve a pinchar con el botn izquierdo y elegimos en el men local verlo en forma grfica. Para aquellos que no conozcan nada de Pascal y vengan de un entorno xBase, decir que, como todo lenguaje, uno se empieza a encontrar a gusto cuando domina su sintaxis. La de Pascal es estructuralmente diferente, por ejemplo, a la de Clipper. A saber.

Estructura de los programas

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

En Clipper se comienza con una funcin principal en un archivo PRG principal que va llamando sucesivamente a otras funciones y/o procedimientos. En Delphi el mdulo principal es el del proyecto y tiene una estructura como la del fuente 1:

// --- Fuente 1 ----------------------------------------------------------program Project1; uses Forms, Unit1 in 'UNIT1.PAS' {Lucero}, Proy in 'PROY.PAS'; {$R *.RES} begin Application.CreateForm(TLucero, Lucero); Application.Run; end.

En primer lugar la palabra reservada program, que indica el comienzo de un programa Delphi, luego los mdulos que intervienen en el proceso (uses), indicadores tiles para el compilador ({$R *.RES}) y comienzo de los elementos ejecutables (entre las palabras reservadas begin y end) y punto final (.). Lo que se ejecuta, en este caso, es la creacin de un formulario, tomando como base la clase Tlucero y su variable Lucero. Esto mismo, en Clipper sera algo idntico a:

Lucero := Application.CreateForm(TLucero);

Por otra parte, las distintas unidades presentan la estructura del fuente 2.

// --- Fuente 2 ----------------------------------------------------------unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TLucero = class(TForm) private { Private declarations } public { Public declarations } end; var Lucero: TLucero; implementation {$R *.DFM} end.

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Encontramos una primera seccin para el interfaz a usar (Interface), seguida de los mdulos necesarios para echar a andar la aplicacin (uses), otra seccin para la definicin de nuevos tipos de datos (type) donde se declara la nueva clase TLucero (que hereda de TForm), la declaracin de variables privadas y pblicas a nivel de aplicacin (luego habr locales a nivel de funcin y/o mtodo), las variables de aplicacin (seccin var) donde se especifica Lucero como tipo TLucero. Tanto el fuente 1 como el 2 se generan de forma automtica.

Separacin de lneas Las lneas se separan por punto y coma (;) como en C. Si hubiera una instruccin con ms de una lnea bastara con escribir una detrs de otra y, al final, poner el punto y coma.

nValor1 := 1; nValor2 := 1; nValor3 := 1; nValor4 := 1; nSuma := nValor1 + nValor2 nValor3 + nValor4;

Declaracin de variables Se usa la palabra reservada var para definir una o un conjunto de variables. Para ello se da el nombre de la variable, el identificador dos puntos (:) y se define un tipo vlido.

var nValor1 : integer; nValor2, nValor3, nValor4 : integer; cCadena : string[10]; oVentana : Tlucero;

Estructuras begin...end Cuando en una estructura se especifica una sola accin no es necesario el uso de agrupaciones begin...end, pero si se van a realizar dos o ms s lo ser:

if nValor1=1 then nValor2:=0 else nValor2:=1000 if nValor1=1 then begin nValor2:=0; nValor3:=0; nValor4:=0; end else begin nValor2:=1000; nValor3:=1000; nValor4:=1000; end;

Valores de funciones
8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Existen funciones que devuelven valores que pueden ser almacenados en variables auxiliares (como en Clipper), pero hay otras que reciben como parmetro dicha variable auxiliar y es dentro de la funcin donde se altera su contenido (se pasan internamente como referencia).

dFecha := Date() cValor1 := Str( nValor1 ) Str( nValor1, cValor1 )

// Correcto // No correcto // Correcto

Comentarios Los comentarios a los programas comienzan abriendo un parntesis y un asterisco y finalizan con un asterisco y un parntesis cerrado. En la versin 2 tambin se pueden utilizar las dos barras (como en C o en Clipper).

(* Comentario a programa Delphi *) // Comentario a programa Delphi

Ubicacin de funciones Todas las funciones, procedimientos y mtodos han de estar al principio del programa, antes del begin...end principal. El begin...end principal debe acabar en punto.

procedure ...(...) var ... begin ... end; procedure ...(...) var ... begin ... end; begin ... end.

Antes de terminar
De aqu en adelante todo va seguir la misma sintaxis expuesta. Por ejemplo, para codificar cada evento basta con hacer doble clic en alguno de los de la relacin mostrada en el inspector de objetos. Automticamente se escribe el correspondiente cdigo, el cual, como se puede observar, se cie a la estructura de ms arriba; eso s, orientado a objetos. Como empezar a modificar todos los datos de la ventana o los eventos que en ella se pueden manifestar hara que me extendiese en demasa, postergo toda esta bsica maquinaria para una segunda entrega, en la que empezaremos a sacarle ms jugo al lenguaje. En este momento, si se quiere ver cmo funciona la ventana Lucero con su caption modificado, bastar con pinchar sobre el icono de ejecucin (tringulo verde) y, efectivamente, verla.

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (II): Mens


Por Vladimir Algara
Exponer de nuevo el tema de los mens en Algoritmo (o en clippeRmana) es algo que no va a deslumbrar a nadie, pero hacerlo desde Delphi s puede interesar a ms de uno. Como ya se coment en la entrega anterior, Delphi posee un editor donde implementar cualesquiera de los elementos habituales de una ventana; en este nmero vamos a ver cmo utilizar el especfico de mens. Cualquier editor de mens de cualquier lenguaje suele ser fcil de manejar, y con ellos implementamos un elemento omnipresente en las ventanas principales de las aplicaciones. Con este artculo describiremos el uso genrico de este editor, as como aquellas caractersticas ms peculiares. Dado que un men va asociado a una ventana (principal o secundaria), la lgica de creacin consiste en la implementacin de uno de estos mens y, una vez terminado, su asociacin posterior a la ventana. Una vez que el men se crea est disponible para cualquier ventana.

Editor de Mens
Una vez dadas estas nociones generales pasaremos a describir el funcionamiento y los elementos del editor de mens (ver figura 1).

Figura 1.

1.- Lnea donde se escribir cada opcin principal del men. En esta lnea se especifican las distintas opciones principales que componen el cuerpo central del men. 2.- Lneas donde se escribirn cada una de las opciones secundarias. En esta lnea se especifican las distintas subopciones de las opciones principales.

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

3.- Lneas donde se escribirn cada una de las subopcines. En esta lnea se especifican las distintas subopciones anidadas. En cualquiera de los tres casos anteriores (o cualquier otro nivel de anidacin de subopciones), si quisiramos activar un Hot-Key para cada opcin, bastara con anteponer a la letra en cuestin el smbolo &:

&Salir creara como Hot-Key la letra S

Para crear subopciones a una opcin, lo nico que tendremos que hacer es pulsar el botn izquierdo del ratn sobre la opcin secundaria seleccionada, eligiendo Create Submenu (o pulsando [Ctrl-flecha derecha] como se informa en la figura 2) en el men local asociado. 4.- Separadores entre subopciones. Para aadir este elemento visual basta con escribir un guin y pasar a la siguiente lnea. Aparecer una lnea separadora. 5.- Abreviatura de teclado para acceso rpido a opciones.

Figura 2

Como podemos observar en la figura 1, el men creado posee todos estos elementos. Es bastante intuitivo y en l podemos observar distintos subniveles, as como los hot-keys asociados a cada opcin del mismo.

El inspector de objetos
El cometido de esta ventana, como ya se adelant algo en la entrega anterior, es el de la especificacin de cada uno de los elementos que, a lo largo del ciclo de desarrollo, vamos dando a las partes que completan la aplicacin. En los mens, podremos declarar los siguientes conceptos:

Propiedades del men


Las caractersticas del men como un todo, como algo que engloba a los distintos tems. La figura 3 se muestra cuando pinchamos sobre un elemento de tipo men.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3.

AutoMerge: Premite que el men se muestre nada ms arrancar la ventana, o no. Items: Permite entrar en el editor de men (pinchando en los puntos suspensivos asociados), y, por tanto, modificarlo y/o consultarlo. Tiene el mismo efecto que hacer doble clic sobre un elemento de tipo men. Name: Nombre simblico a travs del que nos referiremos al men (nombre de la clase que lo alberga). Tag: Valor numrico por el cual conocemos el orden de tabulacin de un elemento. Aplicable a todos los componentes visuales de una ventana.

Propiedades de los tems


La relacin de cada caracterstica de los tems de un mens (ver figura 4).

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 4

Break: Fija uno o varios puntos de ruptura. Esta caracterstica permite obtener mens en forma de caja, en la que cada ruptura (agrupacin) engloba elementos de un mismo tipo para una determinada opcin. Por ejemplo, si queremos obtener la figura 5, bastara con decir que el Break de los tems "Base de datos" estuviera a mbBreak, en vez de a mbNone (opcin por defecto). Si como en la figura 5 se desea, adems, separar cada una de estas rupturas, lo que se tendr que especificar ser mbBarBreak. El resto las dejaremos en mbNone.

Figura 5: Men con agrupaciones de opciones

Caption: Literal descriptivo del tem. En este punto es donde se puede aadir el carcter & para subrayar una letra del caption. Checked: Aade una marca al tem del men. Este tipo de smbolos se utiliza cuando deseamos que una cierta operacin este siempre sujeta, o no, a un comportamiento estndar. Por ejemplo, habilitar que las ventanas siempre aparezcan expuestas en mosaico, o que los iconos aparezcan
4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

organizados, etc. La marca tambin aparece en el propio editor de mens.

Enabled: Muestra atenuado (valor false) o no el tem afectado. Se muestra as en el editor de mens, no slo en la prueba ejecutable. GroupIndex: Establece el nmero de iconos (asociados a los tems) que pertenecern a una sola agrupacin. HelpContext: Especifica, a travs de un nmero, el tipo de ayuda que se visualizar cuando el usuario pulse la tecla [F1] en algn lugar de la aplicacin. HelpContext es un aspecto aplicado no slo a mens, sino a otros contextos; debido a su especificidad y a lo prodigado de su uso, se le dedicar, en otra entrega, un estudio pormenorizado. Name: Como ocurra con el men, nombre simblico del tem. ShotCut: Combinacin de teclas para la llamada rpida al proceso asociado a un tem del men. Estn contempladas las teclas [Ctrl-tecla], las teclas de funcin hasta la [F12], en combinacin o no con Ctrl y/o Shift y dems teclas auxiliares como [Supr], [Inicio], etc., tambin con Ctrl y/o Shift. El literal de la abreviatura de teclado aparece a continuacin del tem al que se le ha asociado. Tag: Valor numrico para el orden de tabulacin.

Eventos
Los mens, y ms concretamente los tems que componen un men, slo tienen un evento; aqul que sucede cuando se elige alguna de las opciones. Por eso la pestaa Events slo dispone del evento OnClick(). Si queremos especificar un evento concreto, basta con escribir en el combo asociado a OnClick() el nombre del procedimiento que queremos ejecutar cuando hagamos Clic, y pulsar [Intro]. Esto har que el nombre de dicho evento se registre en el bloque type, y que se escriba, automticamente, las lneas esenciales de ese mtodo. Por ejemplo si escribimos Salir veremos el cdigo del fuente 1:

// --- Fuente 1 -------------------------------------------------------type . . . . . . procedure Salir(Sender: TObject); . . . . . . procedure TForm1.Salir(Sender: TObject); begin end;

Ahora slo hay que escribir entre el begin y el end lo que queremos ejecutar. En este caso, como lo que queremos es salir, diremos Close.

// --- Fuente 2 -------------------------------------------------------procedure TForm1.Salir(Sender: TObject);

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

begin Close; end;

Otra posibilidad es dejar a Delphi que ponga nombre al mtodo asociado a OnClik(). Como ser habitual, esto lo haremos haciendo doble clic con el ratn en vez de escribir nosotros el nombre. Si ya existen mtodo definidos, podremos elegir, si ha lugar, algunos de los ya escritos. Si ms de un tem ejecuta el mismo mtodo, dentro de ste podremos distinguir si es uno u otro, por medio del parmetro Sender. Supongamos que el tem Cortar y el tem Copiar ejecutan un mtodo comn que realiza una determinada cantidad de operaciones, al final de las cuales, efectivamente, queremos que lo que est marcado en ese momento sea Cortado o Copiado. Para resolverlo nada ms fcil que definir (en Cortar, por ejemplo) el mtodo CortaryCopiar() y pulsar [Intro]; se generar el cdigo asociado y comenzaremos a introducir el cdigo comn a ambos, luego, por medio de Sender, determinaremos cul se puls y actuaremos en consecuencia (ver fuente 3).

// --- Fuente 3 -------------------------------------------------------procedure TForm1.CortaryCopiar(Sender: TObject); begin // Cdigo comn Form1.caption := 'Se est usando el Cut&Paste'; . . . . . . // Fin del cdigo comn if Sender==Cortar then Edit1.cut else Edit1.copy; end;

Donde Edit1 es el Name de un hipottico control de edicin y Cortar el Name asociado al tem Cortar del men. Se supone que el mtodo CortaryCopiar slo es llamado por Cortar o Copiar, de ah que si el que llama (Sender) no es Cortar no quede ms remedio que sea Copiar. Si hubiera ms posibilidades habra bastado con proteger cada operacin particular con su if correspondiente, o con una estructura case que tuviera en cuenta la casustica.

Ejemplo
Pongamos un ejemplo en el que vamos a jugar con dos controles de edicin, en los que vamos a permitir cortar y/o copiar, as como pegar. Tambin se permitir, cuando tenga algo, vaciar el contenido del portapapeles. Para que el efecto visual sea aparente, inhabilitaremos las opciones del men no permitidas. La ventana que recoge este proceso es el la de la figura 6 y el cdigo que hay que ensayar el del fuente 4.

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 6: Aplicacin para uso de mens

// --- Fuente 4 -------------------------------------------------------unit menu2; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, Buttons, ExtCtrls, OleCtrls, ChartFX, StdCtrls; type TForm1 = class(TForm) MainMenu1: TMainMenu; Editar: TMenuItem; Cortar: TMenuItem; Copiar: TMenuItem; Pegar: TMenuItem; Vaciar: TMenuItem; N2: TMenuItem; SBCortar: TSpeedButton; SBCopiar: TSpeedButton; SBSalir: TSpeedButton; Edit1: TEdit; Edit2: TEdit; SBPegar: TSpeedButton; SBVaciar: TSpeedButton; procedure Salir(Sender: TObject); procedure CortaryCopiar(Sender: TObject); procedure PegarDesde(Sender: TObject); procedure VaciaPapelera(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Salir(Sender: TObject); begin Close; end;

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

procedure TForm1.CortaryCopiar(Sender: TObject); begin Form1.caption := 'Se est usando Cut&Paste'; Pegar.Enabled := True; Vaciar.Enabled := True; SBPegar.Enabled := True; SBVaciar.Enabled := True; if Sender=Cortar then Edit1.CutToClipboard else Edit1.CopyToClipboard end; procedure TForm1.PegarDesde(Sender: TObject); begin Edit2.PasteFromClipboard end; procedure TForm1.VaciaPapelera(Sender: TObject); begin Pegar.Enabled := False; Vaciar.Enabled := False; SBPegar.Enabled := False; SBVaciar.Enabled := False; end; end.

Porciones de cdigo a resaltar


En la porcin identificada como type se declara la variable TForm1, que se instancia desde la clase TForm

TForm1 = class(TForm)

Una relacin de todos los tems del men (clase TMenuItem), de los botones de acceso rpido (TSpeedButton), de los controles de edicin (clase TEdit) y de los mtodos llamados al producirse un cierto evento (ver fuente 5).

// --- Fuente 5 -------------------------------------------------------type TForm1 = class(TForm) MainMenu1: TMainMenu; Editar: TMenuItem; Cortar: TMenuItem; . . . SBCortar: TSpeedButton; SBCopiar: TSpeedButton; SBSalir: TSpeedButton; Edit1: TEdit; Edit2: TEdit; SBPegar: TSpeedButton; SBVaciar: TSpeedButton; procedure procedure procedure procedure Salir(Sender: TObject); CortaryCopiar(Sender: TObject); PegarDesde(Sender: TObject); VaciaPapelera(Sender: TObject);

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

En lo que a declaracin de variables se refiere, se define Form1 como representacin de la ventana.

var Form1: TForm1;

Los procedimientos
Salir Se invoca al pulsar sobre el botn de acceso rpido Salir. Su cometido: cerrar la ventana y, por ende, la aplicacin.

procedure TForm1.Salir(Sender: TObject); begin // Cierra la ventana Close; end;

CortaryCopiar Como se ha comentado un poco ms arriba, este procedimiento es comn a las opciones de cortar y copiar (en lo que se refiere a la habilitacin y deshabilitacin de controles) y particular a la hora de almacenar en el portapapeles y respetar el texto seleccionado o eliminarlo. Ver porcin de cdigo en el fuente 6.

// --- Fuente 6 -------------------------------------------------------procedure TForm1.CortaryCopiar(Sender: TObject); begin // Parte comn a Cortar y a Copiar Form1.caption := 'Se est usando Cut&Paste'; Pegar.Enabled := True; Vaciar.Enabled := True; SBPegar.Enabled := True; SBVaciar.Enabled := True; // Parte diferenciada // Si el que ha llamado al procedimiento ha sido Cortar se hace Cut // Si no se hace Copy if Sender=Cortar then Edit1.CutToClipboard else Edit1.CopyToClipboard end;

PegarDesde Este otro se encarga de traer del portapapeles lo que haya all grabado, almacenndolo en el control de edicin cuyo Name es Edit2.

procedure TForm1.PegarDesde(Sender: TObject); 9


Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

begin Edit2.PasteFromClipboard end;

VaciarPapelera Por ltimo el mtodo que vaca el portapapeles. Realmente el portapapeles no se vaca, lo nico que se hace es inhabilitar la opcin de Pegar, para impedir traerse, al menos desde las opciones de la ventana, el contenido del portapapeles. Tambin se inhabilita la opcin de Vaciar, pues es ilgico vaciar ms de una vez el portapapeles ya vaco (ver fuente 7).

// --- Fuente 7 -------------------------------------------------------procedure TForm1.VaciaPapelera(Sender: TObject); begin Pegar.Enabled := False; Vaciar.Enabled := False; SBPegar.Enabled := False; SBVaciar.Enabled := False; end;

Conclusin
Aunque el programa es susceptible de muchas mejoras, como vaciar efectivamente el portapapeles, detectar que existe algo marcado en el control de edicin Edit1 y slo entonces permitir el cortado o el copiado, etc.; se da una idea de cmo interactuar desde los tems del men con ellos mismos, con otros controles de la ventana (botones de acceso rpido y de edicin) y con elementos de Windows (como es el portapapeles). Adems, se ha intentado ir introduciendo algunos elementos de programacin que enseen cmo especificar una orden desde el cdigo fuente (inhabilitar botones, cerrar la ventana, etc.).

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (III): Controles (I)


Por Vladimir Algara

Debido a un desliz lamentable en la entrega anterior, adems, ni siquiera puedo culpar a otro pues lo comet yo, dej de comentar la forma que tiene Delphi de implementar los mens locales a una ventana/control. Esos mens que aparecen cuando pinchamos con el botn derecho del ratn (izquierdo en los zurdos) y que tan de moda ha puesto Windows 95. En esta entrega, y antes de empezar a mover controles de arriba a abajo, dedicar unas lneas a la forma de crear mens locales y que, de haberme percatado en su momento, debieran haber aparecido en el monogrfico de mens del mes pasado. Ustedes sabrn disculparme.

Propiedades de los mens locales


En la figura 1 vemos un ejemplo del men en el editor de mens y el aspecto que adquiere la ventana de propiedades (o ventana del inspector de objetos) de dicho men. Como recordar el lector, los mens se elegan en la paleta de herramientas estndar y se ubicaban en cualquier parte de la ventana; si hacamos doble clic en este elemento entrbamos en el editor de mens, donde el inspector de objetos recoga las caractersticas y eventos posibles que un determinado tem (o todo el men) poda entender y ejecutar. Una vez terminada la fase de diseo, y gracias al nombre simblico (Name) dado al men, asocibamos ste a la ventana. El proceso para los mens locales no es similar al de los mens generales, es idntico; as que no har perder ms tiempo en explicar cmo operar, y me limitar a poner un sencillo ejemplo.

Figura 1: Ejemplo de men local

Ejemplo de men local para salir de una aplicacin


1.- Seleccinese el icono conveniente en la paleta de herramientas (ver figura 2)

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 2: Icono de la paleta de herramientas

2.- Ubquese a discrecin en la ventana elegida. 3.- Edtese y comincese a aadir tems y subtems entre 1 y 200 (o ms). Aadir uno cuyo evento OnClick (en Events) se llame Salir. 4.- Plsese [Intro] para entrar en el editor de cdigo fuente y poder especificar Close segn se aprecia en el fuente 1.

// --- Fuente 1 ---------------------------------------------------------procedure TForm1.Salir(Sender: TObject); begin Close; end;

5.- Hgase clic en la ventana para poder manipular su inspector de objetos. 6.- Seleccinese la entrada PopUpMenu y asciesele el PopUp creado. 7.- Ejectese a fuego rpido la "aplicacin". 8.- Srvase pulsar el botn derecho del ratn sobre la ventana y elegir el tem encargado de acabar. De nuevo, disculpas por el parche mal ubicado y dedicado a mens locales. Aunque, bien pensado, podra haber recurrido a la coartada de explicarlo como un control ms, pues eso, precisamente, es lo que es.

Controles varios
Los controles por excelencia son los PushButton. Estos botones son los encargados de lanzar los procesos, cerrar las ventanas secundarias, abrir otras, dar conformidad a los datos, etc.; motivo principal por el que estn presentes en casi cualquier aplicacin, por sencilla que sta sea. Los iconos que en la paleta de herramientas (no seleccionado y seleccionado) representan a los botones "normales" (los llamo as en contraposicin a los botones con un grfico en su interior) son los de la figura 3.

Figura 3: Iconos para botones

Una vez seleccionados se llevan a la ventana y all pasamos a darles especificidades. Nota: Hay que recordar que cada vez que se pincha alguno de los elementos en la paleta de herramientas y se lleva a la ventana, ste se deselecciona automticamente, debiendo pinchar sobre el control deseado tantas veces como controles se quieran poner. Esto se soluciona si, en
2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

vez de pinchar directamente, pinchamos manteniendo pulsado [Shift]. El icono, al contrario de lo que ocurra con anterioridad, permanecer hundido hasta que no lo pinchemos nuevamente, lo hagamos en otro distinto, o sobre el icono que representa al cursor del ratn (presente en cualquier pestaa de la paleta de herramientas). El nombre (Name) dado a un control de tipo botn, as como su literal inicial es Button1, Button2, etc., si bien stos se pueden rebautizar como nos venga en gana mediante sus propiedades Name y Caption, respectivamente, en la ventana del inspector de objetos. Un control puede ser Marcado, Copiado/Cortado y Pegado hacia y desde el portapapeles. Todo ellos con la secuencia de teclas habituales en la que [Ctrl-C] copia, [Ctrl-X] corta y [Ctrl-V] pega. Adems, la barra de herramientas se puede configurar (opcin Configure de su men local) y agregarle aquellos iconos que se necesiten, entre los cuales se encuentran los que manipulan la informacin del portapapeles mencionada. En la figura 4 se puede ver una barra de herramientas configurada, que ofrece un aspecto distinto al ofrecido cuando arrancamos Delphi por primera vez.

Figura 4: Configuracin de la barra de herramientas

Movilidad de controles
En este subapartado quiero contar, someramente, qu tipo de operaciones se pueden realizar con los controles que se aaden a una ventana; entendidas stas como la posibilidad de mover, redimensionar, borrar, alinear, etc. los controles disponibles. Para ello podemos partir de una ventana que albergar tres botones, del mismo tamao que uno de ellos, alineados respecto del primero y colocados en la esquina inferior derecha de una ventana segn una rejilla (grid) de referencia cuyos puntos equidistan 6 pxels entre s. Grficamente se puede comprender mejor. Se quiere partir de una ventana como la de la figura 5 y se quiere llegar a la de la figura 6.

Figura 5: Controles descolocados

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 6: Controles colocados segn Grid

Para esta maniobra habremos de: 1.- Elegir un Grid para la ventana. Accedemos a la opcin Options del men Tools. En la ventana de dilogo que aparece marcaremos los CheckBox correspondientes a Display Grid y Snap To Grid (el primero visualiza la rejilla, el segundo fuerza que los elementos se adapten a su contorno -dse cuenta que podemos tener un Grid que sirva de referencia, pero, al tiempo, permitir que los controles no se constrian a l-) y se fijar la separacin entre los puntos horizontales y verticales (6 para ambos). 2.- Elegir el botn de referencia. Por ejemplo nos puede servir el Botn 1, lo pinchamos y lo hacemos tan grande como queramos. 3.- Amoldar el tamao del resto de los botones al de referencia. Para ello se seleccionan todos los botones, bien marcando un rea en cuyo interior se encuentren todos los controles deseados, bien eligindolos uno a uno mientras se mantiene presionada la tecla [Shift]. Se pincha con el botn derecho del ratn sobre la ventana y se elige la opcin Size...; aparecer una ventana en la que se permite: 1.2.3.4.No realizar cambios Reducir todos los tamaos adaptndolos al del ms pequeo Ampliar todos los tamaos adaptndolos al del ms grande Fijar una dimensin

Cualquiera de esas operaciones se puede aplicar al redimensionamiento a lo ancho o a lo alto del control. Si nos fijamos, no se puede especificar que todos los controles se adecen al mismo tamao del "mediano", sino al del ms grande o al del ms pequeo; pero esto es suficiente para contemplar todo los casos, pues lo habitual es elegir un conjunto de controles (con su tamao por defecto), manipular uno hacindolo ms grande o ms pequeo, y adaptar el resto. 4.- Alinear los botones. Esta operacin se puede llevar a cabo por medio del la opcin Aling... del men local a la ventana, o haciendo aparecer la ventana de dilogo de la figura 7. A travs del men local aparecer una ventana de dilogo con la misma lgica que la que apareca cuando intentbamos ajustar el tamao (Size...), en la que se permite: 1.2.3.4.5.6.No realizar cambios Alinear a la izquierda y/o arriba Centrar Alinear a la derecha y/o abajo Espaciar idnticamente los controles Centrar en la ventana

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Todo ello segn dos criterios, uno hacerlo horizontal y/o verticalmente, y el otro hacerlo respecto a un control de referencia. La forma que tiene Delphi de determinar cul es el control de referencia consiste en la manera en que son elegidos dichos controles. Por ejemplo, cuando elijamos los tres controles de nuestro ejemplo, aqul que se pinche en primer lugar ser el que sirva de referencia. A travs de las distintas opciones de la ventana, que se aprecia en la figura 7 (a la que se accede tras elegir la opcin Alignment Palette del men View), se pueden hacer las mismas cosas que con la ventana de dilogo recin comentada.

Figura 7: Controles colocados segn Grid

Un control, cmo no, se puede borrar sin ms que seleccionarlo y pulsar la tecla [Supr]. Adems, se puede ensayar cualquiera de las opciones que aparecen en el men local, algunas de las cuales hemos repasado hace un momento. -

Aling To Grig: Forzar a que los controles se cian a la rejilla visualizada. Bring To Front: Traer delante el control elegido. Cuando dos o ms controles ocupan un rea comn (por ejemplo un RadioButton dentro de un GroupBox) se permite fijar cul se encontrar por encima de cul. Send To Back: Llevar detrs (la explicacin es anloga a la de arriba). Aling...: Ya comentada Size...: Ya comentada Scale...: Fijar un tamao proporcional segn el tamao actual del control. Un valor de 100 equivale al mismo tamao, un valor inferior a 100 (hasta un mnimo del 25%) provoca la disminucin proporcional del tamao actual del control y un valor superior (hasta un 400%) un aumento proporcionado. Este escalado es aplicable, no solo a un control especfico, sino a un conjunto de ellos previamente seleccionados. Tab Order... y Creation Order...: Se permite fijar la prioridad de los elementos visuales y no visuales de una ventana, con el fin de que en ejecucin unos tengan preferencia sobre otros. Add To Repository: Aadir la ventana recin configurada a la relacin de las ventanas por defecto. View as Text: Una ventana lleva asociado un cdigo fuente encargado de ponerla en marcha. Dicho cdigo se permite hojearlo mediante esta opcin. Dada la correspondencia entre lo que se ve en la ventana y su cdigo fuente, como el contenido del cdigo fuente y lo que ste genera, cualquier modificacin en uno conllevar la actualizacin del otro, y viceversa. Cuando se est inspeccionando el cdigo fuente, habr que volver a pulsar el botn derecho del ratn y elegir la opcin View as Form (o pulsar [Ctrl-F12]) para volver a disponer de la ventana original.

Propiedades de los botones


5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Como elemento aadido, decir que no hay por qu conformarse con el tamao que el editor le da por defecto a los botones para luego redimensionar, sino basta con pinchar en la ventana y, sin soltar, arrastrar el ratn hasta conseguir el tamao deseado, soltar, y, acto seguido, disponer de un botn con las proporciones perfiladas. Las propiedades y eventos que un control tiene se pueden consultar y alterar en el inspector de objetos. los controles poseen propiedades comunes (como Caption, Name, Left, Hint, etc.), aunque hay otras que son particulares para cada uno. En este apartado se vern las propiedades comunes y particulares de los controles de tipo botn, con el objetivo de que las comunes queden zanjadas para ulteriores explicaciones. Someramente, y segn aparecen en el inspector de objetos, son: -

Cancel. Permite ejecutar el cdigo asociado al botn cuando se pulsa la tecla [Esc]. Suele ser habitual asociarla al botn de cerrar la ventana; de esa forma pulsando [Esc] se da la impresin de abandono de la ventana actual para ir a la anterior. Esta propiedad es particular de los controles de tipo botn y se ha de poner a True cuando queramos activarla y False en caso contrario. Caption. Contenido del control. Es el literal que se visualiza y al que podemos aadir el carcter & para convertir en acceso rpido la tecla que lo precede. &Aceptar se traducira en el botn como Aceptar, lo cual permitira pulsar la tecla A para que la accin asociada al botn se ejecutara. Cursor. Aspecto que adoptar el cursor del ratn cuando lo paseemos sobre el control. El tipo de cursor puede ser definido por el usuario, pero lo ms rpido es asignarle alguno de los predefinidos (definidos por medio de identificadores, tal y como se ve en la figura 8).

Figura 8: Cursores predefinidos

Default. Permite ejecutar el cdigo asociado al botn cuando se pulsa la tecla [Intro]. Suele ser habitual asociarla al botn de cerrar la ventana; de esa forma pulsando [Intro] se da la impresin de acceder de la ventana actual para ir a la siguiente. Esta propiedad es particular de los controles de tipo botn y se ha de poner a True cuando queramos activarla y False en caso contrario. DragCursor. Aspecto del cursor cuando se pasea el puntero sobre el control si se est pinchando y arrastrando (Drag&Drop) elementos entre ventanas de una aplicacin y/o entre

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

aplicaciones Windows. -

DragMode. Forma en la que se va a controlar la tcnica de arrastrar y soltar. Admite dos valores: automtico y manual. Enabled. Determina el estado habilitado o inhabilitado (color gris y no accesible) de un control. Font. tipo de letra, tamao, color etc. del literal que aparecer en el control. Heigth y Width. Alto y ancho, en pxels, del control. HelpContext. Ayuda asociada al control Hint y ShowHint. Literal del tip (etiqueta) que se mostrar cuando paremos el puntero del ratn sobre el control. Cuando ShowHint est a true el Hint se muestra, si no, no. Left y Top. Coordenadas izquierda y superior que el control ocupa en la ventana. ModalResult. Valor devuelto por el control cuando se pulsa. Name. Nombre de control. Este nombre simblico es el que se usa a lo largo de toda la aplicacin para modificar propiedades del control en tiempo de ejecucin.

Boton1.Enabled := true;

PopUpMenu. Men local asociado al control. Se trata de un men particular del control que aparece cada vez que pulsamos el botn izquierdo del ratn sobre el control especfico, y no en otra parte. TabOrder. Secuencia en que se desplaza el foco al pulsar tabulador en la ventana. Delphi mantiene un orden secuencial a medida que se van aadiendo controles a la ventana. Este orden empieza en 0 y se va incrementando de 1 en 1, pero es modificable por el diseador de dicha ventana. TabStop. Habilita o no que la pulsacin del tabulador tenga efecto sobre el control. Tag. Nmero identificativo del control. Visible. Hace desaparecer el control de la ventana, o no.

Eventos posibles, o procedimientos que se llaman cada vez que... -

OnClick: ...se pulsa un botn. OnDragDrop, OnDragOver, OnEndDrag, OnStartDrag: ...se realiza una operacin de arrastrar y soltar (Drag&Drop) OnEnter: ...un control pasa de estar inactivo a estar activo. OnExit: ...el foco abandona el control en curso. OnKeyDown, OnKeyPress, nKeyUp: ...se presiona, se mantiene pulsada o se suelta una tecla.

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

OnMouseDown, OnMouseMove, OnMouseUp: ...se presiona el botn del ratn, se mueve el puntero o se suelta el botn del ratn.

Tanto las propiedades como los eventos se pueden asociar masivamente a un conjunto de controles. Para ello seleccionamos aqullos que se desean alterar, y se cambia alguna de sus propiedades. Por ejemplo si queremos que todos los botones tengan el literal "Botn", modificaramos la propiedad Caption de todos los que estuvieran seleccionados; seguidamente habr que ir aadiendo 1, 2, 3, etc. para cada uno de ellos, pero no Botn 1, Botn 2, etc. Operaciones como poner el mismo Name a una coleccin de controles no estn permitidas, pues el nombre es unvoco.

Propiedades de los textos


Para ver que muchas de las propiedades y muchos de los eventos son comunes entre controles, echemos un vistazo al inspector de objetos correspondiente a un texto (ver figura 9)

Figura 9: Propiedades de un control de texto

Como se puede ver, algunas nuevas respecto a los botones, pero tambin muchas comunes. Entre las nuevas cabe destacar las encargadas de alinear el texto, bien respecto a sus dimensiones, bien respecto a la ventana, tamaos y aspectos del literal escrito, si se tiene en cuenta o no el smbolo &, etc. Por otra parte, entre los eventos, aparece como nuevo OnDblClick, que se invoca cuando se hace doble clic sobre el texto implicado; pero no aparecen los relacionados con perder o ganar el foco (pues no se puede dar el foco a un texto) o pulsar y levantar una tecla.
8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Ejemplo
Pongamos un ejemplo en el que jugaremos con los dos controles vistos. La idea seguida ha sido habilitar el botn 1 con la propiedad Cancel a True (para que se invoque al pulsar [Esc]), el botn 2 con Default y asociar a ambos un procedimiento, llamado Texto, para que lo ejecuten cuando se pulsen. En dicho procedimiento se distingue si se llama con uno u otro botn, y se pinta uno u otro texto. El procedimiento Texto es el que se ve en el fuente 2. Sea cual sea el botn pulsado, se habilita un tercer botn, el de Salir, inicialmente inhabilitado por tener su propiedad Enabled a False. Su misin es permitir salir de la aplicacin. Cada botn lleva un tipo de letra, un tamao, etc. particular.

// --- Fuente 2 ---------------------------------------------------------procedure TForm1.Texto(Sender: TObject); begin if Sender=Boton1 then Label1.caption := 'Se ha pulsado el botn 1 o [Esc]' else Label1.caption := 'El botn 2 se puls o [Intro]'; Boton3.Enabled := True end;

La ventana que recoge este proceso es el la de la figura 10 y el cdigo completo que hay que ensayar el del fuente 3.

Figura 10: Aplicacin para uso de botones y texto

// --- Fuente 3 -------------------------------------------------------unit Boton1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Boton1: TButton; Label1: TLabel; Boton2: TButton; Label2: TLabel; Boton3: TButton; procedure Texto(Sender: TObject);

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

procedure Salir(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Texto(Sender: TObject); begin if Sender=Boton1 then Label1.caption := 'Se ha pulsado el botn 1 o [Esc]' else Label1.caption := 'El botn 2 se puls o [Intro]'; Boton3.Enabled := True end; procedure TForm1.Salir(Sender: TObject); begin Close; end; end.

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (IV): Controles (II)


Por Vladimir Algara

Con esta entrega continuamos en el punto y seguido dejado en la anterior. Recordando un poco lo visto hasta ahora, diremos que estamos en disposicin de crear ventanas con botones (no grficos) y mens, que permiten lanzar los distintos procesos que una aplicacin puede contemplar. Tampoco supone ningn problemas la utilizacin de los textos fijos en una ventana, pero lo ms importante, base esencial para poder huir hacia adeleante en el proceso creativo e investigativo, es el conocimiento del lenguaje y del comportamiento de las aplicaciones Windows. Tener claro cmo se comportan, por ejemplo, los eventos, supone tener recorrido gran parte del camino de aprendizaje, pues todas las situaciones que una ventana, aplicacin, etc. puede advertir vienen recogidas en la gestin de eventos en Windows. Cmo funciona un conjunto de botones de radio (RadioButtons), cmo se rellena una lista (ListBox o ComboBox), etc. podr ser un camino ms o menos costoso, pero se limitar a consultar la ayuda en lnea, los manuales de producto o algn que otro artculo de los muchos articulistas pesados que hay por ah. La filosofa del asunto es lo que realmente importa, y no el conocer al dedillo los mtodos y datos que una clase posee para hacer lo que se pretende en un momento dado. Por otra parte, y esto lo podremos comprobar en el ejemplo final de esta entrega, Delphi automatiza los procesos ms comunes, de manera que la labor del programador se limita a generar la aplicacin desde los editores visuales, siendo su aportacin (en lo que a tirar lneas de cdigo se refiere) mnima.

Botones grficos
Ya dijimos que los controles por excelencia eran los PushButton. Estos botones eran, y son, los encargados de lanzar los procesos, cerrar las ventanas, dar conformidad a los datos, etc.; los botones grficos no son ms que meros botones, pero con una imagen en su interior, la cual no le da ms funcionalidad, sino mejor aspecto. Los botones grficos se encuentran en la carpeta Aditional y los iconos que los representan (no seleccionado y seleccionado) son los de la figura 1.

Figura 1: Iconos para botones grficos

Como ocurre y ocurrir con cualquier control de la paleta de herramientas, una vez seleccionados se llevan a la ventana y all pasamos a darles especificidades. Nota: Vuelvo a recordar que cada vez que se pincha alguno de los elementos en la paleta de herramientas, ste se deselecciona automticamente, a no ser que mantengamos pulsada la tecla [Shift] al pincharlo. El nombre (Name) dado a un control de tipo botn, as como su literal inicial es BitBtn1, BitBtn2, etc.

Propiedades de los botones


1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Las propiedades y eventos generales que un control tiene se pueden consultar en la entrega anterior, en esta nos limitaremos a exponer las caractersticas especficas de los botones grficos, todas ellas alterables desde el inspector de objetos. -

Glyph. La ms elemental de las propiedades que un botn grfico es, propiamenste, el grfico que lleva en su interior. A travs de la propiedad Glyph se asocia un archivo de mapa de bits al botn grfico. Cuando elegimos Glyph en el Inspector de Objetos aparecen unos puntos suspensivos que, al pulsarlos, nos llevan a la ventana de lectura y salvaguarda de grficos (ver figura 2).

Figura 2: Ventana de edicin de BitMaps

Cuando en la ventana de la figura 2 se pulsa sobre el botn Load, aparece una caja estndar de directorios y ficheros destinada a elegir alguno de los bitmaps existentes. Delphi trae una serie de ellos predefinidos en el directorio C:\...\BORLAND\DELPHI32\IMAGES. Se trata de botones de dos estados, uno para el estado activado y otro para el desactivado. Como es habitual en Delphi, estos botones pueden ser diseados por nosotros mismos, con cualquier cantidad de estados, desde aplicaciones destinadas a tal fin, por ejemplo, PaintBrush. Pulsando el botn Ok de la ventana de la figura 2 veremos que el grfico se asocia al botn. Otra posibilidad es salvarlo (botn Save) con otro nombre o en otro destino distinto al actual. Clear rompe el vnculo entre imagen y botn, dejando Glyph en None; Cancel y Help son autoexplicativos.

Kind. Aparte de poder elegir libremente el grfico que se incluir dentro del botn, Delphi ofrece toda una coleccin de los botones grficos ms habituales, as como la accin asociada por defecto. Esta propiedad es muy importante, pues operaciones como la de cerrar una ventana, cancelar un proceso, llamar a la ayuda sensible al contexto, etc., estn implementadas; otra vez, automticamente. Los botones y sus caractersticas se pueden ver en la tabla 1 y su aspecto en la figura 3.

Valor bkCustom

Significado Son los botones configurables, es decir, los que hay que especificar grfico, un texto, una accin, etc. Es el valor por defecto.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Tiene una marca de Check en verde y el texto "OK" (el texto corresponde a la propiedade Caption, y por lo tanto se puede modificar sin problemas, al igual que las dems). La propiedad Default la tiene puesta a True y cuando es pinchado (o se pulsa la tecla [Intro]) devuelve el valor mrOK (constante que se almacena en el dato ModalResult del formulario (clase TForm). bkCancel Tiene un Aspa en rojo y el texto "Cancel". La propiedad Cancel la tiene puesta a True y cuando es pinchado (o se pulsa la tecla [Esc]) devuelve el valor mrCancel. bkYes Tiene una marca de Check en verde y el texto "Yes". La propiedad Default la tiene puesta a True y cuando es pinchado (o se pulsa la tecla [Intro]) se da conformidad a lo tecleado y devuelve el valor mrYes. bkNo Tiene una seal de prohibido en rojo y el texto "No". La propiedad Cancel la tiene puesta a True y cuando es pinchado se omite lo tecleado en la ventana y sta se cierra; devuelve el valor mrNo. bkHelp Tiene una interrogacin en azul y el texto "Help". Cuando es pinchado aparece una ventana de ayuda con el contenido del archivo especificado en la propiedad HelpFile. bkClose Tiene una puerta indicando salida de la aplicacin y el texto "Close". La propiedad Default la tiene puesta a True y cuando es pinchado se cierra el formulatio bkAbort Tiene un Aspa en rojo y el texto "Abort". La propiedad Cancel la tiene puesta a True. bkRetry Tiene dos flechas circulares verdes y el texto "Retry". bkIgnore Tiene un caminante de color verde y el texto "Ignore". Se usa para persistir en una operacin cuando ocurri algn error. bkAll Tiene una doble marca de Check en verde y el texto "All". La propiedad Default la tiene puesta a True. Tabla 1: Botones predefinidos.

bkOK

Figura 3: Botones grficos por defecto.

Layout. Posicin del grfico respecto al texto. Arriba, abajo, a la izquierda o a la derecha. La posicin por defecto es el grfico a la izquierda del texto (blGlyphLeft). Margin. Determina la cantidad de pxels que se van a poner entre el grfico y el borde el botn. Un valor igual a 0 hace que el texto quede pegado al borde. Un valor de -1 (valor por defecto) centra texto y grafico respecto el ancho total del botn. ModalResult. Valores numricos devueltos por el botn. Ver propiedad Kind.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

NumsGlyph. Cantidad de estados que un bitmap va a tener. Un bitmap con dos estados contiene, en un nico archivo, los estados de habilitado y deshabilitado. Para que puedan ser interpretados correctamente por Delphi ambos deben tener las mismas dimensiones y estar uno a continuacin del otro. Los valores posibles oscilan ente 1 y 4, siendo 1 el valor por defecto. Los valores posibles y sus significados se pueden consultar en la tabla 2.

Descripcin Aspecto cuando el botn est no presionado y no es valor por defecto. 2 Inhabilitado Aspecto cuando el botn no puede pincharse (disabled) 3 Hundido Aspecto cuando el botn est presionado. 4 Por defecto Aspecto cuando el botn est no presionado y es valor por defecto. Tabla 2: Nmero de imgenes por bitmap

Posicin Estado 1 Levantado

Spacing. Sigue la misma lgica que Margins, esta vez para fijar el nmero de pxels que separarn texto e imagen. El valor por defecto es 4.
Los eventos posibles son idnticos a los que se comentaron para los botones no grficos. Recordar que tanto las propiedades como los eventos se pueden asociar masivamente a un conjunto de controles, seleccionando los deseados y modificando las pertinentes propiedades.

Listas deslizantes (ListBox)


Como hay que seguir por algn otro control, he elegido ste porque da mucho juego. Los ListBox son una coleccin de elementos en forma de lista que el usuario dispone para elegir all algn elemento. En Delphi existen distintos tipos de ListBox, o ms bien existen distintas clases referentes a este tipo de controles. Usaremos una u otra dependiendo de los datos con los que los rellenemos. Por ejemplo, la clase TListBox se rellena con un tipo especial de cadena denominado TString, o bien desde un fichero de texto que la propia clase TString se encarga de interpretar. Tambin existen la clase TFileListBox (una clase especfica para rellenar con los archivos de un determinado directorio), TDirListBox (para estructuras de directorio), TDBListBox (para conectar a bases de datos) y otras ms para los ComboBox (hbrido entre control de edicin y ListBox). En esta entregra se abordar el ListBox sencillo, dejando para ms adelante el de estructuras de ficheros y directorios y el de conexin con bases de datos.

Propiedades de los ListBox


Nuevamente, hacemos un rpido recorrido por eventos y propiedades que estn ntimamente ligados a lo ListBox.

Alignt. Esta propiedad, si bien no es especfica de los ListBox, s ha aparecido en nuestra serie por primera vez. Con ella se determina cmo se va a mostrar el control respecto a la ventana. Por ejemplo, si se opta por alClient, se estar diciendo que el ListBox se amolde al contorno absoluto de la ventana, por lo que a medida que crezca o disminuya sta, tambin lo har su ListBox asociado.

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

BorderStyle. Determina si el ListBox llevar o no borde, dando as aspecto tridimensional o plano. Columns. Cantidad de columnas del ListBox. ExtendedSelect. En un ListBox se pueden elegir un elemento o varios (para ello hay que modificar la propiedad MultiSelect), y se puede hacer sin ms que ir pinchando aqullos que queramos seleccionar o deseleccionar, o bien siguiendo las tcnicas estndar de Windows, en las que pulsando la tecla [Ctrl] se eligen elementos dispersos y presionando [Shift] un rango de ellos. ExtendedSelect permite definir cmo se va a comportar este modo de seleccin. Items. Elementos con los que el ListBox ser rellenado. Como ya se adelant, este dato alberga un objeto de la clase TString, y, como tal, lo podemos manipular artesanalmente, pero Delphi brinda la posibilidad de ir aadiendo en forma de lista la relacin de tems que se quieren mostrar. Esta relacin se teclea en una ventana como la de la figura 4. En nuestro ejemplo se especifican los meses del ao.

Figura 4: Definicin de los elementos de un ListBox.

Una posibilidad, no obligada, consiste en transformar esta lista en un archivo (archivo plano de texto ASCII, editable desde cualquier parte), para despus poderlo recuperar y asignar en tiempo de ejecucin.

MultiSelect. Permite que se pueda elegir ms de un tem entre los de una relacin. La opcin por defecto es false. Sorted. Parmetro que, de estar a true, fuerza una ordenacin alfabtica del contenido del ListBox y as lo muestra. Esta opcin ordena los tems y los reasigna, perdiendo cualquier referencia a las posiciones originales.

Ejemplo de ListBox
Pongamos un ejemplo en el que jugaremos con los dos controles vistos. La idea seguida ha sido

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

habilitar dos botones configurables (propiedad Kind a bkCustom) a los que se le quita el texto de su interior y cuyo cometido es ordenar alfabticamente, o no, el ListBox de los meses del ao, un botn estndar para cerrar la ventana (propiedad Kind a bkClose) al que cambiamos la propiedad Caption para que ponga "Cerrar" en vez de "Close", y un ListBox con los meses del ao correctamente rellenados. 1.- Pinchamos en el control ListBox y accedemos a su propiedad Items, aparecer la ventana de la figura 4, donde se rellenar convenientemente. Para que sirva para el ejemplo siguiente, podemos salvar esa relacin bajo el nombre de archivo: MESES.TXT. 2.- Elegimos los botones grficos y colocamos tres. Dos de ellos sern bkCustom (opcin por defecto) y el otro bkClose. Entramos en la propiedad Glyph de los botones configurables y elegimos alguno de los bitmap de ejemplo. La ventana diseada se puede parecer a la de la figura 5.

Figura 5: Ejemplo de prueba

3.- Accedemos a los eventos de los botones para que, al pulsar uno u otro, el ListBox se ordene o no. Ambos pueden llamar al mismo procedimiento, por lo que en el OnClick de ambos escribiremos OrdenDesorden; automticamente se generar el cdigo correspondiente donde ensayaremos lo que se ve en le fuente 1.

// --- Fuente 1 ---------------------------------------------------------procedure TForm1.OrdenDesorden(Sender: TObject); begin if Sender=PbSiSort then LBMeses.Sorted := true else LBMeses.Sorted := false end;

Lo que aqu se especifica es que si el control que ha ejecutado el procedimiento se llama PbSiSort (nombre dado al botn de la bombilla encendida), entonces se modifica la propiedad Sorted del control LBMeses (nombre dado a nuestro ListBox) a true, y si no, se pone a false. Este cdigo funciona bien al ordenar, pero como ya se coment algo ms arriba, una ordenacin supone la reasignacin de los elementos y la prdida de la secuencia original, por lo que no basta con cambiar a false la propiedad Sorted, ya que los elementos no se vuelven a asignar correctamente. Aunque la nica lnea de programacin escrita ha sido la del procedimiento OrdenDesorden, no hemos conseguido nuestro propsito final, aunque eso s, ha faltado muy poco. Para resolverlo, basta con asignar correctamente los distintos tems, y para ello hay dos

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

caminos. Primero voy a empezar por el menos ptimo de los dos, luego intentar hacerlo ms elegante y general. En el fuente 2 se aaden los elementos, uno a uno, al ListBox implicado.

// --- Fuente 2 ---------------------------------------------------------procedure TForm1.OrdenDesorden(Sender: TObject); begin if Sender=PbSiSort then LBMeses.Sorted := true else begin LBMeses.Sorted := false ; LBMeses.Items.Strings[ 0 ] := 'enero' ; LBMeses.Items.Strings[ 1 ] := 'febrero' ; LBMeses.Items.Strings[ 2 ] := 'marzo' ; LBMeses.Items.Strings[ 3 ] := 'abril' ; LBMeses.Items.Strings[ 4 ] := 'mayo' ; LBMeses.Items.Strings[ 5 ] := 'junio' ; LBMeses.Items.Strings[ 6 ] := 'julio' ; LBMeses.Items.Strings[ 7 ] := 'agosto' ; LBMeses.Items.Strings[ 8 ] := 'septiembre' ; LBMeses.Items.Strings[ 9 ] := 'octubre' ; LBMeses.Items.Strings[ 10 ] := 'noviembre' ; LBMeses.Items.Strings[ 11 ] := 'diciembre' end end;

Como se puede apreciar, se accede al dato (o propiedad) Items, el cual dispone de otro dato, Strings de la clase TString, donde se almacena la cadena. Dado que TString es una gran cadena alfanumrica, tenemos la posibilidad de referirnos a sus distintos elementos a travs de un ndice (idntico a los arrays). As, por ejemplo, para invocar al elemento 7 haremos lo siguiente:

LBMeses.Items.Strings[ 7 ] := 'agosto' ;

Basta con recorrrnoslos todos reasignando correctamente para que funcione como queremos. El abordaje menos artesanal pasa por disponer de un archivo de texto donde tener almacenados los tems correctos en sus correctas posiciones; concretamente ese archivo que almacenamos con el nombre de MESES.TXT y que ahora vamos a utilizar. En el fuente 3 se ve cmo quedara segn este nuevo camino (las lneas introducidas manualmente llevan comentarios para distinguirlas de las que se insertan automticamente). Adems se deshabilita el botn recin pulsado (habilitando el otro), para no permitir efectuar la misma operacin dos veces y ver el aspecto de los botones grficos deshabilitados (2 estados en el bitmap). Tambin se aade un elemento nuevo de programacin, la declaracin de variables a nivel de aplicacin y su inicializacin ptima.

// --- Fuente 3 ---------------------------------------------------------. . . var Form1: TForm1; oMeses: TStringList // Variable auxiliar;

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

implementation {$R *.DFM} procedure TForm1.OrdenDesorden(Sender: TObject); begin // Cdigo tecleado if Sender=PbSiSort then begin PBSiSort.Enabled := false; // Inhabilitar botn pulsado PBNoSort.Enabled := true; // Habilitar el otro botn LBMeses.Sorted := true; // Ordenar end else begin PBSiSort.Enabled := true; // Habilitar el otro botn PBNoSort.Enabled := false; // Inhabilitar botn pulsado LBMeses.Sorted := false; // No ordenar // Leer contenido del archivo meses oMeses.LoadFromFile('MESES.TXT'); // Borrar contenido del ListBox LBMeses.Clear(); // Reasignar tems al ListBox LBMeses.Items.AddStrings(oMeses); end end; // Instanciacin de la variable global (creacin) initialization oMeses := TStringList.Create; end.

Por una parte se ha creado la variable oMeses de la clase TStringList, que albergar el contenido del archivo MESES.TXT. Para no inicializar esta variable cada vez que se entra en el procedimiento OrdenDesorden, se hace en el mdulo principal, y bajo la palabra reservada Initialization. En ese punto se crea el objeto mediante:

oMeses := TStringList.Create;

A partir de este momento la variable oMeses se podr utilizar como un objeto de la clase TStringList en todos los procedimientos y funciones de la unidad (Unit) correspondiente a esta ventana, y en concreto en el procedimiento OrdenDesorden. Para leer el contenido del archivo MESES.TXT se recurre al mtodo LoadFromFile() de la clase TStringList, para que quede almacenado en forma de cadena de tems entendible por nuestro ListBox.

oMeses.LoadFromFile('MESES.TXT');

A continuacin aadimos la cadena completa mediante el mtodo AddStrings(), que recibe como

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

parmetro la cadena a aadir; no sin antes vaciar el ListBox (de otra forma aadira 12 meses a los 12 ya almacenados, con lo que dispondramos de un ListBox que ira creciendo segn una progresin aritmtica de razn 12).

LBMeses.Clear(); LBMeses.Items.AddStrings(oMeses);

Antes de acabar, hacer una sola observacin. La variable oMeses no sera necesaria, slo se ha introducido para practicar con elementos del lenguaje. Su omisin, y por tanto su declaracin y su instanciacin, se podra haber resuelto de la siguiente forma

LBMeses.Clear(); LBMeses. Items. AddStrings( TStringList. Create. LoadFromFile('MESES.TXT') );

Pero, realmente, queda algo farragoso y altamente ilegible. En la prxima entrega se seguir la senda entreabierta de las listas deslizantes, aplicando sus funcionalidades a la visualizacin de bitmaps e intentando, por todos los medios, que la mayora del trabajo lo haga Delphi por nosotros, que eso, despus de las vacaciones de verano (en el Hemisferio Norte), es harto agradecido

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (V): Controles (III)


Por Vladimir Algara

Como ya se anunci en el nmero anterior de Algoritmo, en este artculo se abordar la forma de manipular las funcionalidades de los ListBox y as solucionar muchas de las necesidades que se presentan a la hora de perfilar una aplicacin. Recordando lo visto hasta ahora acerca de ListBox, saber que partimos de una coleccin de datos almacenados en forma de tabla, que podemos rellenar a nuestro gusto (manualmente o leyendo los datos almacenados en un archivo). Esta fuente de la que obtener los datos, como veremos ms adelante, no se va a quedar anclada aqu, todo lo contrario, se va a caracterizar por su diversificacin. Una vez relleno el ListBox, poda ser ordenado o restaurado segn el original, as como aplicarle cualesquiera de las propiedades y acciones comunes a los controles, a saber, inhabilitar, redimensionar, ocultar, etc. Resumiendo, no hemos visto gran cosa de lo controles tipo ListBox. A partir de que se conozcan ms formas de rellenar controles de tipo ListBox, se irn viendo ms funcionalidades y ms ventajas, y se, concretamente, es el cometido del presente artculo, por lo tanto, me voy a dejar de zarandajas y me meter en el meollo de la cuestin, porque ya lo dijo..., bla, bla, bla..., etc.,...bla, rebla.

Tipos de ListBox
Los ListBox, o sus hermanos los ComboBox, se encuentran en la carpeta Standard y los iconos que los representan (no seleccionados y seleccionados) son los de la figura 1.

Figura 1. Iconos para ListBox y ComboBox

El nombre (Name) que por defecto se da a un control de tipo ListBox es ListBox1, ListBox2, etc., y esto ser lo primero que iremos cambiando, pues ello permitir una mejor localizacin e identificacin posterior (en el ejemplo final vamos a manipular hasta un total de tres listas deslizantes). Existen otros tipos de ListBox, diferentes a los que vienen en la paleta Standard, de ellos vamos a ver dos, uno destinado a mostrar un rbol de los directorios del disco y otro para ver los archivos de un directorio especfico. Con ambos dos y con uno estndar, construiremos una ventana en la que se podr teclear el nombre y/o la extensin de los archivos que queremos visualizar (ser en un control de edicin). De acuerdo al nombre escrito all se almacenar en un ListBox de la clase TFileListBox la relacin de todos los archivos que cumplan la condicin de la mscara, para facilitar la navegacin por los distintos directorios se recurrir a un ListBox de la clase TFileListBox y para tener una relacin de los archivos que se vayan seleccionando se utilizar un ListBox de la clase TListBox (el estndar). Dado que este ListBox final va a tener un filtro de todos aquellos archivos que han merecido nuestra atencin, si partimos de que los archivos a tratar van a ser BitMaps, podemos completar el ejemplo haciendo que el BitMap elegido se visualice por pantalla.

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Para resumir, y como soy consciente de que la explicacin escrita no ha quedado nada clara, muestro en la figura 2 la pantalla a la que quiero llegar.

Figura 2. Pantalla ejemplo de ListBox

Nota: Los distintos elementos disponibles son: Un control de edicin donde especificar el tipo de archivos que se quieren visualizar (opcin por defecto *.bmp), un ListBox con la estructura de directorios de nuestra unidad, otro ListBox con los archivos que cumplen la mscara (*.bmp) del directorio elegido (existe tambin una parte donde se especifica en qu directorio nos encontramos -en verde en la ventana-), otro ListBox con los elementos elegidos en el anterior y una pantalla de visualizacin del bitmap elegido.

Propiedades de los ListBox


Como viene siendo habitual, hacemos un rpido recorrido por eventos y propiedades no vistos por el momento, y que estn ntimamente ligados a los ListBox. En primer lugar se van a comentar las propiedades de los controles TFileListBox y a continuacin los de TDirectoryListBox.

Propiedades de TFileListBox

FileEdit. Es una propiedad (dato) con la que se asocia, de manera automtica, un ListBox a un control de edicin. El objetivo de esta operacin es que, a medida que nos vamos moviendo por el ListBox o seleccionamos alguno de sus datos, el contenido del control de edicin se amolda a la operacin realizada en el ListBox, quedando ambos controles, pues, sincronizados. Dado que a medida que aadimos controles en una ventana stos se van registrando, si pinchamos sobre la propiedad comentada (FileEdit) aparecer una relacin de los controles de edicin disponibles hasta el momento, nuestra misin es elegir alguno de ellos y echarlo a andar; nada ms sencillo. FileType. Tipos de archivos a visualizar segn sus atributos. Se trata de una estructura en la que se puede elegir entre los distintos tipos de la tabla 1.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Atributo de Oculto Atributo de Archivo del Sistema Muestra la etiqueta del volumen seleccionado ftDirectory Atributo de directorio ftArchive Atributo de Archivo ftNormal Archivo sin atributos Tabla 1. Tipos de archivos segn los atributos

Valor ftReadOnl y ftHidden ftSystem ftVolumeID

Significado Atributo de Slo Lectura

Mask. Mscara por defecto de los archivos que se van a mostrar en el ListBox. Si se deja en blanco no se produce filtrado y, por lo tanto, se manipulan todos los archivos. Para nuestro ejemplo se puede rellenar con *.bmp. ExtendedSelect. En un ListBox se pueden elegir un elemento o varios (para ello hay que modificar la propiedad MultiSelect), y se puede hacer sin ms que ir pinchando aquellos que queramos seleccionar o deseleccionar, o bien, siguiendo las tcnicas estndar de Windows, en las que pulsando la tecla [Ctrl] se eligen elementos dispersos y presionando [Shift] un rango de ellos. ExtendedSelect permite definir cmo se va a comportar este modo de seleccin. MultiSelect. Permite que se pueda elegir ms de un tem entre los de una relacin. La opcin por defecto es false.

Propiedades de TDirectoryListBox

DirLabel. De la misma manera que un control de tipo TFileListBox es posible asociarlo a un control de edicin (a travs del dato FileEdit), un control de tipo TDirectoryListBox se puede asociar a un control de tipo TLabel (texto fijo en pantalla). Como antes, el objetivo de esta operacin es tener ambos controles sincronizados, y que la operacin producida en el primero repercuta en el segundo. En el ejemplo de la figura 2 se ha incluido el texto dentro de un recuadro verde, con la intencin de que quede ms bonito, objetivo que no se consigue. FileList. A travs de esta propiedad se permite otra sincronizacin ms. En este caso el control objeto de sincronizacin es uno del tipo TFileListBox. Dado que un TFileListBox posee una mscara de entrada (visto ms arriba), si sincronizamos un TDirectoryListBox con un TFileListBox, ste se rellenar automticamente cada vez que naveguemos por aqul.
Obsrvese lo fcil que resulta realizar una ventana que vaya dando cuenta de cada uno de nuestros movimientos por los directorios, todo sin trazar una lnea de cdigo.

Ejemplo de visualizacin de BitMaps


Los pasos a seguir para obtener la ventana del ejemplo han sido: 1.- Pinchamos en los controles TLabel para poner el literal deseado en cada uno y, en el caso del que est enmarcado en la caja verde, para cambiar su fuente (Arial, 8 Bold y color

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

clWhite) y su color de fondo (clGreen).


2.- Elegimos los controles de edicin TEdit para habilitar un lugar donde especificar la mscara de los archivos a visualizar. Si bien este control lo podramos asociar al ListBox de archivos, no lo haremos, pues la funcionalidad que se le dar ser, a mi juicio, ms interesante que el mero hecho de la sincronizacin. Dado que al ubicar un control de edicin ste se rellena automticamente con el literal Edit1 modificaremos su propiedad Text para dejarlo en blanco o, siguiendo un criterio que ms interesante, lo rellenaremos con *.bmp. 3.- Elegimos un control TFileListBox. Se puede comprobar que se permite su asociacin con cualquier control de edicin presente en la ventana, y en concreto con el que hemos puesto en el paso 2. 4.- Elegimos un control TListBox que se rellenar cuando elijamos, haciendo doble clic, desde el ListBox del paso 3. 5.- Elegimos un control TDirectoryListBox y lo asociamos mediante su propiedad DirLabel con el control de edicin de la caja verde (a todo esto, la caja verde se hace con un control de tipo TShape, que se encuentra en la paleta Additional), y asociamos su propiedad FileList con el ListBox del paso 3. Buf!. 6.- Sin trazar una sola lnea de cdigo ya tenemos mucho. Se puede poner en marcha y ver el resultado de las distintas componentes de la ventana. 7.- Para completar un poco la aplicacin y para que no sea Delphi el nico que trabaje, se van a aadir un par de botones, uno de cerrar ventana y otro para visualizar el BitMap del ListBox del paso 4 (tambin se podr visualizar haciendo doble clic sobre el ListBox). Para la ubicacin y manipulacin de archivos grficos existe un control que se encarga de ellos, este control es de la clase TImage. Un control de este tipo permite, entre otras cosas, ajustar el BitMap a su tamao o slo visualizar, en el rea definida, aquella porcin que quepa. Alguna de las propiedades ms importantes de los controles TImage, o al menos aquellos que vamos a manejar en este ejemplo, son: -

AutoSize. Obvia el tamao prefijado del control TImage, de tal forma que si el archivo grfico a visualizar es mayor que el rea definida, sta se ignora y el BMP ocupa el total de su tamao. Esto puede provocar, incluso, que ni la ventana pueda albergarlo, por lo que, automticamente, aparecern en dicha ventana las barras de desplazamiento oportunas. Center. Centra la imagen en el rea definida, si no la sita en el ngulo superior derecho. Picture. Mediante esta propiedad se asigna al control la imagen que se quiere visualizar. Dado que lo que se pretende hacer es volcar el contenido de una imagen seleccionada por nosotros, en este ejemplo se dejar en blanco dicha propiedad Picture, y se asignar, en tiempo de ejecucin, de la siguiente forma:
Imagen.Picture.LoadFromFile( <Archivo> );

Stretch. Obliga a que el BMP se ajuste al tamao fijado o, de no caber, se visualice slo lo que quepa en el rea definida. Esta propiedad, que en principio es muy potente, puede hacer que un BMP de gran tamao quede reducido y distrosionado excesivamente al ubicarlo en un recinto excesivamente pequeo. En nuestro caso lo vamos a dejar a false, cediendo el control del tamao a otro control auxiliar.

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Precisamente porque los archivos grficos pueden ser enormes o pequeos, apaisados u horizontales, alargados, etc., sera bueno reservar esa famosa zona de pantalla donde ubicar el archivo, independientemente del formato de ste. Para este cometido se va a recurrir a un control del tipo TScrollBox, y dentro de l ubicaremos la imagen (TImage). La operativa a seguir es ubicar, en primer lugar, un TScrollBox y despus un TImage dentro de l. Esto hace que el control TImage quede constreido al control padre y que, en ningn caso, se pueda escapar de su recinto. Las propiedades que nos pueden interesar en los controles de tipo TScrollBox son: -

AutoScroll. Pone, de manera automtica y cuando sea necesario, barras de desplazamiento vertical y horizontal. Ponindolo a true conseguimos que, cuando la imagen sea menor que el recuento definido, aparezca en su totalidad, y cuando no, podamos desplazarlos para verla en su totalidad. BorderStyle: Tipo de marco que se va a utilizar, segn los valores bSingle (tal como aparece en la figura 2) y bNone (sin marco).

Una vez ubicado el control TImage dentro de la caja TScrollBox hacemos que aqul se ajuste al tamao total de ste, lo cual se puede consigue con la propiedad Align de TImage. Asignando a Align la constante alClient forzamos que toda la imagen se amolde al tamao de la caja, pero existe un pero; si visualizamos la imagen en tiempo de ejecucin no vamos a conseguir que aparezcan las mencionadas barras de desplazamiento. Estas barras slo aparecen cuando la propiedad Align est a alNone. Por lo tanto, en primera instancia, podemos elegir alCliente (lo cual provocar que el editor de ventanas se encargue de colocar y redimensionar TImagen a los contornos de la caja) e inmediatamente despus cambiarlo a alNone, para conseguir el efecto deseado en tiempo de ejecucin.

8.- Accedemos a los eventos del botn de visualizacin, concretamente a OnClick, para que al pulsar sobre el Botn de Ver se muestre el contenido del archivo grfico elegido. A este procedimiento se le ha llamado VerBmp y su contenido es el del fuente 1. En l se inicializa la variable nPos, la cual servir para determinar qu elemento del ListBox "estndar" (el de la clase TListBox) se ha elegido. Una vez que se tiene la posicin en nPos la utilizamos para extraer el tem concreto, todo ello a travs del dato Items del ListBox (consistente en una cadena de caracteres organizada en forma de tabla o array)

ListBox2.Items[nPos]

Esto har que dispongamos del nombre del archivo y su ruta, que es lo que efectivamente se guarda en la lista deslizante.

// --- Fuente 1 --------------------------------------------------------procedure TForm1.VerBmp(Sender: TObject); var nPos: integer; begin nPos := ListBox2.ItemIndex; Imagen.Picture.LoadFromFile( ListBox2.Items[nPos] ); end;

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Si partimos de que no slo queremos visualizar el BMP cuando pulsemos el botn de Ver, sino tambin al hacer doble clic en el ListBox, habr que manipular el evento OnDblClick de dicho ListBox. Dado que la operacin que hay que realizar en este caso es idntica a la que se hace cuando pulsamos el botn de Ver, basta con asociar el mismo procedimiento VerBMP ya existente, y que es el que est definido en el fuente 1. Ambos llaman al mismo procedimiento, por lo que en el OnClick del botn Ver y el OnDblClick del ListBox aparecer la llamada a VerBmp.

9.- Accedemos a los eventos del control de edicin, para que cada vez que all se escriba algo, ese algo se asuma como mscara del TFileListBox. El evento que hay que manipular es OnChange del control de edicin, donde ensayaremos lo que se ve en le fuente 2. Por medio del dato Text del control de edicin (en nuestro caso EditDir) accedemos al contenido del control (lo que hay escrito en ese preciso instante). Con ello modificamos la mscara actual, lo cual se hace alterando el contenido del dato Mask de TFileListBox (en nuestro caso BMPListBox).

// --- Fuente 2 --------------------------------------------------------procedure TForm1.CambiarMascara(Sender: TObject); begin BMPListBox.Mask := EditDir.Text; end;

10.- Por ltimo, queda habilitar un mtodo que permita transferir el dato seleccionado en el ListBox de archivos al ListBox estndar. Comnmente esta operacin se realiza tras hacer doble clic en el elemento deseado, por lo que, nuevamente, habr que manipular el evento OnDblClick, esta vez del TFileListBox. Si al procedimiento lo llamamos Exportar, bastar con escribir esto en la casilla asociada a OnDblClick y pulsar [Intro]; en la porcin de cdigo que aparecer seguidamente aadimos las lneas que nos interesan. Como habamos comentado en las lneas de ms arriba, los elementos de un ListBox se almacenan en el dato Items, pero cuando manipulamos un ListBox de archivos est disponible otro dato adicional llamado FileName, donde se almacena la unidad, directorio, nombre y extensin del archivo (toda la ruta). Bastar con decir:

BMPListBox.FileName;

Para disponer del dato que nos interesa. Como vimos en el artculo anterior, para aadir datos a un ListBox se haba de recurrir al mtodo Add, pasndole como parmetro la cadena a aadir, por lo tanto:

cCadena := BMPListBox.FileName; ListBox2.items.Add( cCadena );

Donde cCadena habr que inicializarla. En caso de no querer utilizar una variable intermedia, bastar con sustituirlo por su valor efectivo.
6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Ya que estamos en el procedimiento invocado cada vez que se hace doble clic en el ListBox de archivos, podra ser aqu, tambin, donde se habilitara o no el botn de VerBMP. Como sabemos, este botn se encarga de mostrar el BMP seleccionado en el ListBox, pero si ocurriera que ese ListBox no contuviese an ningn elemento, intentara ver "algo" que an no existe, provocando un error de programa. Para evitar esta situacin se puede inhabilitar inicialmente el boton de Ver, y slo habilitarlo en el mtodo Exportar que estamos perfilando.

PBVer.Enabled := true

Resumiendo, el procedimiento Exportar quedar como se ve en el fuente 3

// --- Fuente 3 --------------------------------------------------------procedure TForm1.Exportar(Sender: TObject); begin ListBox2.items.Add( BMPListBox.FileName ); PBVer.Enabled := true end;

Obsrvese en el fuente 3 cmo no se realiza ningn control sobre el elemento que se va a volcar; esto quiere decir que podremos transferir un mismo archivo tantas veces como doble clic hagamos en el TFileListBox. Este control se puede realizar recorrindose el ListBox de archivos y comprobando su existencia, del resultado de dicha verificacin depender que el elemento se transfiera o no. Sabemos que los elementos del ListBox se almacenan en el dato Items, y que ste pertenece a la clase TString, por lo que se podr hacer uso de cualquiera de sus mtodos y datos. Uno de ellos es IndexOf, encargado de buscar una cadena dentro de un TString. Cuando IndexOf encuentra la cadena buscada, devuelve la posicin que ocupa (siendo 0 la primera de ellas, 1 la segunda y as sucesivamente). Cuando IndexOf devuelve -1 quiere decir que la cadena buscada no se encuentra. Ser en este caso, y no en otro, cuando habremos de transferir la informacin. Si vemos el contenido del fuente 4, que no es ms que una ligera modificacin sobre el fuente 3 para tener en cuenta esta eventualidad, sabremos qu quiero decir.

// --- Fuente 4 --------------------------------------------------------procedure TForm1.Exportar(Sender: TObject); begin if ListBox2.Items.IndexOf( BMPListBox.FileName ) = -1 then begin ListBox2.items.Add( BMPListBox.FileName ); PBVer.Enabled := true end end;

Conclusin
7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Concluir con Delphi es muy sencillo, pero tambin muy repetitivo. Se trata de un lenguaje y una arquitectura que con poqusimas lneas de cdigo permite realizar grandes cosas. En este ejemplo, sin ir ms lejos, se lanz un programa en el que interactuaban una serie de controles, todo ello gestionado desde el editor; fue despus, tratando de encontrarle las cosquillas, cuando tuvimos que escribir la friolera de 9 lneas de cdigo, de las cuales, si omitimos la variable (que solo est puesta por dar algo ms de claridad al cdigo), los begin y los end, se nos quedan en 5. Esto, en mi tierra, es hacer las cosas bien.

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (VI): Controles (IV)


Por Vladimir Algara

Para seguir avanzando en el mundo de los controles y retomar el hilo desde donde se abandon en la entrega anterior, expondr el objetivo del presente artculo. Hasta lo visto, cualquier ejemplo analizado se ha desarrollado y resuelto en una sola ventana, pero en ningn caso se ha recurrido a mostrar una segunda (o ms) en la que seguir completando los datos de la original. Partiendo del ejemplo del nmero anterior, en el que se manipulaban un montn de ListBox y al final se mostraba un archivo BMP, dividiremos la ventana para que, en la primera, efectivamente, se permita movernos por los directorios, elegir el/los archivos oportunos, poner una mscara que filtre el contenido del ListBox de archivos, etc., y la segunda dejarla, exclusivamente, para la visualizacin y manipulacin del archivo grfico. De acuerdo a esta lgica, por un lado se abordar la manipulacin de la ventana de arranque de la aplicacin, que es la que se ve en la figura 1, y por otro la gestin del BMP, la de la figura 2.

Figura 1. Aspecto de la primera ventana.

La ventana de la figura 1 apenas merece explicacin respecto a lo expuesto en la entrega del mes pasado, pues, bsicamente, lo nico que se ha hecho con ella ha sido quitarle controles, y los que han sobrevivido quedaron suficientemente explicados all. La de la figura 2, si bien posee el mismo control para visualizar la imagen, ha crecido en su casustica, pues ha pasado a tener en cuenta qu archivo grfico se ve, si hay otros ms susceptibles de mostrarse, si se quiere asignar un tamao determinado o si se quiere ajustar la imagen al recinto definido (bien expandiendo, bien reduciendo el BMP).

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 2. Aspecto de la segunda ventana.

Bsicamente, todo esto se controlar por medio de las propiedades Stretch y AutoSize. Ambas almacenan un valor lgico, para activarlas o desactivarlas, y su significado es: -

Stretch (ajuste): Amoldar la figura al recinto especificado, de tal manera que si la figura es ms pequea que el recinto, sta se agrandar, agregando pixeles al original para que ocupe totalmente la superficie, y si es ms grande que el recinto se eliminarn pixeles hasta que quepa. La distorsin de la imagen se ve tanto ms acentuada cuanto menos se parezcan las proporciones de la imagen al recinto predefinido. AutoSize (tamao automtico): Permite supeditar el recinto fijado al tamao real de la imagen, de tal manera que si el archivo BMP es menor o mayor que la pantalla de visualizacin (cosa bastante habitual), el control que alberga la imagen se queda con el nuevo tamao. Esto es as mientras dure la sesin en la que estemos trabajando y, dado que en nuestro recinto vamos a tener que visualizar cualquier cantidad de imgenes, ser bueno almacenar las coordenadas y dimensiones originales para poder restaurarlas cuando lo creamos necesario.

Adems, y dado que vamos a jugar con las coordenadas del BMP, se habilita un conjunto de botones de radio (RadioButtons) para ajustar (hacer Stretch), visualizar al tamao real (no hacer Stretch) o personalizar el tamao del BMP. Si lo que se pretende es definir las dimensiones de la imagen, es lgico pensar en dos controles de edicin donde indicar el ancho y el alto (estos controles debern estar habilitados cuando queramos personalizar, y deshabilitados en el resto de los casos.

Situaciones
Antes de pasar a examinar las caractersticas de cada uno de los elementos que completarn el ejemplo, paso a enumerar los casos que nos vamos a encontrar, segn la operacin que se desee hacer con el BMP y el tamao original de ste. Para BMPs ms pequeos que el recinto de visualizacin. Tanto ajustar como mostrar en

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

tamao original no forzarn a que haya barras de desplazamiento que permitan recorrer el BMP en su totalidad, pues, al ser ms pequeo, lo contemplaremos completo. Sin embargo, cuando se fijan las dimensiones, s habr que tener en cuenta que el resultado final exceda del habitculo predefinido. Para BMPs ms grandes que el recinto de visualizacin. En este caso ajustar no fuerza el redimensionamiento, pero s la vista a tamao original, que forzar a que existan barras de desplazamiento para recorrer el BMP en su totalidad. Por otra parte, la lgica a seguir cuando se trata de fijar las dimensiones es idntica a la anterior.

De acuerdo a lo expuesto, las situaciones en las que se puede encontrar un BMP es alguna de las de la tabla 1. En dicha tabla tambin puede verse en qu manera afecta a los estados de dos de las propiedades ms importantes de una imagen, la propiedad Stretch y la propiedad AutoSize.

Tipo Ajustado BMP pequeo S BMP pequeo No BMP pequeo No BMP grande S BMP grande No BMP grande No Tabla 1: Estado de Stretch y

Tanao Original Personalizado No No S No No S No No S No No S AutoSize segn aspecto de BMP.

Stretch true false false true false false

AutoSize false false true false true true

Separacin de bienes
Una vez vistas las situaciones posibles, tomemos el ejemplo del nmero anterior y dividmoslo en las dos partes, las comentadas ms arriba. Para ello: 1.- Se recupera el proyecto del ejemplo del mes anterior. 2.- Se salva con otro nombre para no perder la informacin que ste posea (nunca se sabe hasta dnde habremos de dar marcha atrs). 3.- Se crea un nuevo form que, a todos los efecto, se trata de la nueva ventana que ser invocada desde la principal. Para ello se elige el icono de la barra de herramientas destinada a tal fin, o se procede a su creacin mediante el tem New del men File. Esta ltima operacin nos obliga a elegir entre los distintos tipos de ventanas disponibles, de las cuales se elegir la ms sencilla de todas, la de tipo form, tal y como se indica en la figura 3.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3: Creacin de una nueva ventana

Una vez en posesin de dos ventanas, una con todos los controles y otra con ninguno, basta con mandar cosas de un sitio a otro. La forma ms fcil consiste en visualizar el cdigo asociado a las ventanas actuales. En l se puede observar que cada una de las ventanas tiene una carpeta en la que se almacena su propio cdigo, cuando pinchemos sobre la carpeta Unit1 estaremos accediendo al form1, cuando lo hagamos sobre la carpeta Unit2 estaremos accediendo al form2, y as sucesivamente para el resto de ventanas y sus unidades asociadas a ellas. En las figuras 4 y 5 se ilustra lo que quiero decir,. En la parte de la izquierda de cada figura se ve el editor de cdigo fuente, donde una de las unidades (Units) se llaman LB4 y la otra VerBMP; dependiendo de que una est pinchada o lo est la otra se visualiza, en la parte de la derecha, su ventana asociada.

Figura 4: Ventana principal (form) y cdigo asociado LB4 (unit)

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 5: Ventana para la visualizacin del BMP (form) y cdigo asociado VerBMP (unit)

Una vez en esta situacin bastar con ir a la fuente desde donde queremos copiar (o cortar en este caso), que es LB4, marcar los controles deseados y llevarlos al portapapeles; cambiamos de ventana, activando aqulla que va a recibir los controles almacenados en el portapapeles y nos los traemos desde all. Nota: para cambiar entre cdigo fuente basta con pinchar en la carpeta deseada. Para visualizar la ventana asociada al cdigo elegido se hace mediante el oportuno icono de la barra de herramientas, la opcin Toggle Form/Unit del men View o la pulsacin de la tecla [F12]. En este punto ya nos encontramos con dos ventanas, cada una con la separacin que hemos venido predicando. Ahora basta dejarla bonita redimensionando los controles al tamao que mejor nos parezca y consiguiendo un aspecto similar al que ofrecen las figuras 1 y 2.

Nuevos controles
Como ya se ha adelantado, se han introducido dos controles de lo que an no hemos visto nada, los RadioButton Groups y los Controles de Edicin con Mscara. Un RadioButton Group es un conjunto de RadioButtons con la caracterstica de ser, dentro del grupo, mutuamente excluyentes entre s. Existe en la carpeta Standard la posibilidad de elegir RadioButton individuales, pero cuando queremos agruparlos de manera lgica, lo ms eficaz es recurrir a este otro tipo de agrupacin. El RadioButton Group se encuentra en la carpeta Standard y los iconos que los representan (no seleccionado y seleccionado) son los de la figura 6.

Figura 6: Iconos para RadioButton Group

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Propiedades de los RadioButton Group


Como viene siendo habitual, hacemos un rpido recorrido por eventos y propiedades no vistos por el momento, y que estn ntimamente ligados a los RadioButton Groups.

Caption. Es la propiedad de los literales. Con ella se pone un encabezamiento que indica qu tipo de asociacin se ha hecho para el RadioButton Group. En nuestro caso se ha puesto la descripcin: Presentacin Columns. Cantidad de columnas dentro de la agrupacin. Dado que podemos especificar un nmero arbitrario de elementos, esta propiedad fija la forma en que se van a presentar en pantalla. Lo habitual es que haya una sola columna y que los elementos se presenten como en la figura 2, pero si hubisemos querido que su presentacin fuera horizontal hubiera valido con asignar un 3 al dato Column (nuestro ejemplo tiene tres RadioButton dentro del grupo). ItemIndex. Una agrupacin siempre tendr dos o ms elementos, de los cuales uno ser el que est inicialmente marcado (y desmarcado el resto). Sabiendo que estos controles se rellenan siguiendo la misma lgica que en los ListBox, el primero de los RadioButtons se reconoce por el ndice 0, el segundo por el 1 y as sucesivamente. En nuestro ejemplo partimos de que queremos ver el BMP a tamao real (segunda posicin) por lo que en la propiedad ItemIndex ponemos un 1. Items. Elementos con los que el RadioButton Group ser rellenado. Este dato alberga un objeto de la clase TString por lo que disponemos de la posibilidad de ir aadiendo en forma de lista la relacin de tems que se quieren mostrar.

Propiedades de los Controles de Edicin


El Control MaskEdit se encuentra en la carpeta Adittional y los iconos que los representan (no seleccionado y seleccionado) son los de la figura 7.

Figura 7: Iconos para Controles de Edicin con Mscara

Los controles de edicin con mscara (MaskEdit) tambin disponen de sus particularidades:

AutoSelect. Propiedad que permite seleccionar automticamente el contenido del control de edicin cada vez que ste recibe el foco. En nuestro ejemplo se ha cambiado a false, pues el valor por defecto es true. AutoSize. Propiedad que permite redimensionar el control de edicin a medida que su contenido se va haciendo mayor. CharCase. Tipo de caracteres a utilizar. El valor ecNormal, que es la opcin por defecto, escribe segn cmo se tenga el bloqueo de maysculas, ecUpperCase en mayculas y ecLowerCase minsculas. EditMask. Tipo de mscara que se va a utilizar. Son muchas las mscaras disponibles, y su misin es forzar la escritura como al programador le convenga. Por ejemplo, se podra forzar a escribir siempre nmeros, o con un formato genrico para nmeros de telfono o

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

para NIF. El que nosotros utilizaremos ser el de los nmeros, impidiendo as que se escriba otra cosa que no sean dgitos (adems, se impide que el nmero exceda de tres cifras). Para eso hay que asociar a EditMask la mscara 999 y a MaxLenght el valor 3. Las posibles mscaras se definen o se eligen en la ventana de la figura 8, la cual aparece tras pinchar en el botn de puntos suspensivos asociado a la propiedad EditMask.

Figura 8: Ventana para la definicin de mscaras de edicin

MaxLenght. Longitud mxima permitida a la hora de teclear. Text. Contenido inicial del control. Nuestro ejemplo parte de un valor vaco para los controles de edicin X e Y. PasswordChar. Carcter que se utiliza para encriptar lo que se escribe. En nuestro caso no se quiere encriptar nada, por lo que se deja a #0, valor por defecto.

Ejemplo de visualizacin de BitMaps


Los pasos a seguir para obtener las ventanas del ejemplo han sido: 1.- Hacer la separacin de bienes antedicha 2.- Instanciar la segunda ventana una vez que se pulse el botn de Ver o se haga doble clic sobre el ListBox (habremos de asociar el cdigo del fuente 1 tanto al evento OnClick del botn como al OnDblClick del ListBox).

// --- Fuente 1 --------------------------------------------------------procedure TForm1.VerBmp(Sender: TObject); var nPos: integer; begin nPos := ListBox2.ItemIndex; DlgVerBMP.Show; DlgVerBMP.cLista := ListBox2.Items; DlgVerBMP.nPosicion := nPos; DlgVerBMP.Imagen.Picture.LoadFromFile( ListBox2.Items[nPos] ); end;

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Como se puede apreciar, se hace una llamada al mtodo Show, encargado de visualizar la ventana no modal, sobre una variable llamada DlgVerBMP.

DlgVerBMP.Show;

La variable DlgVerBMP es el nombre que se le dio a la ventana VerBMP en su propiedad Name, y que Delphi se ha encargado de especificar como variable a travs del cdigo generado automticamente (ver fuente 2)

// --- Fuente 2 --------------------------------------------------------. . . type TDlgVerBMP = class(TForm) Cerrar: TBitBtn; RadioGroup1: TRadioGroup; ScrollBox1: TScrollBox; Imagen: TImage; GBCoord: TGroupBox; X: TMaskEdit; Y: TMaskEdit; LabelX: TLabel; LabelY: TLabel; procedure Presenta(Sender: TObject); procedure Activar(nPos: Integer); procedure Tamano(Sender: TObject); procedure Recordar(Sender: TObject); procedure CambiaBMP(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var DlgVerBMP: TDlgVerBMP; . . .

A continuacin se asigna a la variable cLista (inventada por nosotros) la totalidad de los tems del ListBox de archivos y la posicin que ocupa el elegido (se ver ms adelante por qu), para terminar por cargar la imagen (mediante el mtodo LoadFromFile) en el recinto destinado a tal fin. 3.- Importante. Aadir en el apartado uses de LB4 la unidad que contiene la segunda ventana. Si no se hace esto el compilador no podr unir la informacin de una unidad con la de otra, dando el consecuente error y no pudiendo realizar la llamada a una ventana desde otra. En definitiva, en el apartado uses hay que aadir, a la lista que Delphi incorpora automticamente, el literal VerBMP.

uses Windows, Messages, . . . VerBMP;

4.- Sopesando los pasos dados, se puede asegurar que lo menos intuitivo es lo de especificar en el apartado uses la unidad que se quiere utilizar, pero explicado el concepto, parece

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

claro que una aplicacin con multitud de ventanas, no tiene por qu invocar a todas desde todos los sitios, de ah que haya que fijarlo ese sitio y esas ventanas all donde se necesiten, todo ello de acuerdo al diseo dado a la aplicacin y de las necesidades a resolver. Una vez que vemos que todo funciona correctamente hasta el paso 3 (se puede compilar y ejecutar el ejemplo), podemos empezar a utilizar las nuevas funcionalidades conseguidas con los controles estudiados ms arriba, de ah que ubiquemos un RadioButton Group y un MaskEdit. 5.- Determinamos qu hacer cuando se elija alguno de los RadioButton, de acuerdo al evento OnClick de este tipo de controles. En el fuente 3 se ve el cdigo usado para ajustar la imagen, mostrarla a tamao original o personalizar sus dimensiones.

// --- Fuente 3 --------------------------------------------------------procedure TDlgVerBMP.Presenta(Sender: TObject); var nPos: Integer; begin nPos := RadioGroup1.ItemIndex; Activar( nPos ); case nPos of 0 : Imagen.Stretch := True; 1 : Imagen.Stretch := False; 2 : X.SetFocus(); end; end;

Lo primero que hace el procedimiento es provocar una llamada a Activar, pasndole como parmetro el tem que ha sido pulsado en el RadioButton Group. Despus se discierne, en una estructura case, cmo obrar para el tem 1, 2 3 (valores 0, 1 y 2, respectivamente, en nPos). Para el tem 1 se pone el dato Stretch a true, para el tem 2 se modifica a false y para el tem 3 se le da el foco al control de edicin X. Pero pasemos a comprender qu hace el procedimiento Activar. Siempre que no se est personalizando el tamao final del BMP (tems 1 y 2), los controles de edicin X e Y, los literales y la caja que los abarca deberan estar inhabilitados, pasando a estar disponibles solamente cuando se elija el tem 3. Al tratarse de un cdigo que se repite para cada operacin se ha optado por aislarlo en un procedimiento especfico. En el fuente 4, y de acuerdo al valor recibido como parmetro, se activan o desactivan dichos controles. Cuando nPos sea 0 1, el dato Enabled debera estar a false, por lo que se podra ensayar algo como lo que sigue:

if (nPos = 0) or (nPos = 1) then begin GBCoord.Enabled := false; LabelX.Enabled := false; LabelY.Enabled := false; X.Enabled := false; Y.Enabled := false; end else begin GBCoord.Enabled := false;

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

LabelX.Enabled := false; LabelY.Enabled := false; X.Enabled := false; Y.Enabled := false; end;

Pero resulta algo excesivo cuando se puede recoger el valor false o true en una variable y ser esa variable la que se encargue de modificar el contenido del dato Enabled.

if (nPos = 0) or (nPos = 1) then lValor := false else lValor := true; GBCoord.Enabled := lValor; LabelX.Enabled := lValor; LabelY.Enabled := lValor; X.Enabled := lValor; Y.Enabled := lValor;

o, como se hace en el fuente 4, obviar la estructura if y asignar directamente a la variable.

// --- Fuente 4 --------------------------------------------------------procedure TDlgVerBMP.Activar( nPos: Integer ); var lValor : Boolean; begin lValor := not ((nPos = 0) or (nPos = 1)); GBCoord.Enabled := lValor; LabelX.Enabled := lValor; LabelY.Enabled := lValor; X.Enabled := lValor; Y.Enabled := lValor; if not lValor then begin if nPos = 1 then Imagen.AutoSize := True else Imagen.AutoSize := False; Imagen.Width := XOrig; Imagen.Height := YOrig; end; end;

Hasta aqu tenemos asegurado la activacin y la desactivacin de controles de acuerdo al RadioButton elegido, as como el comportamiento de Stretch y AutoSize en los distintos casos. An nos queda tomar como buenos los datos que se introduzcan en los controles de edicin y asignrselos al ancho y alto de la imagen. 6.- Asignacin de los valores tecleados. Ante tal tesitura podemos elegir entre dos caminos. El primero consiste en introducir los valores y, una vez que se consideren aceptables pulsar un botn que actualice lo que se acaba de teclear. El segundo, ms funcional, consiste en actualizar el alto y ancho a medida que las nuevas dimensiones estn siendo introducidas en los controles de edicin. Por ejemplo, si queremos asignar unos valores de 300x459, a medida que escribamos se

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

ir asignando un valor de 3, luego un 30 y luego un 300 para el ancho, y un valor de 4, de 45 y de 459 al alto. Eso, efectivamente, es ms funcional, pero puede darse el caso que un grfico tenga unas dimensiones de 0x0, lo cual no es representable. Por lo tanto, y para llevar a cabo este redimensionamiento dinmico, protegeremos los valores muy pequeos y slo empezaremos a mostrar la imagen a partir de un rango mnimo (que en el ejemplo del fuente 5 se ha fijado en 20). El fuente 5, para que sea invocado a cada pulsacin en los controles de edicin, habr de especificarse en el evento OnChange de ambos EditMask.

// --- Fuente 5 --------------------------------------------------------procedure TDlgVerBMP.Tamano(Sender: TObject); var nValorX, nValorY : Integer; nCod : Integer; begin Val( Trim(X.Text), nValorX, nCod ); Val( Trim(Y.Text), nValorY, nCod ); if (nValorX > 20) and (nValorY > 20) then begin Imagen.Stretch := True; Imagen.Autosize := True; Imagen.Width := nValorX; Imagen.Height := nValorY; end; end;

El contenido de un control de edicin es siempre de tipo carcter, y se recoge por medio del dato Text de dicho control. Por lo tanto, para saber qu dato tiene almacenado el control y as poder fijar la coordenada X (ancho) diremos:

Trim(X.Text)

Donde Trim() es la funcin que se encarga de quitar los blancos sobrantes Una vez obtenida la cadena de caracteres que contiene el valor tecleado la convertimos a un nmero que podemos manipular, por ejemplo, para comparacin, sumas, restas, etc. Esta operacin se hace mediante el uso del procedimiento Val():

Val( cCadena, nValor, nCod )

Donde cCadena es la cadena alfanumrica a convertir, nValor una variable numrica pasada por referencia y donde se recoge el valor convertido y nCod un cdigo de error que se rellena cuando la operacin de conversin ha fallado. De acuerdo con los valores de los controles X e Y, modificamos el alto y el ancho (datos Width y Height, respectivamente) y alteramos AutoSize para que pase a valer true, pero slo cuando ambos controles superen las 20 unidades; por lo que la imagen ms pequea ser de 21x21 pixeles y la ms grande de 999x999 pixeles. Pero esta asignacin a los datos Width y Height hace que la imagen pase a tener,
11
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

efectivamente, esos nuevos valores, lo que har que si queremos ver la imagen tal y como es en realidad no podamos dar marcha atrs. La solucin pasa por recordar en alguna variable los valores originales, y restaurarlos cuando hagan falta. Eso se ha hecho en las variable XOrig e YOrig. Alterando la definicin de la clase podemos acceder o aadir datos pblicos a esa clase (poda haberse hecho en los privados, pues cualquier referencia a ellos se hace desde mtodos de la propia clase). Como se ve en el fuente 6, se ha hecho necesario guardar, adems, una copia de los tems del ListBox de archivos y del tem elegido (estos dos s han de ser pblicos, pues se accede a ellos desde fuera de procedimientos propios de la clase).

// --- Fuente 6 --------------------------------------------------------type TDlgVerBMP = class(TForm) Cerrar: TBitBtn; RadioGroup1: TRadioGroup; ScrollBox1: TScrollBox; Imagen: TImage; GBCoord: TGroupBox; X: TMaskEdit; Y: TMaskEdit; LabelX: TLabel; LabelY: TLabel; procedure Presenta(Sender: TObject); procedure Activar(nPos: Integer); procedure Tamano(Sender: TObject); procedure Recordar(Sender: TObject); procedure CambiaBMP(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } XOrig: Integer; YOrig: Integer; cLista: TStrings; nPosicion: Integer; end;

Ya se dispone de un lugar donde almacenar los valores que, en un determinado momento, puede resultar ventajoso tenerlos; ahora slo falta saber cundo y/o dnde asignarle el valor. Pueden ser varios los sitios donde hacerlo, aunque s parece lgico que la asignacin se haga una sola vez. Para resolver esta cuestin se va a recurrir a los eventos contemplados para la ventana. Los eventos que se pueden interceptar son los de movimiento, redimensionado, activacin, desactivacin de ventana, etc. El que en definitiva nos va a valer para nuestra operativa ser el de creacin de la ventana, identificado con OnCreate. El sencillo cdigo del fuente 7 ser el que se asocie a la creacin de la segunda ventana.

// --- Fuente 7 --------------------------------------------------------procedure TDlgVerBMP.Recordar(Sender: TObject); begin XOrig := Imagen.Width; YOrig := Imagen.Height

12
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

end;

Es decir, al ancho original (XOrig) le asignamos el ancho del control (Witdh) tal y como se ve al aparecer la segunda ventana, y en el alto original (YOrig) almacenamos el alto del control (Height). 7.- Para terminar, y siempre con el afn de dar ms funcionalidad al ejemplo que nos ocupa, se ha implementado una rutina que nos permite recorrer todos los archivos que estn almacenados en el ListBox de archivos. De nuevo nos encontramos ante dos posibles soluciones al problema. Por un lado est la ubicacin de dos botones que permitan avanzar y retroceder a travs de la lista, por otro se pueden utilizar el botn derecho e izquierdo del ratn para ir uno hacia adelante o uno hacia atrs, respectivamente. Este ltimo, aparte de no saturar la ventana con controles, nos permite introducirnos en una nueva operativa, en la que va a entrar en juego las pulsaciones en los botones del ratn. Como siempre, habr que determinar cul es el evento que queremos interceptar, y luego programarlo. Las pulsaciones del ratn que queremos procesar, a priori, parece lgico que sean las que se efectan dentro de la imagen, ignorando aqullas que se hagan en cualquier otro control. Si ahora consultsemos los posibles eventos relacionados con el ratn, aparecera una lista como la de abajo.

OnClick OnDblClick OnMouseDown OnMouseMove OnMouseUp

Los dos primeros (OnClick y OnDblClick) los descartamos, pues slo controlan que se pulse y se suelte el botn principal (una o dos veces). OnMouseMove est pensado para la gestin de cualquier movimiento del ratn. Por ltimo OnMouseUp y OnMouseDown nos informan que un determinado botn se solt o se puls (respectivamente). Para comprender cmo se puede advertir que se utiliz el botn principal o el auxiliar, basta con echar un vistazo al cdigo del fuente 8, generado automticamente por Delphi

// --- Fuente 8 --------------------------------------------------------procedure TDlgVerBMP.CambiaBMP( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer );

Comentemos los parmetros recibidos de manera automtica por el procedimiento. Como siempre, Sender es el control que ha llamado al procedimiento y se utiliza cuando dicho procedimiento es comn a ms de un control. La variable Button es la encargada de almacenar el botn pulsado, pudiendo consultar su contenido segn las constantes predefinidas (mbLeft, mbRight y mbMiddle). La variable Shift guarda informacin acerca de la tecla auxiliar presionada en el teclado, esto es, [Shift], [Alt] y/o [Ctrl], tambin de acuerdo
13
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

a constantes predefinidas (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle y ssDouble). X e Y son las coordenadas de pantalla donde se puls o se solt el botn del ratn. De todas ellas nos bastar con manipular el dato Button, aunque igualmente podramos haber involucrado alguna pulsacin de teclado, y por tanto de parmetro Shift. En el fuente 9, una vez comprendidos los parmetros manipulables, vemos cmo hacer la operacin de avance y retroceso entre imgenes.

// --- Fuente 9 --------------------------------------------------------procedure TDlgVerBMP.CambiaBMP( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer ); begin if Button = mbLeft then if nPosicion > 0 then nPosicion := nPosicion - 1 else nPosicion := 0; if Button = mbRight then begin nPosicion := nPosicion + 1; if nPosicion >= cLista.Count then nPosicion := cLista.Count - 1; end; Imagen.Picture.LoadFromFile( cLista[ nPosicion ] ); end;

Como primera medida se comprueba, por medio de la variable Button, si se puls el botn izquierdo del ratn. Si no, se comprueba si ha sido el botn derecho:

if Button = mbLeft then . . . if Button = mbRight then . . .

Sea como fuere, se manipula el dato nPosicion (una de las variables pblicas de la clase ver fuente 5-) decrementando o incrementando su valor, teniendo cuidado de no sobrepasar el lmite inferior (0) ni el superior (nmero total de elementos del ListBox de archivos menos 1). Sabiendo ya el nuevo valor de nPosicion, capturamos el elemento que se corresponde en el ListBox y que, previamente, hemos almacenado en cLista.

cLista[ nPosicion ]

Conocido ya el elemento que nos interesa lo cargamos, como ya hemos hecho antes, por medio del mtodo LoadFromFile() del control Imagen. Ese ser el cdigo que asociaremos al evento OnMouseUp, pero hay que decir que igualmente se lo podemos asociar a OnMouseDown. Un saludo.

14
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (VII): Aplicaciones MDI


Por Vladimir Algara

En este artculo se van a enumerar los pasos que deben seguirse para proyectar una sencilla aplicacin MDI. Bien es cierto que han sido muchas las veces en las que se ha explicaco el concepto de aplicacin MDI en contraposicin al de SDI, pero me parece obligado hacer una pequea resea de la caracterstica que distingue a una y a otra. Las siglas MDI (Multiple Documents Interface, o lo que es lo mismo Interfaz de Documentos Mltiples) identifican a las aplicaciones en las que se dispone de una ventana principal y todo un conjunto de hijas que dependen de ella; este conjunto puede ser abierto sin necesidad de ir cerrando progresivamente las ventanas ya existentes. En contraposicin a las citadas siglas aparecen las SDI (Single Document Interface, o lo que es lo mismo Interfaz de Documento Sencillo) en el que aparece la presentacin de una nica ventana hija por vez, lo cual quiere decir que para obtener una segunda ventana hija, forzosamente, hay que cerrar la actual. Para ilustrar el ejemplo se va a realizar una aplicacin en la que se permita mostrar un nmero indefinido de ventanas, donde se podr teclear una serie de nmeros, con los cuales operar aritmticamente; es decir, sin pretensin de otra cosa que ilustrar, se crear una rudimentaria calculadora (y la palabra rudimentaria alcanzar con este ejemplo un significado indiscutible) que ser llamada cuantas veces se quiera desde una ventana padre, encargada de distribuir la lgica del funcionamiento a lo largo de la vida de la aplicacin.

Ventana marco (o ventana padre)


Como ya se ha dicho, una aplicacin MDI dispone de una ventana padre que se encarga de la gestin general del programa. Desde ella, y habitualmente por medio de los tems de un men, se llama cuantas veces sea necesario a su o sus ventanas hijas, las cuales tendrn un comportamiento propio como si de programas aislados e independientes se tratara. Como primer paso se crear la ventana marco de aplicacin, a la cual dotaremos con las caractersticas de las ventanas MDI. Esta operacin, como ya estamos acostumbrados a hacer, se realizar modificando la pertinente propiedad del inspector de objetos asociado a la ventana. Por tanto, una vez dentro de Delphi, partamos de un formulario (Form) vaco y cambiemos las propiedades especificadas en la tabla 1.

Propiedad Valor Original Nuevo Valor Caption Form1 Ventana MDI FormStyle fsNormal fsMDIForm Name Form1 VentanaMDI WindowState wsNormal wsMaximized Tabla 1. Valores originales y nuevos para la ventana marco

La propiedad Caption se encarga de cambiar el ttulo de la ventana, FormStyle hace que la ventana no sea una de las creadas por defecto, sino que se comportar como despachadora de ventanas, ser aplicacin MDI, Name hace que cualquier referencia a la ventana padre sea a travs del nombre asignado, ya que siempre ser ms representativo que el genrico Form1, Form2, etc. (siempre que se haga referencia a la ventana padre, ya sea por el cdigo tecleado por nosotros como por el generado automticamente por Delphi, se realizar por medio de este identificativo, en nuestro caso VentanaMDI); por ltimo, se ha modificado la propiedad

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

WindowState para que nada ms arrancar la aplicacin la ventana principal aparezca maximizada a la totalidad de la pantalla).
Ms adelante, cuando dispongamos del men general de la aplicacin, la propiedad Menu habr de ser actualizada con el diseado para la ocasin.

Men principal
Recordemos, someramente, cmo disear nuestros mens; aunque para ms detalles se remite al lector a los manuales de usuario o al artculo sobre mens en Delphi publicado en el nmero 17 de Algoritmo.

Lo elementos que nos encontraremos, tanto para la ventana marco como para las hijas, se describen y enumeran ms abajo. 1.- Lnea donde se escribir cada opcin principal del men. En esta lnea se especifican las distintas opciones principales que componen el cuerpo central del men. 2.- Lneas donde se escribirn cada una de las opciones secundarias. En esta lnea se especifican las distintas subopciones de las opciones principales. 3.- Lneas donde se escribirn cada una de las subopcines. En esta lnea se especifican las distintas subopciones anidadas. En cualquiera de los tres casos anteriores (o cualquier otro nivel de anidacin de subopciones), si quisiramos activar un Hot-Key para cada opcin, bastara con anteponer a la letra en cuestin el smbolo &: &Salir creara como Hot-Key la letra S Para crear subopciones a una opcin, lo nico que tendremos que hacer es pulsar el botn izquierdo del ratn sobre la opcin secundaria seleccionada, eligiendo Create Submenu (o pulsando [Ctrl-flecha derecha]) en el men local asociado. 4.- Separadores entre subopciones. Para aadir este elemento visual basta con escribir un guin y pasar a la siguiente lnea. Aparecer una lnea separadora. 5.- Abreviatura de teclado para acceso rpido a opciones. Los mens, y ms concretamente los tems que componen un men, slo tienen un evento; aqul que sucede cuando se elige alguna de las opciones. Por eso la carpeta Events slo dispone del evento OnClick(). Si queremos especificar un evento concreto, basta con escribir en el combo asociado a OnClick() el nombre del procedimiento que queremos ejecutar cuando hagamos Clic, y pulsar [Intro]. Esto har que el nombre de dicho evento se registre en el bloque type, y que se escriba, automticamente, las lneas esenciales de ese mtodo. Por ejemplo si escribimos SalirClick y asociamos una accin obtendremos el cdigo del fuente 1.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

// --- Fuente 1 -------------------------------------------------------procedure TVentanaMDI.SalirClick(Sender: TObject); begin Close end;

Para confeccionar el men de la ventana principal se han especificado los tems, las teclas aceleradoras y los eventos asociados de la tabla 2.

Items Ejecutar

Caption Acelerador Ejecutar Calculadora C&alculadora Separador Salir Salir Ventanas Ventanas Cascada Cascada Mosaico Mosaico Iconizar Iconizar Tabla 2: Men de la ventana principal

Evento Ctrl-A Ctrl-Z Calcular SalidaClick Cascada Mosaico Iconizar

El aspecto de la ventana principal, tal y como se ha diseado, que no maximizada, debe ser similar al que se muestra en la figura 1.

Figura 1: Aspecto de la ventana principal.

Eventos del men


El evento de Salir de la aplicacin ya se ha comentado, pasemos a comentar los que restan, que son dos. Uno, el de visualizacin de las ventanas instanciadas y que es similar para Cascada, Mosaico e Iconizar. Lo nico que en ellos se hace es llamar al procedimiento que realiza la accin adecuada, y que respectivamente son Cascade, Tile y ArrangeIcons, tal y como se ve en el fuente 2.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

// --- Fuente 2 -------------------------------------------------------procedure TVentanaMDI.Cascada(Sender: TObject); begin Cascade end; procedure TVentanaMDI.Mosaico(Sender: TObject); begin Tile end; procedure TVentanaMDI.Iconizar(Sender: TObject); begin ArrangeIcons end;

El procedimiento en que nos detendremos algo ms ser sobre el encargado de mostrar la calculadora una vez invocada desde el men principal. Se podra ensayar una sencilla llamada al procedimiento Show genrico, pero esta operacin deja sin efecto las especificaciones de la ventana dadas en el inspector de objetos (por ejemplo posicin y tamao), siendo fijadas stas por la ventana padre. Si lo que queremos es que la ventana se muestre segn los parmetros dados al disearla, la forma de proceder ser la que se ofrece en el fuente 3

// --- Fuente 3 -------------------------------------------------------procedure TVentanaMDI.Calcular(Sender: TObject); var CalcForm: TVentanaCalculadora; begin CalcForm := TVentanaCalculadora.Create(Self) end;

Se habilita una variable para dar claridad al cdigo y por si queremos hacerla ms genrica. A continuacin, en vez de ejecutar un Show, creamos un objeto mediante el procedimiento genrico Create, al cual le pasamos como parmetro la ventana marco (Self), para que se sepa quin es el propietario de la ventana recin creada (el de la calculadora). Una vez hecho esto, la ventana aparecer con las caractersticas dadas en el inspector de objetos, y no como la ventana marco fija. Para finalizar, y con las miras puestas en la conservacin de lo que vamos creando, salvaremos nuestro trabajo, pero teniendo la precaucin de darle un nombre distinto al que Delphi le da por defecto. Accediendo a Save as.. del men File le podemos llamar Padre.

Ventana hija
Son las ventanas llamadas desde la ventana principal. Como caracterstica esencial que las define nos encontramos con que la propiedad FormStyle est especificada como fsMDIChild. Esto provoca que su comportamiento est, en todo momento, supeditado a las vicisitudes de la ventana padre.

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Como primer paso, y como ocurri anteriormente, se crear la ventana hija (Child), a la cual dotaremos con las caractersticas de las ventanas MDIChild. Esta operacin se realiza, como antes, modificando la pertinente propiedad del inspector de objetos asociado a la nueva ventana. Las propiedades fijadas se especifican en la tabla 3.

Propiedad Valor Original Nuevo Valor Caption Form1 "Calculadora" FormStyle fsNormal fsMDIChild Name Form1 VentanaCalculadora Tabla 3: Valores originales y nuevos para la ventana hija

Nuevamente, la propiedad Caption se encarga de cambiar el ttulo de la ventana, FormStyle hace que la ventana no sea una de las creadas por defecto, sino que se comportar como hija de la ventana marco Ms adelante, cuando dispongamos del men de la "calculadora", la propiedad Menu habr de ser actualizada.

Men de la calculadora
Para confeccionar el men de la ventana principal se han especificado los tems, las teclas aceleradoras y los eventos asociados de la tabla 4.

Items Nmeros

Caption Acelerador Evento Nmeros 0..9 &0..&9 Operaciones Operaciones Suma Suma Resta Resta Multiplicacin Multiplicacin Divisin Division Igual a Igual a Borrar Borrar Tabla 4: Men de la ventana que alberga la calculadora

El0, El1,.., El9 PbOperar PbOperar PbOperar PbOperar PbIgualar Borrar

El aspecto de la ventana hija debe ser similar al que se muestra en la figura 2.

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 2: Aspecto de la ventana hija

Veamos cmo se comportan los diversos procedimientos y comentemos sus caractersticas ms destacables.

// --- Fuente 4 -------------------------------------------------------procedure TVentanaCalculadora.El0(Sender: TObject); begin Agregar( 0 ) end; procedure TVentanaCalculadora.El1(Sender: TObject); begin Agregar( 1 ) end; . . . . . . procedure TVentanaCalculadora.El9(Sender: TObject); begin Agregar( 9 ) end;

En el fuente 4 se ve cmo en cada uno de los procedimientos asociados a los botones (y a los tems del men) que simbolizan los nmeros de la calculadora (El0, El1,...,El9), se llama a un procedimiento auxiliar que recibe el nmero a aadir en el control de edicin. Una de las muchas mejoras que puede sufrir la "calculadora" es la de impedir teclear un cero si no se ha introducido previamente otro nmero, o permitir teclear nmeros decimales, etc., etc. En cualquier caso el procedimiento Agregar se ve en el fuente 5.

// --- Fuente 5 -------------------------------------------------------var VentanaCalculadora: TVentanaCalculadora; Ch: string[1]; nValor: integer; . . .

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

procedure TVentanaCalculadora.Agregar( nValor: byte ); begin Resul.Text := Resul.Text + IntToStr(nValor) end; . . . initialization Ch := '+'; nValor := 0;

El procedimiento podra no haber pertenecido a la clase TVentanaCalculadora, pero en tal caso no se podra haber accedido a ninguno de los controles de la ventana, y en este procedimiento se altera el contenido del control de edicin. Por tanto, como s es necesario que pertenezca a la clase deberemos informar de ello en la seccin type de su definicin (ver fuente 6). La variables nValor y Ch se han declarado como pblicas del mdulo, y van a servir para almacenar el primer operando y el operador a usar (la inicializacin de ambas variables se hace en la seccin Initialization).

// --- Fuente 6 -------------------------------------------------------type TVentanaCalculadora = class(TForm) MainMenu1: TMainMenu; Nmeros1: TMenuItem; . . . . . . procedure El0(Sender: TObject); procedure El1(Sender: TObject); . . . . . . procedure El9(Sender: TObject); procedure Agregar( nValor: byte ); . . . . . .

Como se ve en la tabla 4, Suma, Resta, Multiplicacin y Divisin tienen un procedimiento comn, el que se ha llamado PBOperar, y dado que es comn habr que distinguir en su interior si se ha llamado por uno o por otro botn (Sender). Si a esto le sumamos que podemos realizar la operacin desde los tems del men de la ventana hija, el Sender podr ser otros cuatro controles ms. En el fuente 7 se ve cmo se discierne entre uno y otro y cmo se almacena, en la variable de tipo cadena Ch, el smbolo a utilizar.

// --- Fuente 7 -------------------------------------------------------procedure TVentanaCalculadora.PBOperar(Sender: TObject); begin if (Sender=PBSuma) or (Sender=SumaMnu) then Ch := '+'; if (Sender=PBResta) or (Sender=RestaMnu) then Ch := '-'; if (Sender=PBMult) or (Sender=MultMnu) then Ch := '*'; if (Sender=PBDiv) or (Sender=DivMnu) then Ch := '/'; nValor := StrToInt( Resul.Text ); Resul.Clear end;

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Cuando se pincha el botn de igual (=) para obtener el resultado, o se elige el tem del men Igual a, se invoca al procedimiento PBIgualar, (ver fuente 8) en el cual se recurre a las dos variables pblicas nValor y Ch con los datos correctamente almacenados, adems se convierte a valor numrico el dato del control de edicin, se calcula convenientemente y se almacena el resultado en el control de edicin.

// --- Fuente 8 -------------------------------------------------------procedure TVentanaCalculadora.PBIgualar(Sender: TObject); var nActual: Integer; nCod: Integer; nResultado: Integer; begin Val( Resul.Text, nActual, nCod ); case Ch[1] of '+': nResultado := nValor + nActual; '-': nResultado := nValor - nActual; '*': nResultado := nValor * nActual; '/': nResultado := nValor div nActual; end; Resul.Text := IntToStr( nResultado ) end;

Otra mejora sera la de realizar la divisin con el operador /, la cual permite obtener decimales (lo cual obligara a tipificar la variable como real, no como integer)., en vez del operador div que resulta, para el ejemplo, tan cmodo como ineficaz.

Relacin entre ventanas


Una aplicacin MDI con ventanas hijas instancia, de manera automtica, al menos una de sus hijas. Hecho esto, y acto seguido, se pueden instanciar ms de la manera que se ha visto en el fuente 3. An as, podemos querer no instanciar ni una sola de ellas de manera automtica, sino dejar esta operacin al buen criterio del usuario. Para hacer esto hay que entrar en la opcin Options... del men Project, y en la carpeta Form desplazar del ListBox de la izquierda al de la derecha todas aquellas ventanas que no queramos lanzar automticamente. En nuestro caso slo hay que trasladar la ventana VentanaCalculadora (ver figura 3), pues slo tenemos un tipo de ventana hija.

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3: Opciones del Proyecto

En lo que a mens se refiere, es habitual mezclar los de las ventanas hijas con el de la padre, haciendo que todos ellos convivan en la ventana marco. Para esto hay que manipular el dato GroupIndex del men, diciendo el nivel que cada men tiene. Por defecto, el valor de GroupIndex es 0, lo cual hara que los mens de las ventanas hijas, que tambin tienen un GroupIndex a 0 por defecto, reemplazara al de la ventana padre. Sin embargo, si al tem Ejecutar (ventana padre) le dejamos el GroupIndex a 0 y al tem Ventanas (tambin de la ventana padre) le reservamos un 9, nos estaremos asegurando de que el tem Ventanas siempre aparecer al final del men. Cuando ahora se instancie la ventana hija slo se reemplazar el tem Ejecutar, y se compartir el de Ventanas. Tambin esto se puede evitar asignando al GroupIndex de todos los tems de la ventana hija el valor 1, quedndonos el aspecto del men como se ve en la figura 4.

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 4: Mens compartidos entre ventanas

Para acabar de depurar el cdigo, diremos que si una ventana hija de una MDI es cerrada (por cualquiera de sus formas de hacerlo), sta no desaparece, sino que se iconiza hasta que la aplicacin general finalice. Si queremos cerrar la ventana y, adems, que sta desaparezca del todo hay que ensayar el cdigo del fuente 9, encargado de destruir el objeto y de liberar la totalidad de la memoria.

// --- Fuente 9 -------------------------------------------------------procedure TVentanaCalculadora.Liberar(Sender: TObject; var Action:TCloseAction); begin Action := caFree end;

En cualquier caso, y cuando se acabe la aplicacin, todas las ventanas hijas desaparecern, sin que el programador se tenga que encargar de recorrrselas cerrndolas o destruyndolas.

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (VIII) Cajas de dilogo estndar(I)


Por Vladimir Algara
En esta entrega me propongo contar algunos de los automatismos que Windows ofrece al programador que explota sus recursos (los de Windows), y todo ello lo desea explotar con Delphi 32. A la hora de desarrollar una aplicacin existen gran cantidad de elementos que son comunes a cualesquiera otras, es por ello que distintos fabricantes hayan dirigido sus esfuerzos a la construccin de unos interfaces capaces de hacer ms clara y accesible la forma de dominar y programar dichos automatismos. Los elementos a los que me refiero, bsicamente, son a las ventanas de configuracin y peticin de datos de Windows (en concreto de Windows 95). Sus ventanas, comunes a cualquier aplicacin que corra bajo este sistema operativo, se suelen emplear para solicitar desde el archivo que va a ser ledo (con su ruta correcta, extensin, atributos...), a configurar la forma en que imprimir la impresora por defecto. Las ventanas que vamos a encontrar son: Recuperacin de archivos (OpenDialogf) Salvaguarda de archivos (SaveDialog) Eleccin de tipos de letra (FontDialog) Ventana de impresin (PrintDialog) Configuracin de la impresin (SetUpPrinterDialog) Bsqueda de cadenas de caracteres en un texto (SearchDialog) Bsqueda y reemplazamiento de cadenas de caracteres (SearchReplaceDialog)

en

un

texto

Ventanas para la apertura de archivos


Todos los ejemplos que se vayan mostrando a lo largo del artculo se basan en los conocimientos que se hayan podido ir adquiriendo en entregas anteriores de esta mi saga interminable. Los nicos elementos novedosos sern los que se han mencionado en el prrafo precedente. Por tanto se asume como conocida gran parte de la operativa seguida en la confeccin de las ventanas de ejemplo, as como las pautas a seguir para la incorporacin y modificacin de cdigo fuente. Cualesquiera de las ventanas estndar que se usarn se encuentran ubicadas en la barra de elementos, bajo la pestaa (tabs) que lleva por nombre Standard Dialogs, en la cual aparece una coleccin de iconos semejante a la que se muestra en la figura 1.

Figura 1. Iconos de la pestaa Standard Dialogs de la barra de elementos.

Como ocurriera con los mens, siempre que se desee elegir unos de estos elementos habremos de ubicarlos en la ventana que va a hacer uso de ellos y luego ser llamados expresamente. A diferencia de los mens (la ventana posea una propiedad -en su inspector de objetos- en la que identificar el men asociado) estas ventanas han de ser instanciadas expresamente desde la ventana que ser su propietaria.
1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

En primer lugar comentaremos la funcionalidad de las ventanas para la apertura de archivos, as como sus caractersticas, dejando para despus el cdigo a ensayar para que pueda operarse con ellas.

Figura 2. Aspecto de una ventana OpenDialog.

Como se puede apreciar en la figura 2, en una ventana OpenDialog se distinguen diversas zonas bien diferenciadas. En la parte superior el directorio en curso (en forma de rbol de directorios), a la derecha los iconos para la realizacin de las operaciones ms habituales (acceder al directorio padre del actual, crear una nueva carpeta que cuelgue de la que nos encontramos, y modos de visualizacin de los archivos mostrados); ms abajo se aprecia una relacin de archivos disponibles, estos archivos se filtran de acuerdo al criterio especificado en el combo de la parte inferior (Archivos de tipo) y que en la figura 2 se corresponde con todos aqullos que tienen extensin BMP. Se permite realizar un segundo filtro, en el que se puede indicar el patrn de nombre que habr de seguir el archivo o grupo de archivos (control de edicin de Nombre de archivo) por medio de los caracteres comodines por todos conocidos. Sea como fuere, una vez obtenido el conjunto de seleccin se podr optar por uno de ellos, bien a travs del botn de abrir, bien a travs de realizar un doble clic. Esto no provoca en s la apertura del archivo, sino slo su seleccin de entre los de una coleccin. Tendr que ser la aplicacin que ha llamado a la ventana de dilogo la que se tendr que encargar, convenientemente, de abrir el archivo elegido. La ventana OpenDialog, por su parte, de lo nico que se encarga es de permitir elegir alguno de los archivos existentes en el equipo, devolviendo dicho nombre o la cadena vaca.

Especificidades desde Delphi


Para crear una ventana OpenDialog desde Delphi, partiremos de una ventana principal desde la que se permitirn unas operaciones determinadas, entre ellas la de llamar a una ventana del tipo que nos ocupa. Una vez llamada podramos, por ejemplo, escribir en el caption de la ventana el nombre del archivo elegido. Creamos una ventana de prueba en la que ubicaremos tres elementos, dos botones (uno para salir y otro para llamar a la ventana OpenDialog) y la propia ventana para la apertura de archivos. La ventana principal quedara como se ve en la figura 3

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3. Ventana de ejemplo para la aplicacin. En el fuente 1 se ven los pasos a seguir para instanciar la ventana OpenDialog desde la ventana principal de la aplicacin.

// --- Fuente 1 ---------------------------------------------------procedure TForm1.LlamarOpenDialog(Sender: TObject); begin if OpenDialog1.Execute then begin Caption := OpenDialog1.FileName; OpenDialog1.InitialDir := ''; end; end;

Por el hecho de ubicar un control de tipo OpenDialog, se crea una variable con nombre OpenDialog1 (que como todas es susceptible de ser cambiada a travs de la propiedad Name desde el Inspector de objetos), que usamos para ejecutar (y por tanto mostrar) la ventana:
if OpenDialog1.Execute then

Si conseguimos ejecutar con xito la ventana, entonces pintamos en el Caption de la ventana padre el nombre (con la ruta) del archivo elegido (si es que se elige alguno) y especificamos como Directorio inicial aqul en el que nos hayamos quedado en la ltima operacin de eleccin de archivo. Para complicar algo ms el ejemplo y no quedarnos en la mera visualizacin del nombre del archivo, lo que haremos ser visualizar el contenido de dicho archivo en un control de edicin (de otra ventana) en el cual podamos modificar su contenido en fondo y forma. Antes de eso repasaremos algunas de las caractersticas propias de las ventanas OpenDialog, para ver cmo configurarlas. En la figura 4 se ve el aspecto tpico que ofrece el Inspector de Objetos para una ventana de tipo OpenDialog.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 4. Inspector de Objetos para una ventana de tipo OpenDialog.

La explicacin de sus propiedades son:

DefaultExt

Extensin por defecto que aparecer en el control de edicin. Cualquiera de los comodines habituales tiene cabida en esta mscara. En nuestro ejemplo especificaremos *.TXT. Determina si el usuario se encontrar con un control de edicin o un Combo a la hora de especificar el archivo que quiere recuperar. Los dos valores permitidos son fsComboBox o fsEdit. Nombre del archivo que se va a recuperar. En nuestro ejemplo podemos especificar PRUEBA. Perfiles de tipos de archivos que se pueden usar para agrupar, de manera lgica, un conjunto de archivos. Como se aprecia en la figura 5, se pueden indicar una serie de literales y asociar stos a una mscara de archivos que cumplan un determinado filtro. A un literal se le puede asociar una o ms mscaras (separando con punto y coma), aunque lo habitual es slo una.

FileEditStyle

FileName Filter

Figura 5. Editor de filtros.


4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

FilterIndex

En caso de que exista una relacin de filtros (especificada segn lo recin comentado), en este punto se indica por cual de ellos empezar. En nuestro ejemplo si especificamos 1, se visualizarn los Archivos de texto (y por tanto los que lleven Extensin TXT). Cuando la opcin FileEditStyle est seleccionada como fsComboBox, en este punto se podr indicar qu histrico de aperturas de archivos se ha llevado a cabo. Directorio a partir del cual se muestran los archivos del equipo. Tipo de archivos que van a ser tenidos en cuenta. Segn los atributos y las caractersticas de los archivos nos podemos encontrar los casos que se muestran en la tabla 1.

HistoryList

InitialDir

Options

Significado Cuando es True permite selecciona ms de un archivo en el ListBox. OfCreatePrompt Cuando es True aparece una caja de dilogo indicando la eleccin de un archivo inexistente. Si se contesta que S, el archivo se crea nuevo. OfExtensionDifferent Se activa cuando el archivo devuelto no se cie a las especificaciones dadas en la propiedad DefaultExt. OfFileMustExist Si es True obliga a que el archivo exista. OfHideReadOnly Si es True oculta los archivos con atributos Read Only. OfNoChangeDir Si es True impide cambiar de directorio. OfNoReadOnlyReturn Si es True aparece un mensaje si el usuario eligi un archivo marcado como Read Only. OfNoTestFileCreate Se invoca cuando se quiere crear un archivo en una red y ste est protegido. OfNoValidate Si es True no se verifica que lo caracteres introducidos para el nombre del archivo sean vlidos. OfOverwritePrompt Si es True se indica, mediante una caja, que el archivo ser sobreescrito. OfReadOnly Si es True el check de archivos de Slo lectura de la caja se marca. OfPathMustExist Si es True slo se podrn especificar rutas vlidas. OfShareAware Si es True se ignora cualquier error ocurrido en red. OfShowHelp Si es True se mostrar un botn de ayuda en la caja de dilogo. Tabla 1. Opciones para los archivos.

Valor OfAllowMultiSelect

Title

Literal de la ventana (caption)

Una vez dadas estas caractersticas a la ventana y ejecutado el programa de ejemplo, aparecer la ventana de la figura 6. Pero antes de lanzarlo, aadamos la funcionalidad comentada ms arriba. Una vez que se elija el archivo, visualizaremos su contenido en un control de edicin multilnea, que pertenecer a una ventana independiente. Para ir ganando terreno aadiremos a esta ventana tres botones, uno para salir de ella, otro para almacenar los hipotticos cambios realizados en el control de edicin, y por tanto en el archivo, y otro que nos va a permitir acceder a las peculiaridades de otra caja de dilogo estndar, la de eleccin de tipos de letra.

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 6. Aspecto de la ventana de dilogo, para las caractersticas dadas El cdigo necesario concerniente a la ventana OpenDialog y por lo tanto para poner en funcionamiento este ejemplo se ve en el fuente 2. Aparece en negrilla el cdigo que ha habido que introducir manualmente.

// --- Fuente 2 --------------------------------------------------------unit OD; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Buttons, StdCtrls, Ventana; type TForm1 = class(TForm) OpenDialog1: TOpenDialog; Button1: TButton; BitBtn1: TBitBtn; Label1: TLabel; procedure LlamarOpenDialog(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; oVentana: TForm2; implementation {$R *.DFM} procedure TForm1.LlamarOpenDialog(Sender: TObject); begin if OpenDialog1.Execute then begin Caption := OpenDialog1.FileName; OpenDialog1.InitialDir := ''; oVentana := TForm2.Create( Form1 ); 6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

oVentana.Show; oVentana.Memo1.Lines.LoadFromFile( OpenDialog1.FileName ); end; end; end.

Como se puede apreciar, se ha aadido a la porcin de cdigo que se vio en el fuente 1 tres lneas ms, las encargadas de instanciar la ventana que albergar el contenido del archivo elegido. Expliqumoslo un poco. Se sigue utilizando Execute para hacer la llamada estndar a la ventana OpenDialog, tambin se sigue sustituyendo el Caption de la ventana padre con el nombre del archivo elegido as como tambin permanece la especificacin del directorio inicial de lectura; pero, adems, se crea una nueva instanciacin, la de la ventana encargada de mostrar el contenido del archivo seleccionado:
oVentana := TForm2.Create( Form1 );

TForm2 es el nombre de la ventana creada, Create es el mtodo encargado de crearla y Form1 es el parmetro pasado a Create para que TForm2 tenga informacin de quin ha sido la ventana que la ha creado. Una vez creada, la mostramos por pantalla, como siempre a travs del mtodo Show
oVentana.Show;

Como lo primero que queremos hacer es visualizar el contenido del archivo seleccionado, recurrimos al mtodo LoadFromFile, el cual recibe como parmetro el nombre del archivo desde el que queremos recuperar la informacin (que ya hemos visto que lo tenemos almacenado en OpenDialog.FileName). El mtodo LoadFromFile se aplica al control de edicin (Memo1) de la ventana recin creada, y ms concretamente a su dato Lines, segn se ve a continuacin:
oVentana.Memo1.Lines.LoadFromFile( OpenDialog1.FileName );

Con esto se consigue que el archivo elegido se muestre en la ventana, pero no se ha tenido la precaucin de comprobar que el tamao del texto no supere el mximo permitido en el control de edicin; tampoco se ha corroborado que se ha elegido un archivo entre los disponibles, aunque esto no produce error alguno no estara de ms el mostrar un mensaje indicativo o impedir salir de la ventana sin haber realizado la eleccin oportuna. Dado que son operaciones exentas de complejidad y no aportan nada nuevo, pasaremos a los elementos que realmente interesan.

Ventanas para la salvaguarda de archivos


Como ha ocurrido con la ventana OpenDialog, siempre que se desee elegir una ventana SaveDialog la habremos de ubicar en la ventana que va a hacer uso de ella y, luego, se llama expresamente. Como hicimos antes, comentaremos la funcionalidad de las ventanas para la salvaguarda de archivos, as como sus caractersticas, dejando para despus el cdigo a ensayar para que pueda operarse con ella.
7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 7. Aspecto de una ventana SaveDialog.

Como se puede apreciar en la figura 7, en una ventana SaveDialog se distinguen las mismas zonas diferenciadas que se distinguan en la ventana OpenDialog. En la parte superior el directorio en curso (en forma de rbol de directorios), a la derecha los iconos para la realizacin de las operaciones ms habituales, etc. Sea como fuere, una vez decidido el nombre que se le va a dar al archivo se podr optar por realizar la salvaguarda, bien a travs del botn de guardar, bien a travs de realizar un doble clic. Esto no provoca en s la salvaguarda del archivo, sino slo su seleccin de entre los de una coleccin. Tendr que ser la aplicacin que ha llamado a la ventana de dilogo la que se tendr que encargar, convenientemente, de guardar el archivo con el nombre elegido. La ventana SaveDialog, por su parte, de lo nico que se encarga es de permitir elegir un nombre en alguno de los directorios y/o unidades existentes en el equipo, devolviendo dicho nombre o la cadena vaca.

Especificidades desde Delphi


Para crear una ventana SaveDialog desde Delphi, partiremos de la ventana antes generada, desde la que se permite la operacin de guardar los cambios hechos en el control de edicin, el cambio de fuentes a usar o su cancelacin. Una vez creada la ventana de prueba quedar como la de la figura 8.

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 8. Ventana de ejemplo para la aplicacin.

Para nuestro ejemplo habamos decidido guardar el contenido del control de edicin multilnea en forma de archivo, lo cual se har al pulsar el botn guardar. Antes de eso repasaremos algunas de las caractersticas propias de las ventanas SaveDialog, para ver cmo configurarlas. La explicacin de sus propiedades son similares a las que se dieron para OpenDialog, de ah que slo se comenten las cambiantes respecto al anterior.

DefaultExt FileName Title

Extensin por defecto que aparecer en el control de edicin. En nuestro ejemplo especificaremos *.TXT. Nombre del archivo que se va a salvar. En nuestro ejemplo podemos especificar DOC. Literal de la ventana (caption). En nuestro ejemplo pondremos "Guardar cambios"

El cdigo necesario concerniente a la ventana SaveDialog y por lo tanto para poner en funcionamiento este ejemplo se ve en el fuente 3. Aparece en negrilla el cdigo que ha habido que introducir manualmente.

// --- Fuente 3 --------------------------------------------------------unit Ventana; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type TForm2 = class(TForm) BitBtn1: TBitBtn; BitBtn2: TBitBtn; Memo1: TMemo; SaveDialog1: TSaveDialog; FontDialog1: TFontDialog; BitBtn3: TBitBtn; procedure GuardarArchivo(Sender: TObject); private { Private declarations }

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

public { Public declarations } end; var Form2: TForm2; implementation {$R *.DFM} procedure TForm2.GuardarArchivo(Sender: TObject); begin if SaveDialog1.Execute then begin SaveDialog1.InitialDir := ''; Memo1.Lines.SaveToFile( SaveDialog1.FileName ); end; end; end.

Como se puede apreciar se ha aadido un cdigo similar al que se us en el fuente 2 para la ventana OpenDialog, el cdigo encargado de almacenar el texto en forma de archivo. Se sigue utilizando Execute para hacer la llamada estndar a la ventana SaveDialog, tambin se sigue especificando el directorio inicial de escritura; pero, adems, se guarda el contenido del control de edicin (Memo1.Lines) en forma de archivo, mediante el mtodo SaveToFile, que recibe como parmetro el nombre del archivo deseado. El nombre de este archivo lo tenemos guardado en el dato FileName de la ventana SaveDialog.
Memo1.Lines.SaveToFile( SaveDialog1.FileName );

Tipos de letra (FontDialog)


Basndonos en que ya disponemos de un sitio donde se est visualizando un texto, vamos a llamar a la ventana estndar FontDialog para cambiar el tipo de letra con el que se muestra Antes de nada repasaremos las caractersticas propias de las ventanas FontDialog, para ver cmo configurarlas. La explicacin de sus propiedades son:

Device

Dispositivo por el que se va a obtener el tipo de letra elegido. En nuestro ejemplo especificaremos fdScreen, para verlo por pantalla, aunque podramos haber especificado fdPrinter (impresora) o ambos (fdBoth). Determina el tipo de fuente a usar, definiendo cada una de sus caractersticas, como son tamao de la letra, color, ancho, si ser negrita o no, etc. Es el mximo valor permitido en lo que a tamao de letra se refiere, mediante este valor podemos limitar superiormente los tamaos disponibles. Es el mnimo valor permitido en lo que a tamao de letra se refiere. En la tabla 2 se muestran los valores que modifican las caractersticas de las fuentes elegidas.

Font MaxFontSize MinFontSize Options

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Significado Si es True slo se pueden seleccionar fuentes que estn marcadas como ANSI Windows. fdEffects Si es True aparecer en la ventana de dilogo la posibilidad de dotar de efectos a las fuentes. fdFixedPitchOnly Si es True slo se permiten fuentes monoespaciadas. fdForceFontExist Si es True aparece una ventana informativa si se elige una fuente que no est presente en el combo mostrado. fdLimitSize Si es True los valores MaxFontSize y MinFontSize pasan a tener sentido. fdNoFaceSel Si es True no aparece ninguna fuente por defecto en la ventana. fdNoOEMFonts Si es True slo se pueden seleccionar fuentes vectoriales de Windows. fdScalableOnly Si es True slo se pueden seleccionar fuentes escalares de Windows. fdNoSimulations Si es True slo se pueden seleccionar fuentes GDI de Windows. fdNoSizeSel Si es True no aparece ningn tamao por defecto en la ventana. fdNoStyleSel Si es True no aparece ningn estilo por defecto en la ventana. fdNoVectorFonts Igual que fdNoOEMFonts. fdShowHelp Si es True aparecer un botn de ayuda (Help) en la ventana. fdTrueTypeOnly Si es True slo se permiten fuentes True Type. fdWysiwyg Si es True slo se permiten fuentes que aparezcan con el mismo aspecto en la impresora y en la pantalla. Tabla 2. Valores para las fuentes. El cdigo necesario concerniente a la ventana FontDialog y por lo tanto para poner en funcionamiento este ejemplo se ve en el fuente 4.

Valor fdAnsiOnly

// --- Fuente 4 --------------------------------------------------------procedure TForm2.CambiarFuente(Sender: TObject); begin FontDialog1.Execute; Memo1.Font := FontDialog1.Font; end;

Como se puede apreciar, se ha tenido que aadir un nuevo procedimiento a la porcin de cdigo que se vio en el fuente 3. Es el encargado de modificar el tipo de letra con que se visualiza el contenido del control de edicin. De nuevo, se sigue utilizando Execute para hacer la llamada estndar a la ventana FontDialog, pero, esta vez, se altera el dato Font del control de edicin multilnea, asignndole aqul que se haya elegido en FontDialog1, la de la ventana encargada de elegir entre los distintos tipos de letras disponibles. El resultado de la recuperacin de un archivo y su alteracin en el modo de visualizarlo se puede ver en la figura 9. En ella se ha elegido un tipo de letra Arial, de paso 10 y negrita.

11
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 9. Cambio de Font en el control de edicin.

Bueno, hasta aqu tres de las ventanas de dilogo estndar que brinda Windows. Para la prxima entrega abordaremos el resto, siguiendo como base del ejemplo el que aqu se ha venido desarrollando.

12
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (IX): Cajas de dilogo estndar(y II)


Por Vladimir Algara
Esta entrega se concibe como la continuacin de la ofrecida en el nmero anterior de Algoritmo, en la que, como en aqulla, me propongo contar todos o casi todos los automatismos que Windows ofrece al programador respecto a las cajas de dilogo estndar, y todo ello, nuevamente, con Delphi 32. Vimos entonces una serie de cajas de dilogo encaminadas a facilitar la vida a todo aqul que se quisiera valer de sus ventajas, dejando para ms adelante las que vamos a ver hoy. Las ventanas que nos quedan por repasar son: Ventana de impresin (PrintDialog) Configuracin de la impresin (SetUpPrinterDialog) Bsqueda de cadenas de caracteres en un texto (SearchDialog) Bsqueda y reemplazamiento de cadenas de caracteres en un texto (SearchReplaceDialog)

Para informacin del resto (recuperacin de archivos -OpenDialog-, salvaguarda de archivos SaveDialog- y eleccin de tipos de letra -FontDialog-) remito al lector a la ya citada referencia de esta misma revista.

Ventanas para la impresin


Todos los ejemplos que se vayan mostrando a lo largo del artculo parten del ejercicio que se fue desarrollando en la primera entrega, y adems se asume una soltura en el manejo y comprensin de la forma en que Delphi opera. Cualesquiera de las ventanas estndar que se usarn se encuentran ubicadas en la barra de elementos, bajo la pestaa (tabs) que lleva por nombre Standard Dialogs, en la cual aparece una coleccin de iconos semejante a la que se muestra en la figura 1, y de los que slo utilizaremos los marcados con una flecha.

Figura 1: Iconos a utilizar de la pestaa Standard Dialogs de la barra de elementos

Como ya se coment, siempre que se elija unos de estos elementos se ubicarn en la ventana y slo sern visibles en tiempo de creacin/modificacin, aunque sern trasparentes a la hora de mostrarla. Una vez disponibles se puede hacer uso de ellos llamndolos expresamente, la forma genrica, ya se vio, es:

<nombre>.Execute

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

En primer lugar abordaremos las ventanas para la impresin de archivos, as como sus caractersticas, dejando para despus el cdigo a ensayar para que pueda operarse con ellas.

Figura 2: Aspecto de una ventana PrintDialog

Como se puede apreciar en la figura 2, en una ventana PrintDialog se distinguen tres secciones principales. En la parte superior todo lo referente a las caractersticas de la impresora definida por defecto (nombre, tipo, ubicacin...), en la parte izquierda el tipo de impresin que se quiere realizar, donde se permite elegir (segn configuracin) si se aplicar a todo el documento, a lo seleccionado o a un rango de pginas, y en la parte derecha las copias a imprimir y la organizacin de stas. De acuerdo con lo que aqu se elija se modificar el contenido de las distintas propiedades (datos) de la ventana, datos que fijarn la forma en que se tendr que comportar la aplicacin de nuestro ejemplo. La ventana PrintDialog, por su parte, de lo nico que se encarga es de determinar si se imprimir o no, el trabajo de volcar lo realmente imprimible lo ha de fijar el procedimiento ejecutado. La forma genrica de su uso es mediante la consulta de lo que Execute devuelve, pues un valor booleano a True, significar que se puls Aceptar en la ventana PrintDialog, y un valor False que se presion Cancelar.

Especificidades desde Delphi


Para crear una ventana PrintDialog desde Delphi se parte de la ventana que contena el control de edicin multilnea a la que, respetando la funcionalidad hasta ahora conseguida, aadimos otras, es decir, tantos botones grficos como ventanas queramos invocar. En la figura 3 se puede apreciar el aspecto que ofrecer para permitir llamar a las ventanas estndar que nos preocupan.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3: Ventana de ejemplo para la aplicacin

Cuando pulsemos el botn de Imprimir aparecer una caja estndar similar a la de la figura 2. Que salga con ms o menos elementos depender de las especificidades dadas en el Inspector de Objetos para una ventana de tipo PrintDialog La explicacin de sus propiedades las abordaremos comenzando por el dato Options, pues muchas de sus caractersticas aportan o quitan luz al resto:

Options

Son los distintos aspectos y componentes de la ventana, algunos mutuamente excluyentes entre s, otros que se complementan. Todos ellos se recogen en la tabla 1. Valor poHelp Significado Si su valor es true aparece un botn de Help. Si su valor es true se permite elegir un rango de pginas para mandar a impresora. Si su valor es true aparece el CheckButton en el que se indica si la impresin del texto elegido va a obtenerse por impresora o en forma de archivo. Si se marca, tendremos que preocuparnos de preguntar si est checked o no y, si lo est, mostrar una ventana para pedir el nombre del archivo de volcado. Si su valor es true se habilita el RadioButton correspondiente a la Seleccin de texto. Si su valor es true y no hay impresora conectada (o no se encuentra disponible) se muestra una ventana informativa de dicha situacin, de la cual slo se puede salir pulsando OK. Si su valor es True y poPrintToFile lo es tambin, el CheckButtom en el que se redirige la impresin a un archivo no aparece.

poPageNums poPrintToFile

poSelection poWarning

poDisablePrintToFile

Tabla 1: Opciones para los archivos

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Collate Copies

Determina la organizacin de las hojas del listado. Cuando es true el CheckButton Organizar aparecer marcado por defecto. Nmero de copias que se desean obtener. De acuerdo con el entero que se almacena en este dato se pueden lanzar tantas copias como las especificadas, de forma similar a lo siguiente:

for nCopias := 1 to PrintDialog1.Copies do . . .

Siendo nCopias una variable auxiliar del programa para el bucle for, PrintDialog1 el nombre de la variable donde se guarda la ventana instanciada y Copies el dato de dicha ventana destinado a almacenar las reproducciones deseadas.

FromPage MaxPage

Fija el comienzo de pgina para la impresin del documento. Su valor por defecto es 0, lo cual quiere decir que la posicin queda sin efecto. Fija el tope mximo permitido a la hora de especificar el rango de impresin. Si dicho tope se superase aparecera un mensaje informativo dando cuenta de ello. Este parmetro no tiene efecto si en Options no est incluido el valor poPageNums. Fija el tope mnimo permitido a la hora de especificar el rango de impresin. Si dicho tope se superase aparecera un mensaje informativo dando cuenta de ello. Este parmetro no tiene efecto si en Options no est incluido el valor poPageNums. Tipo de rango a utilizar en la impresin. Admite tres posibles valores, prAllPages que fija el RadioButton de Todas, prSelection para el de Seleccin y prPageNums para el rango de pginas. En el caso de que en Options est incluido el valor poPrintToFile, este valor permite que el CheckButtom aparezca marcado, o no, por defecto. Fija el final de pgina para la impresin del documento. Su valor por defecto es 0, lo cual quiere decir que la posicin queda sin efecto.

MinPage

PrintRange

PrintToFile ToPage

No existen eventos para este tipo de ventanas. El cdigo necesario concerniente a la ventana PrintDialog y, por lo tanto, para poner en funcionamiento nuestro ejemplo se ve en el fuente 1. Mucho de l se coment en la entrega anterior, y es el que se encarga de almacenar los presuntos cambios realizados en el control de edicin de la ventana y cambiar el aspecto de la letra utilizada. El que realmente nos interesa a nosotros aparece en el procedimiento ImrpimirTexto; lo que est en negrilla es el cdigo que ha habido que introducir manualmente.

// --- Fuente 1 --------------------------------------------------------unit Ventana; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, Printers;

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

type TForm2 = class(TForm) BitBtn1: TBitBtn; BitBtn2: TBitBtn; Memo1: TMemo; SaveDialog1: TSaveDialog; FontDialog1: TFontDialog; BitBtn3: TBitBtn; Imprimir: TBitBtn; SetUp: TBitBtn; Buscar: TBitBtn; BusReem: TBitBtn; PrintDialog1: TPrintDialog; PrinterSetupDialog1: TPrinterSetupDialog; FindDialog1: TFindDialog; ReplaceDialog1: TReplaceDialog; procedure GuardarArchivo(Sender: TObject); procedure CambiarFuente(Sender: TObject); procedure ImrpimirTexto(Sender: TObject); procedure SetUpImpresora(Sender: TObject); procedure BuscaCadena(Sender: TObject); procedure lEncontrado(Sender: TObject); procedure ReemplazaCadena(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.DFM} procedure TForm2.GuardarArchivo(Sender: TObject); begin if SaveDialog1.Execute then begin SaveDialog1.InitialDir := ''; Memo1.Lines.SaveToFile( SaveDialog1.FileName ); end; end; procedure TForm2.CambiarFuente(Sender: TObject); begin FontDialog1.Execute; Memo1.Font := FontDialog1.Font; end; procedure TForm2.ImrpimirTexto(Sender: TObject); var nLinea: Integer; PrintText: TextFile; {variable de tipo file}

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

begin if PrintDialog1.Execute then begin AssignPrn(PrintText); Rewrite(PrintText); Printer.Canvas.Font := Memo1.Font; for nLinea := 0 to Memo1.Lines.Count - 1 do Writeln(PrintText, Memo1.Lines[ nLinea ]); System.CloseFile(PrintText); end; end; end.

Expliqumoslo un poco. Se sigue utilizando Execute para hacer la llamada estndar a la ventana PrintDialog, como ocurra con sus ventanas hermanas, y se consulta el valor devuelto; determinando as si lo que se ha pulsado ha sido Aceptar o Cancelar.

if PrintDialog1.Execute then

Si se puls Aceptar en la ventana estndar de impresin el mtodo Execute devolver un valor true, pasando a ejecutarse la porcin de cdigo existente entre el begin y el end. La funcin AssignPrn() se encarga de asignar un archivo auxiliar al dispositivo de impresin, despus de esto se fuerza una primera escritura que provoca la apertura fsica del archivo declarado (con ReWrite). Por fin el contenido es actualizado en la impresora por medio del dato Canvas de la variable Printer (esta variable se crea de manera automtica para disponer en todo momento de, al menos, una instanciacin de la clase de impresin TPrinter). Una vez definidos los pasos previos necesarios pasamos a recorrer el texto a imprimir almacenado en el control de edicin, tal como se ve ms abajo:

for nLinea := 0 to Memo1.Lines.Count - 1 do Writeln(PrintText, Memo1.Lines[ nLinea ]);

Se utiliza la variable auxiliar nLinea que oscila desde el valor 0 (correspondiente a la lnea 1 del control de edicin) hasta el mximo nmero de lneas almacenadas. Memo1 es la variable que identifica el control de edicin multilnea, Lines es el dato que almacena las cadenas alfanumricas que se han adaptado al ancho del control de edicin y que recibe como parmetro la lnea que se desea consultar. Con todos estos ingredientes lo nico que resta es imprimir fsicamente las distintas lneas, lo cual se realiza con la funcin WriteLn(), encargada de escribir una cadena de caracteres y provocar un salto de lnea. Por ltimo se cierra el archivo auxiliar con CloseFile().

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Ventanas para la configuracin de la impresora


Como ha ocurrido con la ventana PrintDialog y anteriores, siempre que se desee elegir una ventana PrinterSetupDialog la habremos de ubicar en la ventana que va a hacer uso de ella y, luego, llamarla expresamente. Como hicimos antes, comentaremos la funcionalidad de las ventanas para la configuracin de impresoras e impresin, lo cual no nos llevar mucho.

Figura 4: Aspecto de una ventana PrinterSetupDialog

Especificidades desde Delphi


Para crear una ventana PrinterSetupDialog desde Delphi, partiremos de la ventana antes generada, desde la que se permitir la operacin de configuracin. Este tipo de ventanas no posee datos que no hayamos explicado con anterioridad, y como ocurriera con las PrintDialog, no dispone de eventos propios, por lo que su explicacin queda as zanjada. Nos limitaremos a llamarla, desde el botn destinado a tal efecto, de la siguiente manera:

procedure TForm2.SetUpImpresora(Sender: TObject); begin PrinterSetupDialog1.Execute; end;

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Ventanas para la bsqueda de cadenas de caracteres


Las ventanas FindDialog ofrecen un aspecto como el de la figura 5, y sus caractersticas se describen ms abajo.

Figura 5: Aspecto de una ventana FindDialog La explicacin de sus propiedades son similares a las que se dieron para otras Standard Dialog Window, de ah que slo se comenten las cambiantes respecto a las anteriores.

FindText Options

Cadena de caracteres por defecto que aparecer en el control de edicin. En nuestro ejemplo lo dejamos en blanco. Son los distintos aspectos y componentes de la ventana. Todos ellos se recogen en la tabla 2.

Valor

Significado Habilita o no el CheckBox que discierne entre maysculas y minsculas. Habilita o no los RadioButtons para la bsqueda hacia arriba o hacia abajo. Habilita o no el CheckBox que discierne entre palabras exactamente coincidentes o no. Cuando es True se marca la bsqueda hacia abajo. Oculta o no el CheckBox que discierne entre maysculas y minsculas Oculta o no el CheckBox que discierne entre palabras exactamente coincidentes o no. Oculta o no los RadioButtons para la bsqueda hacia arriba o hacia abajo. Cuando est a True marca el CheckBox que discierne entre maysculas y minsculas. Puede ser cambiado manualmente. Se explicar en las ventanas ReplaceDialog. Se explicar en las ventanas ReplaceDialog. Cuando est a True muestra un botn de ayuda. Cuando est a True marca el CheckBox que discierne entre palabras exactamente coincidentes o no. Puede ser cambiado manualmente.

frDisableMatchCase frDisableUpDown frDisableWholeWord frDown frHideMatchCase frHideWholeWord frHideUpDown frMatchCase

frReplace frReplaceAll frShowHelp frWholeWord

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Este tipo de ventanas poseen, al contrario que las precedentes, un evento propio que, como en otras ocasiones, manipularemos a nuestro gusto.

OnFind

Evento al que se llama cada vez que existe una ocurrencia de la cadena buscada. En nuestro caso hemos especificado que el procedimiento invocado va a ser uno que lleva por nombre lEncontrado, el cual se puede ver en el fuente 2 de ms abajo y que forma parte del fuente 1 antes expuesto.

// --- Fuente 2 -------------------------------------------------------. . . private nLineaActual: Integer; { Private declarations } public { Public declarations } end; . . . procedure TForm2.BuscaCadena(Sender: TObject); begin nLineaActual := 0; FindDialog1.Position := Point( 20, 20 ); FindDialog1.Execute; end; procedure TForm2.lEncontrado(Sender: TObject); var I, J, nPos, nCarSaltar: Integer; begin I := nLineaActual; while I <= Memo1.Lines.Count - 1 do begin nPos := Pos( FindDialog1.FindText, Memo1.Lines[I]); if nPos <> 0 then begin nCarSaltar := 0; for J := 0 to I - 1 do nCarSaltar := nCarSaltar + Length(Memo1.Lines[J]); nCarSaltar := nCarSaltar + (I*2); nCarSaltar := nCarSaltar + nPos - 1; Memo1.SetFocus; Memo1.SelStart := nCarSaltar; Memo1.SelLength := Length( FindDialog1.FindText ); nLineaActual := I + 1; I := Memo1.Lines.Count; end else MessageBeep( MB_ICONHAND ); I := I + 1; end; end; . . .

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Como se puede apreciar se ha aadido un cdigo similar al que se us en el fuente 1. Disponemos de dos procedimientos, BuscaCadena que se encarga de instanciar la ventana FindDialog, y lEncotrado que es el que est asociado al evento de xito o fracaso en la bsqueda realizada. En el primero, adems, se inicializa la variable privada de la clase nLineaActual (encargada de saber por que lnea se ha quedado la ltima bsqueda) y se reposiciona la ventana en la pantalla (a efectos de que ambas no se solapen). En el segundo se desarrolla el algoritmo que se encarga de encontrar la cadena en el control de edicin (almacenada en el dato FindText de la ventana estndar de bsqueda), averiguar su posicin dentro del control de edicin, sobreiluminar la cadena en el texto y recordar cul fue la ltima lnea donde se hall la cadena deseada; en caso de no encontrar la ocurrencia, provoca un tono de aviso (en este ejemplo se ha recurrido a la funcin MessageBeep( MB_ICONHAND ) del API de Windows para realizar dicho sonido). Hay que tener en cuenta (y esto corre de su cuenta seor/a lector/a) que la aparicin repetida de una cadena en la misma lnea no se hallara, pues slo se tiene en cuenta la lnea por la que se va, y no la columna. Habramos de acudir a una segunda variable de la clase para ir registrando los valores de la columna actual e ir manipulndolos para calcular correctamente los desplazamientos.

Ventanas para el reemplazamiento de cadenas de caracteres


No me detendr apenas en las ventanas ReplaceDialog pues son casi idnticas a las FindDialog. Su nica diferencia consiste en que con ests (ya lo sabe) se puede sustituir la cadena hallada. Ofrecen un aspecto como el de la figura 6, y sus caractersticas se describen ms abajo.

Figura 6: Aspecto de una ventana ReplaceDialog

FindText: ReplaceText: Options:

Cadena de caracteres por defecto que aparecer en el control de edicin para la bsqueda. En nuestro ejemplo lo dejamos en blanco. Cadena de caracteres por defecto que aparecer en el control de edicin de reemplazamiento. En nuestro ejemplo lo dejamos en blanco. Los posibles valores se recogen en la tabla 2 y 3.

Valor

Significado Especifica que la cadena ReplaceText ocurrencia de la cadena FindText. reemplazar la

frReplace frReplaceAll

Especifica que la cadena ReplaceText reemplazar TODAS las ocurrencias de la cadena FindText.

10
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Este tipo de ventanas poseen adems del evento OnFind de las FindDialog, el evento OnReplace.

OnReplace:

Evento al que se llama cada vez que existe un reemplazamiento de la cadena de bsqueda.

Una operativa similar a la que se ha usado con las ventanas FindDialog se puede aplicar a las ReplaceDialog para realizar bsquedas y reemplazamientos en el control de edicin de nuestra ventana de trabajo. Bueno, hasta aqu las ventanas de dilogo estndar que restaban para completar la saga que se comenz en el nmero anterior y que Windows brinda para la unificacin de tareas entre aplicaciones.

11
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (X) Delphi y Windows 95 (I)


Por Vladimir Algara
Continuando con el afn de avanzar hacia la asimilacin de conceptos y el control de las herramientas brindadas por Delphi, atajaremos los nuevos elementos disponibles en la versin de 32 bits del omnipresente producto estrella de Microsoft, lo cual quiere decir que slo podrn ponerlo en funcionamiento aquellos que posean la versin 2.0 o posterior de Delphi. Ya vimos, hace no muchas entregas, el uso y abuso de los controles, en sta continuaremos con esa saga, pero aplicando los esfuerzos a conocer los nuevos controles aportados en Windows 95. Los distintos controles que vamos a comentar se encuentran, como todo hasta ahora, en la paleta de herramientas (paleta de elementos); bajo la pestaa que lleva por nombre Win95. En ella se pueden encontrar los iconos de la relacin de ms abajo, correspondientes con sus respectivas funcionalidades:

Tabulador de control (carpetas dependientes) Pgina de control (carpetas independientes) Estructura arbrea Barra de marcaje Cabecera de control Spinner (UpDown) Editor de texto enriquecido (RTF) Dada la gran variedad de controles, y dado que cada uno tiene su propia coleccin de especificidades, voy a ir comentando la forma de usarlos (poniendo ejemplos que pretenden ser esclarecedores) hasta completar un tamao aceptable para el presente artculo. Estructura en forma de lista Barra de progreso (barra Gauge) Barra de estado HotKey (teclas activas)

Las carpetas
Antes de comenzar quiero hacer una aclaracin y solicitar el perdn del lector, pues nunca s muy bien cmo referirme a los controles denominados ControlTabs, de ah que, a veces, los llame (o los haya llamado en artculos precedentes a ste) carpetas, pestaas, o simplemente Tabs; as que, teniendo esto en cuenta por ambas partes, intentar referirme a ellos siempre con el mismo nombre (carpetas) y no liarme ms de lo que suelo. Pues bien, los ControlTabs (es broma). Pues bien, las carpetas, son, en mi opinin, unos de los controles ms ingeniosos que tienen las ventanas de Windows, pues en una sola de ellas se puede solicitar gran cantidad de informacin y, adems, tenerla organizada por grupos que cumplen un determinado patrn. Antes de que existieran no haba ms remedio que mostrar gigantescas ventanas para la solicitud de datos en las que cada agrupacin no quedaba ms remedio que identificarla por medio de un GroupBox (cuadro agrupador) y, dentro de l, se disponan los controles pertinentes, o bien se diseaba una ventana por cada grupo de datos.

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Con las carpetas podemos trabajar con una ventana de pequeas dimensiones en la que se permite preguntar multitud de cuestiones, y, adems, gratamente organizadas. Por ejemplo, una de las ventanas de configuracin ms complicadas que yo he visto es la que muestra el procesador de textos Microsoft Word, en su tem Opciones del men Herramientas. En la figura 1 podemos echar un vistazo a la ventana referida, en la que, entre las muchas carpetas que dispone, se ha seleccionado una de las que menos datos solicita (en la figura se puede ver que se trata de la carpeta de Edicin).

Figura 1: Carpetas de Word para la configuracin de Opciones

Todos los ejemplos que se vayan mostrando a lo largo del artculo parten de un ejercicio que se seguir desarrollando en la segundo entrega; adems, se asume una soltura en el manejo y comprensin de la forma en que Delphi opera con el lenguaje y con el diseo de las ventanas, as como la conexin de stas con el inspector de objetos. Cuando estudiamos las carpetas de Windows 95 podemos hacer dos distinciones esenciales; por un lado se encuentran las carpetas que hacen referencia a un mismo elemento y cuyo objetivo suele consistir en usarlo para distinguir sus distintas partes, organizndolas de la manera ms conveniente; por otra parte se dispone de las carpetas que, por decirlo de alguna forma, son independientes entre s (como lo son las de la figura 1 de ms arriba). Respectivamente encontramos estos dos tipos de carpetas bajo el nombre de tabuladores de control (ControlTab) y pginas de control (ControlPage). El ejemplo propuesto consistente en una nica ventana (en entregas posteriores se convertirn en dos), en la que se escoge un tipo de cada uno de los de arriba; unas carpetas dependientes, en la que cada una se corresponde con el captulo de un hipottico libro, y unas carpetas independientes, donde se permite perfilar las caractersticas de una persona segn una serie de parmetros. El resultado final se muestra en la figura 2 y los pasos que se han seguido para llegar a eso se detallan ms abajo.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 2: Ventana conteniendo los dos tipos de carpetas

Especificidades de las carpetas


Vamos a ir explicando por orden y aisladamente, aunque ms adelante comprobaremos que se solapan, cada uno de los tipos de carpetas.

Carpeta del tipo ControlTabs Cuando se elige un ControlTabs (la de los captulos del libro en nuestro ejemplo), slo tenemos la posibilidad de enumerar las distintas carpetas de que va a disponer, sin opcin a ubicar elementos diferentes en diferentes carpetas (como suceder en las del otro tipo). Si, como en nuestro ejemplo, decimos que en esa carpeta va a aparecer un Control de Edicin Multilnea, en cada una de las carpetas aparecer dicho control y no otro (a no ser que lo cambiemos en tiempo de ejecucin, pero esto sera excesivo, pues esa operativa est ya contemplada en las carpetas de tipo PageTabs, y lo nico que conseguiramos sera controlar manualmente algo que ya se hace de manera automtica). La explicacin de las propiedades y de los eventos las abordaremos comenzando por el dato Tabs, pues es el encargado de definir el aspecto, en lo que a literales se refiere, de la carpeta en curso: - Tabs: Se trata de un dato de la clase TStrings, y contiene la relacin de literales que aparecern en las pestaas de cada una de las carpetas que componen nuestro control. Estos literales pueden ser cambiados en tiempo de ejecucin, pero lo habitual es perfilarlos en tiempo de diseo por medio de la ventana de la figura 3. En ella Delphi brinda la posibilidad de ir aadiendo, en forma de lista, la relacin de tems que se quieren mostrar. En nuestro ejemplo se especifican los cuatro captulos del libro.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 3: Definicin de los literales de las carpetas

Una posibilidad, no obligada, consiste en transformar esta lista en un archivo (archivo plano de texto ASCII, editable desde cualquier parte), para despus poderlo recuperar y asignarlo en tiempo de ejecucin. - MultiLine Esta propiedad brinda la posibilidad de mostrar las carpetas en una sola lnea (si no cupieran en la ventana aparecera una barra de desplazamiento que nos permitira llegar a cualquiera de ellas) o en varias (como se apreciaba en la figura 1). La opcin por defecto es el valor lgico false, pero, para nuestro ejemplo, no va a afectar que est en un estado o en otro, ya que una de las modificaciones que vamos a introducir en el control va a ser el de su alineacin respecto de la ventana, y esto, en cualquier caso, tiene ms prioridad que lo guardado en MultiLine. Altura del recinto donde va el literal de las carpetas. Cuando se especifica 0 (valor por defecto) Delphi se encarga de calcular el tamao, en pxels, de acuerdo al tipo de letra utilizado (forma y tamao de Font), pero cuando somos nosotros los que imponemos el valor no habr clculo automtico posible, siendo el valor asignado el que se utilice (aunque esto suponga el sacrificio de parte del texto y lo convirtamos en ilegible). Es un nmero que corresponde a la carpeta que se seleccionar por defecto al visualizar la ventana que contiene el control. Por defecto su valor es de -1, lo cual indica que se tiene que escoger la primera carpeta del conjunto, independientemente de la posicin que sta ocupe. En la fase de diseo los distintos literales aparecen dispuestos consecutivamente, pero esta cadencia se podra alterar al realizar una ordenacin de algn tipo, por ejemplo alfabtica, que hiciera que su posicin variase respecto al original. En este caso los valores internos asociados a cada literal no se reasignaran, por lo que el elemento que ahora ocupa la posicin inicial bien podra tener un TabIndex igual a 3. Esto se soluciona recurriendo al valor -1 que, como adelant, siempre identifica al primer elemento. Las distintas carpetas estn numeradas empezando desde 0 y terminando en Count-1 (nmero de carpetas menos una). Otras propiedades que han sido cambiadas para el ejemplo, pero que no voy a explicar porque ya lo hice en entregas anteriores, son Align (a la que se le ha asignado un valor de alTop para

- TabHeight

- TabIndex

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

que siempre aparezca en la parte superior de la ventana), Hint y ShowHints (para mostrar un pequeo tip cada vez que paremos el cursor del ratn sobre los captulos del libro) y Font (para que cualquier elemento ubicado en la carpeta aparezca con el tipo de letra y tamao establecido por defecto para la carpeta). Por otro lado, las especificaciones dadas al control de edicin multilnea han sido la de fijar Align (que se le ha asignado un valor de alClient para que abarque toda la superficie de la carpeta a la que pertenece) y la de vaciar las lneas para que aparezca totalmente vaco en fase de diseo (propiedad Lines en blanco). En lo que a eventos se refiere, se han manipulado dos de ellos; uno que est estrechamente relacionado con la carpeta (es OnChange y va a ser el que nos permitir realizar una cierta operacin cada vez que se seleccione alguna de las carpetas disponibles; en nuestro ejemplo se controla que se cargue el contenido de un determinado archivo, segn la carpeta elegida) y otro con la ventana (es OnActivate y va a ser el encargado de recuperar el texto inicial que se mostrar en la carpeta; es decir, el de texto correspondiente al Captulo 1). El cdigo que se ensaya en OnActivate se ve en el fuente 1.

// --- Fuente 1 ----------------------------------------------------procedure TVentanaPpal.FormActivate(Sender: TObject); begin Memo1.Lines.LoadFromFile('CAP1.TXT'); end;

Como se aprecia, nos valemos del contenido de un archivo que lleva por nombre CAP1.TXT. Este archivo debe existir y debe estar ubicado en el mismo directorio donde se encuentre el ejecutable de la aplicacin de ejemplo, de lo contrario la puesta en marcha de nuestro ejemplo producir un error. Recurriendo al mtodo LoadFromFile, de la clase TStrings, recuperamos la "valiosa" informacin y la almacenamos en la propiedad Lines de nuestro control de edicin. Esto hace que, nada ms mostrar la ventana, el texto 1 aparezca en la carpeta del Captulo 1, como se supone que debe ser. No hay otra forma de hacerlo, pues los controles de tipo TMemo, aunque s permiten especificar un valor por defecto a partir del contenido de un archivo, slo recuperan el contenido de dicho archivo en la lectura inicial, pero no lo asocian unvocamente; por lo que no se actualizar si cambia la del archivo. Algo similar hacemos con el mtodo OnChange. En el fuente 2 se hace extensiva, a todas las carpetas, la idea aplicada en el fuente 1.

// --- Fuente 2 ----------------------------------------------------procedure TVentanaPpal.MiraCapitulo(Sender: TObject); var nCapitulo: integer; begin nCapitulo := TabCapitulos.TabIndex; case nCapitulo of 0 : Memo1.Lines.LoadFromFile('CAP1.TXT'); 1 : Memo1.Lines.LoadFromFile('CAP2.TXT'); 2 : Memo1.Lines.LoadFromFile('CAP3.TXT'); 3 : Memo1.Lines.LoadFromFile('CAP4.TXT'); end;

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

end;

Como se ve, almacenamos en la variable auxiliar nCapitulo el valor contenido en la propiedad TabIndex del conjunto de carpetas, el cual nos indica qu carpeta en concreto se ha seleccionado. De acuerdo a que haya sido una u otra recurrimos al pertinente archivo. Esta distincin se realiza por medio de una estructura case...end, donde se evalan los valores posibles de la variable nCapitulo. Como alternativa al fuente propuesto, podra haberse recurrido a construir el nombre del archivo como concatenacin de cadenas de caracteres (as evitaramos utilizar el case...end), pues su nombre nos lo permite. Esto lo haramos de la siguiente forma:

// --- Fuente 3 ----------------------------------------------------procedure TVentanaPpal.MiraCapitulo(Sender: TObject); var cCapitulo: string; begin // Se almacena en cCapitulo el nmero de la carpeta elegida ms 1 Str( TabCapitulos.TabIndex + 1, cCapitulo ); // Quitar blancos a la cadena de caracteres cCapitulo := Trim( cCapitulo ); // Componer nombre del archivo sabiendo que todos empiezan por // CAP y tienen extensin TXT Memo1.Lines.LoadFromFile('CAP' + cCapitulo + '.TXT'); end;

Carpeta del tipo PageControl Cuando se elige una carpeta de la clase TPageControl (la que se ha utilizado para definir las caractersticas personales en nuestro ejemplo), tenemos la posibilidad de ubicar en cada una de ellas la cantidad de controles que nos vengan en gana (no como suceda en las del tipo anterior). La explicacin de las propiedades y de los eventos tambin las abordaremos comenzando por el dato anlogo a Tabs, que, como ya sabemos, era el encargado de definir los literales de la carpeta en curso. En este caso, la forma de disear cada carpeta no se hace a travs de una propiedad del Inspector de Objetos, sino a travs del men local asociado a la carpeta. Una vez ubicado el control TPageControl en la ventana estamos en disposicin de hacer clic con el botn secundario del ratn (botn derecho del ratn para los diestros e izquierdo para los zurdos), con lo que surgir un men local como el de la figura 4. En ese men disponemos de tres posibilidades ms de las que habitualmente aparecen, que son la de aadir una nueva pgina (nueva carpeta), ir a la siguiente o ir a la anterior (estas dos ltimas opciones son accesorias, pues podemos seleccionar una u otra carpeta sin ms que pinchar sobre la deseada, y no hace falta para nada recurrir al men).

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 4: Men local de las carpetas

En lo que al Inspector de Objetos se refiere, tendremos dos conjuntos de propiedades segn el punto de la carpeta en el que pinchemos; as, si lo hacemos en la parte de la carpeta destinada a mostrar el literal que la identifica (pestaa) aparecer un Inspector de Objetos en el que se permite alterar las propiedades de la clase TPageControl propiamente dicha, mientras que si pinchamos sobre el "cuerpo" de la carpeta lo que se podr definir sern las propiedades y eventos de la clase TTabSheet. Nos encontramos en un claro ejemplo de clases contenedoras y contenidas. En la programacin orientada al objeto se introduce el concepto de posesin en contraposicin a la herencia mltiple. Un objeto puede almacenar en una o ms de sus propiedades otro objeto, e, incluso, un array de objetos. En este caso la clase TPageControl almacena un array de objetos de la clase TTabSheet. - ActivePage: Se trata del dato que identifica cul de los objetos TTabSheet va a ser el que se encuentre pulsado nada ms mostrar la ventana (ver figura 2). En nuestro ejemplo ponemos el sexo por delante de cualquier otra cosa. Muestra las carpetas en una sola lnea o en varias. La opcin por defecto es false. Altura del recinto donde va el literal de las carpetas. El valor 0 equivale a un clculo automtico.

- MultiLine

- TabHeight

Otras propiedades que han sido cambiadas para el ejemplo son Align (que se le ha asignado un valor de alBottom para que siempre aparezca en la parte inferior de la ventana), Hint y ShowHints (para mostrar un pequeo tip). Hay que hacer una llamada sobre los tips, pues existe uno genrico para el control TPageControl y otros especficos para cada uno de los controles TTabSheet. En lo que a eventos se refiere no se ha manipulado ninguno de ellos, pues no han hecho falta para la operativa de ejemplo y los que hay nuevos son idnticos a los de la clase TTabControl. Por ltimo, partiendo de que en cada carpeta se puede meter lo que nos venga en gana, he aprovechado para utilizar controles que an no habamos visto, los de tipo CheckButtons. Las dems carpetas se ha rellenado usando controles conocidos como RadioButtons y GroupBox, todos ellos los podemos encontrar dentro de la carpeta Standard de la barra de elementos. Recordemos que un RadioButton Group es un conjunto de RadioButtons con la caracterstica de ser, dentro del grupo, mutuamente excluyentes entre s. Aunque existe la posibilidad de
7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

elegir RadioButton individuales, lo ms apropiado es agruparlos de esta manera lgica,.

Propiedades de los CheckButtons


Como viene siendo habitual, hacemos un rpido recorrido por eventos y propiedades no vistos por el momento, y que estn ligados a los CheckButtons. -.AllowGrayed: Permite definir un control de tres estados, donde se puede dejar marcado, desmarcado o indeterminado (el cual se corresponde con una tonalidad gris, que da nombre a la propiedad)

- Caption:
-.Checked:

Es la propiedad en la que se especifica el literal a mostrar. Permite partir de un valor marcado (valor true) o desmarcado (false, por defecto) para el Check. Son los distintos estados posibles y los cuales podemos consultar por medio de los valores predefinidos. Estos valores se recogen en la tabla 1.

-.State:

Descripcin El check box no tiene marca. El check box tiene marca indicando que el usuario ha seleccionado la opcin correspondiente. CbGrayed El check box se encuentra en posicin indeterminada. La aplicacin se tendr que encargar de interpretar qu significado tiene esto. Tabla 1: Valores almacenados segn el estado de un CheckButton

Valor cbUnchecked cbChecked

El nico evento digno de mencin es OnClick que, como su nombre hace pensar, ser el que se llame cada vez que marquemos o desmarquemos el control Bueno, hasta aqu llego, en la prxima entrega, dado que lo ms complicado ya se ha ido repasando, explotaremos la funcionalidad del resto de los nuevos controles de Windows 95. Hasta entonces, un saludo.

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (XI) Delphi y Windows 95 (II)


Por Vladimir Algara
En esta segunda parte voy a continuar con los controles disponibles en Windows 95 y, como ya se vio en la entrega anterior, estn disponibles en la versin de 32 bits de Delphi, es decir, en la 2.0 y posteriores. Los distintos controles que vamos a comentar en esta entrega sern los que se encuentran a continuacin de las carpetas, pues en la anterior, que llevaba el nmero I, se trataron, ampliamente, todo lo referente a ellas. Como recordar el lector, los dos tipos de carpetas venan simbolizados por sendos iconos y se correspondan con:

Tabulador de control (carpetas dependientes) Pgina de control (carpetas independientes) El resto, como los anteriores, se encuentran disponibles en la paleta de herramientas (paleta de elementos); bajo la pestaa que lleva por nombre Win95. Dada la gran variedad de controles, y dado que cada uno tiene su propia coleccin de especificidades, seguir comentando la forma de usarlos, aprovechando el ejemplo del anterior artculo y amplindolo para el que nos ocupa.

Las estructuras arbreas


Estas estructuras son las usadas, por poner un ejemplo por todos conocido, en el Explorador de Windows 95, en el que la seccin de los directorios se encuentra en la parte izquierda (stos se pueden desplegar, comprimir o navegar por ellos). En la figura 1 se muestra la estructura comentada y que pertenece, como ya se ha comentado, al Explorador de Windows 95.

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 1: Estructura arbrea del Explorador

Estas estructuras son, en mi opinin, los controles que ofrecen la mejor organizacin visual de los elementos principales respecto a los subordinados. La principal ventaja consiste en que se permite seleccionar un determinado tem dentro de una jerarqua de padre e hijos, en los que cada familia se puede representar en un compartimento-estanco. Como ocurre en los datos de la figura 1, podemos organizar nuestra informacin en celdillas, que cada una de estas celdillas disponga de un nmero variable de datos (que a su vez puede consistir en otra celdilla) los cuales disponen de distintas caractersticas. Si aplicamos esta lgica a los elementos de la figura 1, cada celdilla se correspondera a cada uno de los directorios, los datos almacenados en estos directorios pueden ser, a su vez, directorios o archivos (lo cuales no aparecen en la seccin de la izquierda, sino en los de la derecha). El siguiente ejemplo se ha desarrollado con la lgica aqu descrita, y su resultado final se puede ver en la figura 2. En l se establecen dos grupos correspondientes a sendos elementos principales (Alfonso y Vladimir), en ellos se albergan tres ramas (Motes, Ojos y Aficiones), cada una de las cuales posee una cantidad concreta de datos, todos ellos estrictamente clasificados y accesibles de manera coherente. Como ocurriera con la seccin de los directorios en el Explorador, estas ramas se pueden contraer y expandir (no as las hojas) y tambin seleccionar desde programa; cualquiera de estas acciones provoca la activacin de un evento que, en caso de programarlo, realizar las acciones pertinentes.

Figura 2: Propiedades y caractersticas para los elementos Alfonso y Vladimir Como hacemos siempre, recorramos las distintas propiedades y eventos disponibles para este control y expliquemos las de ms inters.

Propiedades

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

- Count - Editable - Indent - Item - Items

Nmero de elementos en el rbol. Determines si el valor actualmente seleccionado es editable o no, de acuerdo con su contenido true o false. Nmero de pixeles usados para la separacin horizontal. Retorna el tem del rbol. Almacena todos los tems del rbol. La forma de definirlos, en la fase de diseo de la aplicacin, se puede ver en la ventana de la figura 3. En fase de ejecucin, como veremos ms abajo, se puede alterar la estructura inicialmente fijada.

Figura 3: Definicin de los nodos/tems en tiempo de diseo.

New Item: aade un nuevo nodo. New SubItem: aade un nuevo tem al nodo seleccionado. Delete: Elimina el tem seleccionado Load: Almacena, en forma de archivo, la estructura creada hasta el momento.
- ShowButtons Fuerza la aparicin del smbolo '+' en un nodo comprimido (expansible) y el menos '-' en uno ya expandido (comprimible). - ShowLines - ShowRoot - Sorted - TopItem Fuerza la aparicin de las lneas que conectan los nodos y los tems. Fuerza la aparicin de las lneas que conectan los nodos padres con los nodos hijos. Ordena alfabticamente los literales. Primer tem del rbol.

Mtodos
- AddChildFirst - AddChildObjectFirst - AddFirst - AddObject - AddObjectFirst - Append - AppendChild - AppendChildObject - AppendObject - FullCollapse - FullExpand - GetFirstNode - Insert -SortChildren Aade un nodo al rbol en la primera posicin. Aade un nodo hijo al rbol asocindole un objeto. Aade un tem en el primer nodo. Aade un tem al rbol en la primera posicin. Aade un tem al rbol asocindole un objeto. Agrega al final del rbol un tem. Agrega al final del rbol un nodo. Agrega al final del rbol un nodo asocindole un objeto. Agrega al final del rbol un tem. Comprime todo el rbol. Expande todo el rbol. Devuelve el primer elemento del rbol. Inserta un tem en una posicin concreta del rbol. Ordena alfabticamente los literales de un nodo concreto.

Eventos
3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

-OnChange

Se lanza cuando el aspecto del rbol cambia (despus de comprimir, de aadir, de borrar, etc.). -OnChanging Se lanza cuando el aspecto del rbol cambia (antes de refrescar en pantalla). Se lanza al contraer un nodo. -OnCollapse -OnCollapsing Se lanza al contraer un nodo (antes de refrescar en pantalla). Se lanza al borrar un tem. -OnDeletion Se lanza al editar un tem. -OnEdited Se lanza mientras se est editando un tem. -OnEditting -OnExpanded Se lanza al expandir un nodo. -OnExpanding Se lanza al expandir un nodo (antes de refrescar en pantalla).

Las estructuras detalladas


Estas estructuras tambin son usadas, por poner el mismo ejemplo del Explorador de Windows 95, en la seccin de los archivos, que se encuentra en la parte derecha de la ventana que veamos en la figura 1. los archivos existentes en el directorio/unidad seleccionado. En la figura 1 se muestra la estructura comentada y que pertenece al Explorador de Windows 95. Esta estructuras est destinada a guardar diversa informacin de un elemento, de ah que en el Explorador constituya la mejor de las opciones disponibles, pues cada movimiento en la estructura arbrea se corresponde con una actualizacin de la estructura de detalle (parte derecha de la ventana). Cada archivo consta de distintas propiedades, como son el nombre (propiedad principal), el tamao, el tipo y la fecha y hora de creacin. El siguiente ejemplo, resultado de ejecutar la aplicacin de ejemplo de la entrega correspondiente a este mes, se ha desarrollado con la lgica de ir aadiendo informacin a un determinado concepto, y su resultado final se puede ver en la figura 4. Los encabezamientos (Cab1, Cab2, etc.) son descriptores de lo que aparecer ms abajo, y lo que aparece ms abajo es el resultado de inventar por mi parte informacin absolutamente incoherente.

Figura 4: Ventana con varios controles

Todos los ejemplos que se vayan mostrando a lo largo del artculo parten del ejercicio que se desarroll en la primera entrega; adems, se asume una soltura en el manejo y comprensin de

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

la forma en que Delphi opera con el lenguaje y con el diseo de las ventanas, as como la conexin de stas con el inspector de objetos. Recorramos, aqu tambin, las distintas propiedades y eventos disponibles para este control.

Propiedades
- Columns - EditLabels - IconArrangement - Items Relacin de los objetos TListColumn. Permite o no la edicin de los tems Posicin por defecto de los iconos. Relacin de los objetos TListItem. La forma de definirlos es idntica a la que se explic en el ejemplo de las estructuras arbreas, y, por lo tanto, se definen en tiempo de diseo en una ventana similar a la que se mostr en la figura 3 de ms arriba. Tipo de visualizacin a utilizar. Ver la tabla 1 para especificaciones ms concretas.

- ViewStyle

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Descripcin En forma de lista detallada propiamente dicha En forma de iconos En forma de relacin en la que slo aparece la propiedad principal vsSmallIcon En forma de lista de iconos pequeos Tabla 1: Tipo de listas disponibles. Mxima cantidad de tems disponibles por control. - MaxItems - ShowColumnHead Permitir o no la visualizacin de la cabecera descriptiva.

Valor vsReport vsIcon vsList

Mtodos
- Arrange - Scroll - Sort Reorganizacin de los tems. Desplazamiento de los elementos en la ventana. Permite la ordenacin manual o automtica de los elementos.

Eventos
- OnChange - OnChanging - OnColumnClick Se lanza el aspecto de la lista (despus de aadir, borrar, etc.). Se lanza al cambiar el aspecto de la lista (antes de refrescar en pantalla). Se lanza al pinchar sobre la cabecera de los elementos. Por ejemplo, al pinchar sobre la cabecera destinada a mostrar el nombre del archivo en el Explorador de Windows 95, se produce una ordenacin por dicho nombre, el cdigo encargado de esto debera implementarse en el evento OnColumnClick. Se lanza al borrar un elemento de la lista. Se lanza al editar. Se lanza mientras se est editando un elemento de la lista.

- OnDeletion - OnEdited - OnEditting

Las barras de marcaje (TrackBar)


Se trata, ni ms ni menos, que de una ampliacin (para mejor) de las barras de desplazamiento, con la peculiaridad aadida que se pueden dar, adems de los valores mximo y mnimo alcanzables, unos valores de referencia. Adems, la escala es mucho ms reducida y concreta que la que se obtena con las ScrollBar, por lo que su manejo se hace ms cmodo. Podemos ver una barra de stas (en uno de sus aspectos habituales) en la ventana de la figura 4 de ms arriba. En el ejemplo se muestra un barra en la que elegir una temperatura ambiente (en grados centgrados) y en la que se fija un tope mximo de 70 y un mnimo de -100; adems, se ponen unas marcas de referencia en las que se indican cules han sido el mximo y mnimo valores alcanzados en la Tierra (61 y -78, respectivamente). Todos estos valores son internos a la barra, por lo que para poder visualizarlos ha habido que recurrir a la ubicacin en la ventana de textos fijos.

Propiedades
- LineSize - Max - Min - Orientation Cantidad de marcas a usar en la barra Valor mximo alcanzable en la barra (en nuestro ejemplo 70). Valor mnimo alcanzable en la barra (en nuestro ejemplo -100). Posicin de la barra: horizontal ( tbHorizontal) o vertical (tbVertical). En nuestro ejemplo horizontal.
6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

- PageSize - Position - SelEnd - SelStart - TickMarks

Cantidad de marcas a desplazar cuando se usa avance o retroceso de pgina (en nuestro ejemplo 10). Valor por defecto de la barra (en nuestro ejemplo 0). Punto mximo de referencia (en nuestro ejemplo 61). Punto mnimo de referencia (en nuestro ejemplo -78). Posicin de las marcas respecto de la barra. Ver tabla 2.

Descripcin Arriba de la barra si es horizontal o a la izquierda si es vertical tmBoth A ambos lados de la barra tmBottomRight Abajo de la barra si es horizontal o a la derecha si es vertical Tabla 2: Tipo de posiciones disponibles

Valor tmTopLef

Eventos
El nico evento digno de mencin es OnChange que, como su nombre hace pensar, ser el que se llame cada vez que movamos el control - OnChange Siempre que la barra se mueve, ya sea con el ratn, con las flechas de movimiento o con el avance o retroceso de pgina, se invoca este mtodo. Nosotros lo usaremos para actualizar un texto fijo y que el resultado de mover la barra se vea all fielmente reflejado.

En el fuente 1 se ve lo explicado en el evento OnChange, y adems de aprovecha el valor de la barra para determinar que, al cerrar la ventana, habr un retardo ms o menos largo o no habr ningn tipo de espera. Se actualiza un literal y luego se obra en consecuencia.

// --- Fuente 1 --------------------------------------------------------procedure TDlgFiesta.ActualizarGrados(Sender: TObject); var cGrados: string[4]; begin Str( TrackGrados.Position, cGrados ); Grados.Caption := 'Grados: ' + cGrados; if TrackGrados.Position > 0 then LitBarra.Caption := 'Barra de progreso desde 0 a ' + cGrados else LitBarra.Caption := 'No habr barra de progreso al salir'; end;

Se declara la variable de tipo cadena cGrados (de hasta cuatro caracteres) en la que se almacena el valor actual de la barra (el cual se almacena en el dato interno Position), como dicho valor es de tipo numrico, previamente hay que convertirlo a cadena de caracteres mediante la funcin Str(), resultado que concatenamos con el literal 'Grados: '. El conjunto final se asigna al texto fijo que lleva por nombre Grados. De manera similar se actualiza el texto fijo que lleva por nombre LitBarra, y se hace de acuerdo a que el dato Position de la barra. Cuando sea estrictamente mayor que cero se especificarn la cantidad de unidades que contar nuestra (an inexistente) barra de progreso, en cambio, cuando sea menor o igual que cero, aparecer el texto constante 'No habr barra de progreso al salir'.

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Las barras de progreso


Las barras de progreso o barras Gauge son los controles que se usan cuando se quiere indicar el punto en el que se encuentra un determinado trabajo (por lo habitual largo en el tiempo o en el tamao). As, cuando se necesita realizar una copia de seguridad, por ejemplo, es norma, casi obligada, mostrar el punto en el que nos encontramos y ofrecer una idea orientativa de lo que el proceso va a tardar. Estas dos caractersticas las cubren las barras de progreso, pues al rellenar completamente el recinto disponible a tal efecto nos encontraremos en la situacin de fin del proceso. En nuestro ejemplo se ha utilizado la barra de progreso para provocar un retardo en el cierre de la ventana, que ser tanto ms grande cuanto mayor sea la temperatura elegida en la barra de marcaje comentada en el apartado anterior. Cuando la barra de estado llegue al final (este final habr que fijarlo en tiempo de ejecucin segn el contenido Position de la TrackBar) querr decir que ha contado todo lo que tena que contar y, por ende, deber cerrar la ventana.

Propiedades
- Max - Min - Position - Step Valor mximo alcanzable en la barra (en nuestro TrackGrados.Position). Valor mnimo alcanzable en la barra (en nuestro ejemplo 0). Valor por defecto de la barra (en nuestro ejemplo 0). Cantidad de marcas cuando avance la barra (en nuestro ejemplo 1). ejemplo

En el fuente 2 se ve el cdigo a ensayar para el control de la barra de progreso.

// --- Fuente 2 --------------------------------------------------------procedure TDlgFiesta.TiempoEspera(Sender: TObject); var nCont: integer; nAux: integer; cTope: string[4]; begin ProgressBar1.Min := 0; ProgressBar1.Max := TrackGrados.Position; for nCont := 0 to TrackGrados.Position do begin // Retardo for nAux := 0 to 1000000 do; // Asignar los valores de nCont a la barra de progreso ProgressBar1.Position := nCont; Str( nCont, cTope ); // y asignarlo al literal asociado LitActual.Caption := cTope; // Procesar los mensajes mientras que se encuentre en el bucle Application.ProcessMessages; end; Close; end;

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Como se ve, se declaran todas las variables auxiliares que van a hacer falta en el procedimiento. Como primera medida se asigna a los valores mnimo y mximo los valores de 0 y, como ya hemos dicho, grados de la TrackBar, pasando a continuacin a realizar un bucle que abarca desde 0 hasta el mximo fijado. Dentro del bucle se produce un retardo, que va de 0 a 1000000, despus del cual se procede a actualizar los valores de la barra de progreso y del literal fijo. Si slo hiciramos esto, observaramos cmo, efectivamente, la barra de progreso se iba actualizando, aunque no as el literal fijo. Esto sucede porque nos encontramos actualizando un control que no tiene capacidad para "autorrefrescarse" (el texto fijo) cuando el control de la aplicacin lo tiene un bucle (pues este bucle est acaparando los recursos del sistema mientras nos encontremos dentro de l). Ese es el motivo de que se ponga la siguiente lnea:

Application.ProcessMessages;

que obliga a que los eventos se sigan procesando de la forma esperada, y por lo tanto permitiendo que el texto fijo se actualice. Bueno, hasta aqu llego, en la prxima entrega seguiremos indagando en la funcionalidad del resto de los nuevos controles de Windows 95. Hasta entonces, ponga en marcha el ejemplo anexo y comprueba lo que he querido decir con toda esta perorata. Ah!, un saludo.

9
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (XII) Delphi y Windows 95 (y III)


Por Vladimir Algara
En esta tercera y ltima parte voy a finalizar con los controles disponibles en Windows 95 y, como ya se record en la entrega anterior, slo estn disponibles en las versiones de Delphi a partir de la 2.0 en adelante. Los distintos controles a abordar en esta entrega sern los que se ven a continuacin.

Cabecera de control Barra de estado Spinner (UpDown) HotKey (teclas activas) Editor de texto enriquecido (RTF) Todos ellos se encuentran en la paleta de herramientas (paleta de elementos); bajo la pestaa que lleva por nombre Win95.

Cabeceras de control
Son identificadores que suelen encontrarse en la parte superior de la ventana (la alineacin por defecto, respecto de la ventana , es de AlTop) y que responden a la pulsacin efectuada sobre ellos. En realidad, yo las concibo como un invento cmodo de agrupar los PushButton y darles un aspecto diferente al que estamos acostumbrados, pues se trata de controles que no llegan a la organizacin que nos puede dar las estructuras en forma de lista, ni la funcionalidad de las carpetas (pestaas). En cualquier caso, se gestionan, como ya he dicho, con la misma lgica que los PushButton, de ah que no vaya a hacer mucho hincapi en su manipulacin, limitndome a contar las diferencias que existen entre uno y otro. En la figura 1 se muestra el control comentado, que pertenece a la clase THeaderControl, y ms abajo se enumeran sus propiedades y sus eventos ms resultones.

Figura 1: Ejemplo de Cabecera de Control

Para la definicin de las distintas secciones se utiliza la ventana destinada a tal fin, y que se puede ver en la figura 2.
1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 2: Definicin de las secciones de un THeaderControl

Como se puede advertir se dispone de dos posibles operaciones, la de aadir nuevas secciones (New) y la de eliminar alguna de las existentes (Delete). De acuerdo a aquella que se tenga seleccionada, en la parte de la derecha de la ventana podremos modificar distintos elementos (los cuales se corresponden con sendas propiedades de la clase THeaderControl), a saber: - Text - Width Literal que aparecer en la seccin creada. Puede modificarse en tiempo de ejecucin. Anchura en pxels de la seccin. Este ancho, si no se especifica explcitamente, se puede cambiar en tiempo de ejecucin, bien por accin del usuario, bien a travs de programacin. Valor mnimo que la columna puede alcanzar. Esto limita la decisin de usuario de hacer tan pequea como quiera la seccin que se decida a redimensionar, de ah que el valor por defecto sea 0, lo cual permite reducir a la mnima expresin el tamao del rectngulo. Si no se quiere que el usuario sobrepase unos lmites mnimos ser aqu donde indicar esta frontera. Valor mximo que la columna puede alcanzar. Si no se quiere que el usuario sobrepase unos lmites mximo ser aqu donde indicar esta frontera. Tipo de alineacin del texto en la celda, segn los valores de la tabla 1. Valor Descripcin taLeftJustify Alineacin a la izquierda taCenter centrado taRightJustify Alineacin a la derecha Tabla 1: Tipo de justificaciones disponibles. - Style Tipo de contenido que va a tener la cabecera de control. Puede ser un texto sin ms (entonces se fija el valor de Style a hsText, que es el valor por defecto), o puede contener cabeceras de control anidadas (en cuyo caso habra que fijar el valor a hsOwnerDraw). Permite o no que las distintas secciones de la cabecera de control respondan, o no, cuando se hace clic sobre ellas.

- MinWidth

- MaxWidth - Alignment

- AllowClick

Como ocurriera con los PushButton, se puede especificar qu procedimiento invocar cuando se produzca el evento OnClick. En el fuente 1 de ms abajo se implementa una sencilla lnea de cdigo cuyo nico cometido es hacer aparecer una ventana informando del hecho de que una de las secciones ha sido pulsada.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

// --- Fuente 1 --------------------------------------------------------procedure TDlgFiesta.HacerClicEnSeccion( HeaderControl: THeaderControl; Section: THeaderSection ); begin MessageDlg( 'Estoy aqu, en ' + Section.Text, mtConfirmation, mbYesNoCancel , 0); end;

Lo nico a resaltar, por resaltar algo, es que se accede a la propiedad Text de la variable Section, que es pasada automticamente al procedimiento cuando se realiza un clic en alguna de las secciones. Al ser Section una variable de la clase THeaderSection, podemos consultar o modificar cualquiera de sus datos accesibles, y Text es el que interesa, para conocer el literal sobre el cual se pinch.

Barra de estado
Las habituales barras de control de Windows fueron sustituidas por las ms completas de Windows 95, en las que, adems de disponer de un control ms especfico del redimensionamiento de la ventana, lo cual es accesorio, se dispone de un lugar en el que poder informar de la cuestin que se desee. La asociacin de esta zona a la ventana hace que cualquier suceso se pueda ver all reflejado, independientemente del tipo de ventana que se est manipulando y sin necesidad de mostrar una ventana adicional. En la figura 3 se ofrece un aspecto tan completo como poco esttico de lo que se puede mostrar en una barra de estado con formato Windows 95.

Figura 3: Tipos de Barras de estado

Si en las cabeceras de control el tipo de alineacin por defecto era en la parte superior de la ventana, en las barras de estado es en el lado opuesto, es decir, la variable encargada de la alineacin respecto a la ventana toma un valor de AlBottom.
3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Tipo de barra sencilla


Son las ms habituales, pues dan una informacin genrica no agrupable. Para especificarla hay que jugar con dos datos: SimplePanel, que deber tener un valor verdadero, y SimpleText, donde se indicar el literal a mostrar (accesible, lgicamente, en tiempo de ejecucin). Esto hace que obtengamos la barra de estado de la figura 3 que lleva por leyenda "Texto sencillo".

Tipo de barra compuesta


Son menos habituales pero ms completas y organizadas, pues dan informacin especfica que, adems, podemos agrupar por el criterio que nos parezca ms intuitivo. Para especificarla hay que jugar con SimplePanel, que deber tener un valor falso, y Panels, donde se indicarn el/los distintos bloques de informacin (aparte de la informacin contenida en ellos). En la figura 3 se distingue la existencia de tres secciones, cada una de ellas alineada respecto al habitculo que la contiene, con un tamao predeterminado y mostrando un aspecto realzado, hundido o plano segn criterios seguidos en la fase de diseo. Este diseo se realiza en una ventana casi idntica a la que se ha mostrado en la figura 2, en la que el nico elemento novedoso sera es aspecto realzado, etc. al que haca referencia. Este dato se encuentra tipificado en la Variable Bevel, y los valores posibles se dan en la tabla 2.

Valor Descripcin pbNone Sin realzado, aspecto plano pbLowered Hundido pbRaised Realzado, sobresaliendo Tabla 2: Tipo de realzados disponibles. Otros datos de inters son las propiedades SizeGrip (para mostrar o no el tringulo de la esquina inferior derecha donde se redimensiona la ventana) y Hints (para poner etiquetas explicativas de lo que la barra de estado hace). Esta ltima propiedad ya haba sido comentada en entregas anteriores, y ya se explic que siempre iba asociada a la propiedad ShowHints que permite o no mostrar dichas etiquetas, pero aqu, como estamos tratando un control ntimamente ligado a la ventana, la propiedad ShowHints que hay que manipular es la de la ventana, no la del control (pues ste no la posee)

Spinner
Los spinner son contadores que, normalmente, van asociados a controles de edicin de tipo numrico, en los que al pinchar la flecha arriba el valor se incrementa, decrementndose al pinchar la flecha abajo (o las teclas de navegacin). Digo que, normalmente, los spinner van asociados a controles de edicin de tipo numrico, pero en realidad se pueden asociar a cualquier control existente en la ventana. Las propiedades de la clase TUpDown, a la cual pertenece este control, son: - Associate Control con el que se va a asociar el spinner. Se trata de un ComboBox en el que aparece la relacin de todos los controles. Nosotros podemos asignarlo en tiempo de ejecucin, pero cuidado con equivocarse al hacerlo, pues provoca un error de excepcin insalvable. Posicin relativa respecto al control al que el spinner est asociado. Los valores permitidos son a la derecha ( udRight) o a la izquierda (udLeft).

- AlignButton

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

- ArrowKey

- Max/Min - Wrap

Permitir el uso de la flecha arriba y flecha abajo para simular la pulsacin del ratn sobre el spinner (ser efectivo cuando el control de edicin tenga el foco) o para usarlas como teclas de navegacin por el control de edicin. El valor por defecto es true. Valores mximos y mnimos alcazables. Hace que la lista sea circular, es decir, que si se est pulsando la flecha arriba y se intenta sobrepasar el tope mximo fijado, cuando Wrap est a false permanecer en dicho mximo, pero cuando est a true seguir aumentando desde el mnimo fijado hacia arriba. Una lgica similar hay que aplicar cuando lo que se est haciendo es pulsar la flecha abajo en vez de la flecha arriba. Es el lugar donde se almacena el valor actual del control de edicin. Es accesible y modificable.

- Position

Teclas activas
Este control es autoexplicativo, pues se trata de la posibilidad que tenemos de activar, o mejor dicho, asociar a una pulsacin de tecla una cierta operativa. Cuando se define, delimita y asigna un determinado comportamiento a este tipo de controles, se dispone, de una forma abreviada, de realizar una operacin ms o menos repetitiva mediante un teclazo.

Propiedades
- AutoSize Permite que el tamao del control se adapte al contenido, el cual ser la tecla asociada a dicho control, por ejemplo Alt-F12. No es lo mismo ubicar F12 en el control que Ctrl-Alt-W. Tipo de enmarcado que llevar el control. Puede llevar un marco sencillo (valor bsSimple) o no llevar ninguno (bsNone), son las dos nicas alternativas. Tecla que se asociar al control. Si pinchamos sobre el ComboBox asociado a esta propiedad en el inspector de objetos, aparecer la relacin de las teclas que se permite utilizar. Relacin de las teclas no permitidas. La relacin de teclas vlidas se ve filtrada por los modificadores que elijamos en esta propiedad, los cuales se encuentran representados en la tabla 3. Valor hcNone hcShift hcCtrl hcAlt hcShiftCtrl hcShiftAlt hcCtrlAlt hcShiftCtrlAlt Descripcin Todas las combinaciones de teclas son vlidas. La tecla Shift no est permitida en la definicin de la tecla. La tecla Ctrl no est permitida en la definicin de la tecla. La tecla Alt no est permitida en la definicin de la tecla. La combinacin de teclas Shift+Ctrl no est permitida en la definicin de la tecla. La combinacin de teclas Shift+Alt no est permitida en la definicin de la tecla. La combinacin de teclas Ctrl+Alt no est permitida en la definicin de la tecla. La combinacin de teclas Shift+Ctrl+Alt no est permitida en la definicin de la tecla.

- BorderStyle - HotKey

- InvalidKeys

En el fuente 2 se ha programado un procedimiento que provoque el cierre de la ventana y que regrese a la principal.

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

// --- Fuente 2 --------------------------------------------------------procedure TDlgFiesta.QueHago(Sender: TObject); begin Close; end;

Bueno, aqu termino con este complicadsimo cdigo, dejando el comentario de los controles de edicin para formatos RTF (Rich Text Format -Texto enriquecido como lo traducen en Windows 95) para que el lector lo compare con el de controles de edicin multilnea, pues son idnticos en su estructura (heredan de una clase comn), aunque el contenido del primero es, si se me permite, mucho ms rico que el del segundo. Un saludo.

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Delphi paso a paso (y XIII) El depurador


Por Vladimir Algara
En esta entrega, que lleva como nmero de orden el (y XIV), se pretende finalizar con esta serie de artculos que han llevado por nombre Delphi paso a paso. No quiero decir con esto que nunca ms vuelva a tratar el tema de Delphi, ni mucho menos, pero s que lo tratar de manera menos sistemtica y, sobre todo, no concibindolo como un curso en el que se van quemando etapas y en el que se va aprendiendo, pautadamente, las caractersticas de un lenguaje. Cada vez que, puntualmente, me surja un tema interesante que pueda serlo asimismo para el lector de mis ideas, lo expondr en este medio, pues son muchos los temas que an quedan por tratar. Uno de los temas no abordados en esta serie, y que en su concepcin resultaba inimaginable no hacerlo as, es la gestin de bases de datos; entendindolos en su manera de explotarlos en fondo y forma. Gracias a que existen otros articulistas que han compartido conmigo las bondades de Delphi, creo que el acercamiento que yo hubiera hecho a tales temas ha quedado ms que resuelto con sus respectivos razonamientos, lo cual me ha llevado a hacer este razonamiento, ajeno a lo que ser el contenido de las lneas que nos ocupan, y llegar a la conclusin de que es mucho mejor abandonar la forma reglada de explicar Delphi y tomar como regla la explicacin espordica de los casos interesantes. En resumen, que el y XIV del ttulo significa que el curso lo doy por concluido en su concepto, pero no que vaya a abandonar el lenguaje Delphi por otro mejor postor, slo voy a deshacer mi monogamia informtica arrastrada en los ltimos meses. Bueno, despus de toda esta retahla de nosequ, voy a entrar en el meollo del artculo, que no es otro que el uso y abuso del depurador de Delphi para correccin y seguimiento de errores en las aplicaciones diseadas en el lenguaje de Borland.

Tipos de errores
Todo el mundo sabe a qu tipos de errores nos enfrentamos a la hora de disear una aplicacin con cualquier herramienta, los peores de todos suelen encontrarse en la eleccin del analista que ha de perfilar el coherente funcionamiento del programa. Bromas aparte, los errores se clasifican histricamente en: Errores de compilacin: Delphi posee un potente compilador/enlazador que, una vez entendida su idiosincrasia, permite fijar con total exactitud el/los puntos conflictivos del cdigo errneo. Estos errores consisten, esencialmente, en fallos sintcticos, del tipo falta punto y coma, inconsistencia entre tipos de variables, sentencias mal construidas, estructuras de control inacabadas, etc., etc., etc. Errores de enlazado. Superada la fase de compilacin llega la de enlazado, en la que se especifica que elementos, ajenos a nuestro cdigo compilable, se van a usar para el correcto funcionamiento de la aplicacin. Es la parte en la que se han de resear los mdulos OBJ, libreras y DLLs, y la ausencia de alguna de ellas provocar la queja de Delphi. Errores de ejecucin. Los hay, a su vez, de dos tipos, y la forma de clasificarlos se limita a la dificultad de corregirlos. Los ms evidentes son los denominados errores Run-Time, los cuales originan una ruptura del buen funcionamiento de la aplicacin y una salida de la misma. Dado lo acotado del error su localizacin es fcil, aunque su correccin puede no serlo tanto (consisten en especificaciones de archivos que no existen y que se quieren utilizar, divisiones por cero, la obtencin de la raz cuadrada de un nmero negativo, etc.);

1
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

los menos evidentes son los llamados errores lgicos y consisten en un funcionamiento anmalo que, en el peor de los casos, pueden dar con nuestros huesos en el Psiquitrico asignado a nuestra rea Sanitaria. En lo que a mi experiencia personal se refiere, el error lgico que ms tiempo me ha llevado descubrir fue uno en el que se juntaron varios factores: 1.- No utilizaba la notacin Word Mixing en la declaracin de mis variables. 2.- El programa estaba hecho en un Pascal arcaico sobre una mquina arcaica (no dispona de depurador) 3.- No tena la experiencia suficiente para enfrentarme a lo que deba resolver (vamos, que no tena ni idea) El resultado de estas tres variables derivaron en que el programa se tir sin funcionar ms de una semana, todo por culpa de una lnea en la que se utilizaba un contador de manera inadecuada:

I := 1 + 1

En la que realmente debera haber puesto, como todo el mundo alcanza a comprender:

I := I + 1

Este error siempre lo ocult y aqu y ahora me sincero con todos. En fin, experiencias personales aparte, cualquiera de los dos tipos de errores que se pueden dar en tiempo de ejecucin los vamos a resolver (o lo intentaremos) por medio del depurador de Delphi.

Ventajas y desventajas
Antes de pasar a explicar cmo manejar el depurador, debo hacer la advertencia que siempre se hace cuando se habla de este tipo de utilitarios, y que gira en torno a los recursos que estos utilitarios consumen. No es lo mismo entregar un ejecutable final con la informacin necesaria para ser depurado que sin ella. En tiempo de desarrollo podemos permitirnos el lujo de introducir dicha informacin dentro de nuestros ejecutables, pero una vez acabados y depurados habremos de eliminarla. Por una parte impediremos que el ejecutable sea inspeccionado por ojos espas, y, por otra, reduciremos su tamao final (hay que tener presente que Delphi aade la informacin necesaria en el archivo .DCU asociado a la aplicacin, y que la vuelve a eliminar cuando no se desea usar el debugger) y aumentaremos la velocidad de los procesos. Estableciendo que vamos a depurar el programa, sepamos de qu ventajas inmediatas vamos a disponer: 1. La primera, y principal, la de poder recorrer e inspeccionar el cdigo que se est ejecutando en el momento que el programa responde a nuestras especificaciones o a estmulos exteriores.

2.- Cambiar el contenido de las variables que influyen en la forma de trabajar de un determinado proceso.

2
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

3.- Provocar la parada del programa a tenor del contenido de una o ms variables de referencia. O de la conjuncin de todas ellas. 4.- Alterar el valor asociado a los campos de las bases de datos

Configuracin del depurador


El depurador se configura genricamente en el men Tools, en el tem Options... Desde l accedemos a la ventana de configuracin general Environment Options en la que, entre otras, se encuentra la pestaa Preferences. Dado que existen distintos aspectos que podemos tocar en lo que a preferencias del entorno se refiere, dentro de la pestaa Preferences existen otras subdivisiones correspondientes a sendas facetas configurables. La que a nosotros nos interesa se encuentra en el GroupBox reservado al Debugging que se ve en la figura 1.

Figura 1: Ventana para la configuracin del depurador

Los valores que se pueden fijar en este cuadro de grupo son, como se ve en la figura de ms arriba, los siguientes: 1.- Integrated Debugging: Es la piedra angular de todo este berenjenal. Cuando est marcado (valor por defecto) se dispone de depurador para las aplicaciones, si no, no. 2.- Step program block: Ejecuta el programa usando el depurador desde el principio de la aplicacin, o a partir del mdulo que contenga la informacin necesaria como para ser reconocido como bloque de comienzo (un punto de ruptura, por ejemplo). Estos dos puntos estn ntimamente ligados al depurador, los otros tres ya no tanto, pero como se engloban dentro del mismo GroupBox los explicar.

3
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

3.- Hide designer on run: Hace que el inspector de objetos y el lugar donde se disean las distintas ventanas desaparezcan, a la hora de ejecutar una aplicacin. 4.- Break on exception: Habilita o no la salida de la aplicacin cuando se produce un error de tipo Run-Time. El valor por defecto de este Check es marcado, lo cual significa que cuando ocurra un error aparecer la ventana de la figura 2 y la aplicacin acabar. Si no est marcado aparecer una caja diferente a la anterior (la de la figura 3), que tambin nos informa de que ha sucedido un error, pero permite que el programa siga funcionando. Por ejemplo, en la porcin de cdigo de ms abajo, se fuerza la aparicin de un error. Se pretende leer el contenido de un archivo que no existe, lo cual provoca un error de excepcin que, en un caso nos echa y en otro no.

nCapitulo := TabCapitulos.TabIndex; case nCapitulo of 0 : Memo1.Lines.LoadFromFile('KK.TXT'); archivo 1 : Memo1.Lines.LoadFromFile('CAP2.TXT'); 2 : Memo1.Lines.LoadFromFile('CAP3.TXT'); 3 : Memo1.Lines.LoadFromFile('CAP4.TXT'); end;

// Error, no existe el

Figura 2: Ventana informativa y el programa deja de ejecutarse

Figura 3: Ventana informativa y el programa contina su normal ejecucin

Cuando no marcamos la opcin de disponer de depurador (punto 1.-), nunca aparecer la ventana de la figura 2, siempre saldr la de la 3. 5.- Minimize on run: Hace que Delphi se minimice al ejecutar la aplicacin.

Puesta en marcha
Para hacer funcionar el depurador ha de hacerse desde dentro de Delphi. Una vez funcionando podemos acceder a la parte del cdigo que se quiere inspeccionar y all poner una marca que

4
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

indique a la utilidad que debe parar la ejecucin del programa. Estos puntos son los llamados BreakPoints (Puntos de ruptura) y son la forma ms habitual de trabajar con el depurador. De cualquier forma, esta no es la nica manera que tenemos de comunicarnos con el depurador, existen otras y todas ellas se engloban en el men Run, del cual se ha hecho un extracto en la figura 4.

Figura 4: Operaciones con el depurador 1.- Run: Ejecuta la aplicacin sin pausa, hasta que encuentra un Punto de Ruptura o se pulsa la combinacin de teclas (varias veces) [Ctrl] + [Alt] +[Pet Sis]. 2.- Parameters: Permite pasar parmetros a la aplicacin. 3.- Step Over: Ejecuta una lnea de la aplicacin. Si la lnea consiste en una llamada a una funcin o a un procedimiento, sta se realiza de una sola vez, sin entrar en el cdigo que haya en su interior. 4.- Trace Into: Ejecuta, como el anterior, una lnea de la aplicacin, pero, en este caso, si la lnea es una llamada a funcin o a procedimiento, se recorre el cdigo contenido en ellos. 5.- Run to Cursor: Dado que una vez que se ejecuta un programa se puede uno mover libremente por el cdigo que lo gua, podemos acceder a una lnea sospechosa de contener error y elegir esta opcin, lo cual har que la aplicacin se desarrolle libremente, sin trabas, hasta el momento que se alcance la lnea escogida. 6.- Show Execution Point: Muestra la lnea de programa por la que se va. Esto puede ser til si nos hemos movido por otras porciones de cdigo fuente o hemos minimizado la ventana que contiene el cdigo ejecutable. 7.- Program Pause. Detiene, momentneamente, la ejecucin de la aplicacin. 8.- Program Reset. Vuelve a ejecutar, desde el principio, la aplicacin en curso.

Puntos de Ruptura
Los Puntos de Ruptura son las herramientas ms usadas en la interaccin con el depurador. En Delphi hay varias formas de especificar uno de estos Puntos de Ruptura.

5
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

La forma de hacerlo es ir a una lnea "sospechosa" de contener error y convertirla en un Punto de Ruptura. Esta operativa se puede realizar cuantas veces se desee. El resultado final puede ser algo similar a lo que se ve en la figura 5, en la que existen tres puntos de ruptura, uno de ellos inhabilitado (color verde) y dos no (color rojo, azul para el daltnico de Alfonso).

Figura 5: Puntos de Ruptura en el cdigo de ejemplo

Para poner un Punto de Ruptura (o quitarlo) basta con realizar alguna de las acciones siguientes sobre la lnea elegida. Pinchar con el botn principal del ratn en la parte izquierda del editor de cdigo. Pulsar la tecla [F5]. Pinchar con el botn auxiliar del ratn para que aparezca el men local y elegir la opcin Toggle BreakPoint. Acceder, por medio del men de Run, al tem Add BreakPoint; lo cual har que aparezca la ventana de la figura 6. All, como se puede ver, se le indica la unidad donde est la lnea a aadir (por defecto en el que nos encontramos), el nmero de lnea de programa (por defecto en la que nos encontramos), una condicin y un nmero de ejecuciones.

6
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 6: Puntos de Ruptura desde la ventana de configuracin Al especificar algo en Condition, el Punto de Ruptura slo ser vlido cuando ese "algo" devuelva un valor verdadero; por ejemplo, se podra poner:

nCapitulo >= 2

Para que slo entrara cuando se pinche sobre las pestaas 3 y 4. Al especificar un nmero en Pass Count, el Punto de Ruptura slo ser vlido cuando la lnea que lo tiene haya sido leda ese nmero de veces.; por ejemplo, se podra poner un 3, lo cual permitira pasar dos veces por la lnea definida sin que el Punto de Ruptura saltase. A la ventana de la figura 6 se puede llegar desde la ventana de la figura 7, en la que se muestran todos los Puntos de Ruptura definidos hasta el momento. Esta ventana, aparte de ofrecernos una relacin detallada de ellos, nos permite modificar el contenido de todos o parte de ellos (haciendo doble clic sobre alguno o pinchando con el botn auxiliar del ratn) y variarlo de acuerdo a nuestros propsitos. A la ventana de la figura 7 se llega por medio del men de View, a travs del tem BreakPoints.

Figura 7: Relacin de los Puntos de Ruptura

Puntos de Observacin
Los Puntos de Observacin son otras de las herramientas ms usadas en la consulta de los datos con el depurador. Al contrario que los Punto de Ruptura, stos no detienen la normal ejecucin del programa, sino que slo muestran el contenido de una variable, un conjunto de ellas o una expresin compleja. Para poner un Punto de Observacin (o quitarlo) basta con acceder, por medio del men de Run, al tem Add Watch...; lo cual har que aparezca la ventana de la figura 8. All, como se puede ver, se le indica la expresin que se desea ver, un nmero de ejecuciones a partir de la cual queremos que se haga efectiva la visualizacin, el nmero de dgitos que se van a usar en dicha visualizacin y si se puede ver o no (el valor por defecto de Enabled es estar marcado, o sea, que se pueda ver, pero en algn punto del programa nos puede interesar eliminar alguno de los Puntos de Observacin definidos). Los distintos RadioButtons son autoexplicativos.

7
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS

Figura 8: Puntos de Ruptura desde la ventana de configuracin

Identif. ,C

Tipo afectado Caracteres

Descripcin Muestra los caracteres correspondientes a los ASCCI comprendidos entre el 0 y el 31. De no especificarlo, dichos caracteres se interpretan como secuencia de escape del tipo \n, \t, etc. Muestra los caracteres ASCCI comprendidos entre el 0 y el 31 como secuencia de escape. Muestra los valores enteros en formato decimal, incluidos los campos de las bases de datos tratadas. Muestra los valores enteros en formato hexadecimal, aadiendo el prefijo 0x, incluidos los campos de las bases de datos tratadas. Muestra informacin de la direccin ocupada por los punteros (segmento:offset). Esto permite identificar, de manera indirecta, por ejemplo, qu variable est causando un determinado problema. Ofrece informacin especfica de los distintos valores almacenados en las variables de una clase, para una instaciacin concreta de un objeto concreto. Visualiza n bytes de memoria, comenzando en la direccin de la expresin reseada. Una especificacin del tipo 5M, mostrar informacin de los cinco primeros bytes de la variable en cuestin.

,S ,D ,H o ,X ,P

Caracteres Enteros Enteros Punteros

,R

Registros, clases, objetos Cualquiera

,nM

Tabla 1: Modificadores de formato.

Bueno, aqu me despido de la serie y de todo aquel que me quiera or. En esta entrega no se acompaa con ningn tipo de ejemplo, pues provocar errores en un programa es la cosa ms sencilla del mundo, lo que es ms complicado es quitrselos de encima. Lo dicho, se cierra la serie, pero no la investigacin en Delphi.

8
Algoritmo. La revista para el programador de sistemas de bases de datos. http://www.eidos.es - Grupo EIDOS