Componentes en C++ Builder

Transcripción

Componentes en C++ Builder
Técnicas de Programación
3.2.- Programación C++ con Builder C++
Tema 3.2.2.- Componentes en C++ Builder
Introducción
Los compiladores C++Builder nos ofrecen definidos una serie de componentes en la paleta de
componentes. Los componentes se agrupan en esta paleta en una serie de pestañas o páginas según
la funcionalidad de los mismos. Existen tres formas posibles de insertar cualquier componente en un
formulario, que son:
• Hacemos clic sobre el componentes y posteriormente en el formulario.
• Hacemos un doble click sobre el componente.
• Hacemos un click sobre el componente y, manteniendo pulsado el botón izquierdo del ratón,
arrastramos sobre el formulario hasta dar el tamaño deseado al componente.
Mediante el inspector de objetos accedemos a las propiedades y eventos asociados a los
componentes. Estos componentes son elementos genéricos con una funcionalidad muy concreta, cuya
finalidad es la reutilización. Cada uno de ellos está destinado a realizar una tarea típica en una
aplicación. Los componentes se organizan en la denominada VCL (Visual Component Library) que es
una jerarquía de clases escritas en Object Pascal y que se asocia al IDE de C++Buider.
Un componente de la VCL es una clase que caracteriza a un control de Windows agregando
propiedades, métodos y gestores de eventos a cada control.
En este tema vamos a analizar las propiedades, métodos y eventos de los componentes más
importante y usuales.
Tema 3.2.2.- Componentes en C++ Builder
1
La VCL (Visual Components Library) o biblioteca de componentes visuales
En Windows, no son las aplicaciones quienes manejan los recursos del sistema como pueden ser la
memoria, los ficheros, las ventanas y hasta los controles gráficos. Es el sistema operativo quién realiza
todas estas tareas. Y la aplicación se limita a realizar peticiones de lo que necesita. Estas peticiones se
realizan mediante lo que se denomina la API de Windows.
Por todo esto los entornos de programación visuales han desarrollado diversos Marcos de Trabajo. Un
marco de trabajo es una fase intermedia que se coloca por encima de la API para aportar mayor
sencillez a las aplicaciones. Normalmente estos marcos de trabajo son orientados a objetos y se
implementan como bibliotecas del lenguaje base, por ello también se suelen denominar bibliotecas de
clases. La VCL es un marco de trabajo visual y orientado a objetos.
Tan importantes son los marcos de trabajo, que dominar un
entorno de programación visual, suele traducirse en conocer el
lenguaje base del entorno, y su marco de trabajo.
Los marcos de trabajo se pueden clasificar en dos categorías:
1. Los marcos de trabajo C++ (OWL y MFC)
2. La VCL.
Aplicación
OWL (Object Windows Library o Biblioteca de Objetos para
Windows) fue un marco de trabajo desarrollado por Borland e
incorporado a los compiladores Borland C++ (versiones 3 y
VCL
sucesivas) y supuso un importante hito en la programación
para Windows por su potencia y facilidad de uso.
MFC (Microsoft Foundation Class o Biblioteca Fundamental de
Clases de Microsoft) y lo incorporó a los compiladores
S.O. Windows
Microsoft Visual C++ (actualmente incluso en Borland C++ 6).
MFC es una biblioteca de clases menos abstracta que el OWL y
más cercana a la API. También resulta más sencillo que OWL
para los programadores que conocen la API.
Aunque MFC se usa más que OWL la arquitectura de OWL es,
técnicamente, mejor que MFC.
Tema 3.2.2.- Componentes en C++ Builder
2
La VCL (Visual Components Library) o biblioteca de componentes visuales
En 1995, Borland lanzó al mercado Delphi, que supuso la revolución en la programación para Windows
e inició el desarrollo rápido y sencillo de aplicaciones visuales (RAD), empleando componentes
(objetos que pueden ubicarse en formularios y manipulados por medio de propiedades, métodos y
eventos). Delphi se basa en el lenguaje Object Pascal (una ampliación de Pascal que incorpora
programación orientada a objetos) y permitía la creación de programas ejecutables independientes que
no requerían intérprete, por lo que se ejecutaban mucho más rápido.
Lo más relevante desde el punto de vista técnico es que Borland creó la VCL (Visual Class Library o
Biblioteca de Componentes Visuales) que es un marco de trabajo para crear aplicaciones Windows
diseñada en torno al concepto de componente (propiedades, métodos y eventos). La VCL desarrollada
para Delphi es la misma que se emplea como núcleo de C++ Builder, de hecho, está escrita en Object
Pascal.
TObject
La VCL hace un uso
TPersistent
extensivo del concepto de
herencia. El objetivo final de
TComponent
la VCL es crear clases que
Componentes
representan a componentes,
visibles
aunque algunas clases no
hagan
referencia
a
TControl
componentes
concretos:
realizan tareas de gestión
interna y se emplean como
Ttimer, Ttable, ...
TGraphicControl
TWinControl
clases bases para derivar
mediante
herencia
otras
Componentes
clases.
En
la
figura
mostramos una pequeña
no visibles
TpaintBox ...
Tbutton, Tpanel, ...
parte de la jerarquía de
clases que forman la VCL.
Tema 3.2.2.- Componentes en C++ Builder
3
La VCL (Visual Components Library) o biblioteca de componentes visuales
Es posible construir aplicaciones Windows de gran calidad con C++ Builder sin un conocimiento
exhaustivo de la VCL, aunque es conveniente realizar una somera descripción de la jerarquía de clases
que conforman la VCL.
Las clases que conforman la parte superior (el techo) de la jerarquía de la VCL (Tobject, TPersistent y
TComponent) se denominan clases "abstractas" porque sirven para estructurar, y agrupar
comportamientos comunes de las clases de la VCL. No se suelen crear objetos directamente a partir de
ellas. Rigurosamente hablando, no son clases abstractas, porque no tienen métodos virtuales puros,
pero las podemos considerar como tales en la práctica.
Tobject
Es el ancestro de todas las clases de la VCL. Encapsula el comportamiento común de los objetos en C+
+ Builder, como puede ser información de la clase, instanciación... Suele ser una buena idea derivar
nuestras propias clases de TObject, porque aunque no sea normal que el programador haga uso de los
métodos proporcionados por Tobject, si lo es que lo haga C++ Builder en tiempo de ejecución.
Directamente de TObject heredan aquellas clases que no son componentes, y no necesitan ser
almacenadas en disco.
TPersistent
Esta clase tiene que ver con la habilidad de un objeto de almacenarse en disco o en memoria,
asignarse a otros objetos, así como otros detalles internos de C++ Builder.
TComponent
Ésta es una de las clases más importantes de la VCL, ya que la mayoría de los objetos que se manejan
en una aplicación son componentes. Esta clase proporciona toda la funcionalidad que requiere un
componente básico. La funcionalidad de TComponent permite que los objetos aparezcan en la paleta
de componentes y que sean manipulados por el diseñador de formularios, además de otras
capacidades comunes a los componentes.
Los componentes no visibles derivan directamente de TComponent mientras que los componentes
visibles derivan de TControl, que a su vez deriva de TComponent. Por esta razón se suelen denominar
controles a los componentes visibles.
Tema 3.2.2.- Componentes en C++ Builder
4
La VCL (Visual Components Library) o biblioteca de componentes visuales
TControl
Proporciona la funcionalidad de los componentes visibles (controles). Esta funcionalidad es
principalmente el aspecto visual que deben ofrecer los componentes en tiempo de ejecución. TControl
proporciona mayor funcionalidad que la que requieren los componentes visibles: los componentes
individuales derivan de TGraphicControl o de TWinControl, clases derivadas de Tcontrol.
TGraphicControl
Generaliza a los controles que tienen una representación visual, pero no pueden recibir el foco: el
usuario podrá verlos pero no interactuar con ellos. Suelen ser controles para visualizar texto (no
editable en tiempo de ejecución), gráficos o dibujos. Poseen una propiedad Canvas que permite
acceder a su área de dibujo.
TWinControl
Son los controles típicos de Windows, que pueden recibir el foco, contener otros controles, y además
poseen un manejador de ventana. Un manejador de ventana es un identificador que proporciona
Windows para el control, por lo que podemos decir que Windows tiene un conocimiento directo de la
existencia del mismo. Dicho identificador es un número que Windows incorpora a su base de datos de
controladores y periódicamente comprueba si ha realizado alguna solicitud.
Clases de Formularios y Aplicaciones
Son controles en si mismos, pero no se presentan en la paleta de componentes.
TApplication
La clase TApplication encapsula una aplicación Windows por lo que caracteriza las operaciones
fundamentales de un programa en Windows. TApplication simplifica el interface entre el programador
y el sistema operativo, ocupándose de tareas como gestionar el paso de mensajes, proporcionar la
ayuda contextual, establecer los textos de sugerencia de los botones y barras de estado,
procesamiento de "teclas rápidas", gestión de excepciones, ejecutar cuadros de mensajes, etc.
Todas las aplicaciones de C++ Builder tienen un puntero a un objeto Tapplication denominado
Application, que se crea automáticamente. Cuando un programa empieza a ejecutarse, C++ Builder
invoca a la variable Application, llama a sus métodos Initialize(), CreateForm() y Run().
Tema 3.2.2.- Componentes en C++ Builder
5
Clases de Formularios y Aplicaciones
TApplication
Por ejemplo, si retomamos el ejemplo 3 podemos abrir el fichero Ejemplo3.cpp o bien abrir el proyecto
y seleccionar Proyect/View Source para observar el contenido del fichero que C++ Builder crea como
fichero principal de la aplicación.
{
try
{
Application->Initialize();
Application->Title = "Primera aplicación";
Application->CreateForm(__classid(TFormPrincipal), &FormPrincipal);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
Métodos Initialize(), CreateForm() y Run().
}
Además aparece el método Title por haber
catch (...)
puesto un título a nuestra aplicación
{
try
{
Como Application se crea automáticamente no aparece
throw Exception("");
en la paleta de componentes ni está disponible en el
}
inspector de objetos para manipular "visualmente" sus
catch (Exception &exception)
propiedades.
{
En cualquier caso, algunas propiedades pueden
Application->ShowException(&exception);
}
establecerse en tiempo de diseño seleccionando las
}
páginas Forms o Applicaction en Project/Options.
return 0;
}
Tema 3.2.2.- Componentes en C++ Builder
6
Clases de Formularios y Aplicaciones
Propiedades de TApplication
Propiedad
Descripción
Active
Especifica si la aplicación está activa y tiene el foco.
Hint
Hint especifica el texto que debe aparecer en el cuadro de ayuda o texto de sugerencia asociado
a la aplicación. Este cuadro aparece cuando ocurre el evento OnHint. Por defecto se muestra
únicamente el cuadro asociado al componente sobre el que está el ratón por lo que usualmente
se emplea esta propiedad para mostrar la información extensa de este componente en una barra
de estado, por ejemplo.
ShowHint
ShowHint determina si los cuadros de sugerencia estarán activados o desactivados para toda la
aplicación.
Pueden emplearse las funciones GetShortHint() y GetLongHint() para obtener las dos partes de
la propiedad Hint.
MainForm
MainForm especifica qué formulario actúa como ventana principal de la aplicación.
ShowMainForm
ShowMainForm especifica si la aplicación debe mostrar la ventana principal al iniciar su
ejecución. Para ocultarla, establecer esta propiedad a false antes de la llamada a Application>Run y asegurarse de que la propiedad Visible del formulario esté también a false.
Icon y Title
Especifican el icono y el texto, respectivamente, que aparecen en la barra de tareas de Windows
cuando se minimiza la aplicación. Pueden establecerse en tiempo de diseño seleccionando
Project/Options/Application.
HelpFile y
CurrentHelpFile
Para especificar el fichero de ayuda asociado a la aplicación.
Ejemplo 93.- Propiedades de TApplication
Vamos a realizar paso a paso una aplicación visual que muestra el uso de la propiedad
Application.
Tema 3.2.2.- Componentes en C++ Builder
7
Clases de Formularios y Aplicaciones
Propiedades de TApplication
Creamos una aplicación y archivamos el trabajo, no es necesario cambiar el nombre a ningún archivos.
Declaramos el método DisplayHint como un procedimiento público del Formulario
Escribimos en el Unit, debajo de lo creado automáticamente, el método DisplayHint y lo asignamos a
Application para que lo maneje el evento OnCreate del Form.
void __fastcall TForm1::DisplayHint(TObject *Sender)
{
StatusBar1->SimpleText = GetLongHint(Application->Hint);
}
Situamos sobre el formulario un componente OpenPictureDialog de la pestaña Dialog y un botón al que
modificamos su propiedad Caption a Seleccionar un Icono.
Tema 3.2.2.- Componentes en C++ Builder
8
Clases de Formularios y Aplicaciones
Propiedades de TApplication
Situamos sobre el formulario un componente StatusBar de la pestaña Win32 y hacemos doble clic
sobre el formulario para crear el gestor de evento y teclear las líneas siguientes.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Form1->Hint="Mostrar la propiedad Hint";
Application->OnHint = DisplayHint;
Application->Title="Uso de Application";
}
Hacemos doble clic sobre el botón para crear el gestor de evento y teclear las líneas siguientes.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
OpenPictureDialog1->DefaultExt = GraphicExtension(__classid(TIcon));
OpenPictureDialog1->FileName = GraphicFileMask(__classid(TIcon));
OpenPictureDialog1->Filter = GraphicFilter(__classid(TIcon));
OpenPictureDialog1->Options.Clear();
OpenPictureDialog1->Options << ofFileMustExist << ofHideReadOnly << ofNoChangeDir;
while (true) { if (OpenPictureDialog1->Execute())
{ if (!OpenPictureDialog1->Options.Contains(ofExtensionDifferent))
{ Application->Icon->LoadFromFile(OpenPictureDialog1->FileName); break; }
else
{
OpenPictureDialog1->Options.Clear();
OpenPictureDialog1->Options << ofFileMustExist << ofHideReadOnly << ofNoChangeDir;
}
}
else break; }
}
Tema 3.2.2.- Componentes en C++ Builder
9
Clases de Formularios y Aplicaciones
Propiedades de TApplication
Ejecutando el programa y seleccionando un icono al pulsar el
botón
obtenemos
el
siguiente
resultado.
Observar
minimizando la aplicación como aparece el título de la misma.
El ejemplo lo hemos realizado a efectos de demostración de
Application, ya que mostrar una pista en la barra de estado se
puede hacer con su propiedad Autohint sin necesidad de
escribir el evento OnHint.
Métodos de TApplication
Método
Descripción
BringToFront()
Establece la última ventana activa como la que se muestra por encima de todas las demás.
CreateForm()
Crea un nuevo formulario. Generalmente, el programador no usa este método ya que las líneas de
código para la creación de formularios las añade automáticamente C++ Builder.
HelpCommand()
HelpContext()
HelpJump()
Se emplean para gestionar la ayuda asociada a una aplicación. Generan un evento OnHelp, y si no
hay un gestor para este evento, se gestiona a través de WinHelp.
MessageBox()
Muestra un mensaje al usuario en cuadro de diálogo que puede incorporar botones. Devuelve un
valor que depende del botón seleccionado para cerrar el cuadro de diálogo.
Minimize()
Minimiza una aplicación y la aloja en la barra de tareas de Windows.
Restore()
Reestablece el tamaño que tenía la aplicación antes de ser minimizada.
Run()
Ejecuta la aplicación.
Terminate()
Finaliza laejecución de una aplicación.
ShowException()
Muestra un cuadro de diálogo cuando se produce una excepción que no es gestionada por la
aplicación. Para especificar qué excepciones pueden gestionarse en la aplicación, debemos
construir un gestor para el evento OnException.
HandleException() Proporciona una manera de gestionar excepciones por defecto en la aplicación.
Tema 3.2.2.- Componentes en C++ Builder
10
Clases de Formularios y Aplicaciones
Eventos de TApplication
Evento
Descripción
OnActivate
OnDeactivate
Ocurren respectivamente cuando se activa o desactiva la aplicación.
Una aplicación se activa cuando se genera la aplicación (empieza a ejecutarse) o cuando
estaba activa otra aplicación y una ventana de la aplicación a la que se refiere recibe el foco.
Una aplicación se desactiva cuando el usuario selecciona otra aplicación.
OnHint
OnHint ocurre cuando el cursor se coloca sobre un control o una opción de un menú que
puede mostrar un cuadro de sugerencia.
Se suele escribir un gestor para este evento cuando se quiere mostrar un texto largo de
sugerencia en una barra de estado.
OnShowHint
OnShowHint ocurre cuando la aplicación va a mostar un cuadro de sugerencia. Se suele
usar para modificar la apariencia del cuadro.
Pueden emplearse las funciones GetShortHint() y GetLongHint() para obtener las dos partes
de la propiedad Hint
OnMinimize
OnRestore
Ocurren cuando la aplicación se minimiza o se reestablece al tamaño normal,
respectivamente.
OnHelp
Ocurre cuando la aplicación recibe una petición de ayuda. Los métodos HelpContext() y
HelpJump() gestionan de forma automática este evento.
OnException
Se emplea cuando se desea modificar el comportamiento por defecto de una aplicación
cuando se manifiesta alguna excepción que no es tratada por el programa.
OnShortCut
Se emplea este gestor para realizar acciones antes de que el formulario o los controles del
formulario gestionen los eventos oportunos a la pulsación de teclas.
Cuando se pulsa una tecla se desencadenan los siguientes eventos, por este orden:
OnKeyDown, OnKeyPress, y OnKeyUp.
Tema 3.2.2.- Componentes en C++ Builder
11
Clases de Formularios y Aplicaciones
Métodos y eventos de TApplication
Ejemplo 94.- Métodos y eventos de TApplication
Muestra de un programa totalmente comentado para ver algunos métodos y eventos de
Tapplication. Situando en un Form un componente Timer y dos botones para tener algo similar a:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
/* Hacemos doble clic sobre el botón al que hemos puesto en Caption Mostrar Mensaje. Las siguientes líneas
harán que la ventana con el mensaje se muestre en primer plano y una vez cerrada esta que el formulario desde el
que la hemos llamado se restaure en primer plano. */
Application->NormalizeTopMosts();
Application->MessageBox("Esto se muestra en primer plano", "Observese", MB_OK);
Application->RestoreTopMosts();
}
//--------------------------------------------------------------------------void __fastcall TForm1::AppDeactivate(TObject *Sender)
{
/* El código siguiente minimiza la aplicación cuando esta se desactiva. Debemos declarar el método como público
en el header con lo siguiente: void __fastcall AppDeactivate(TObject *Sender); */
Application->Minimize();
}
//--------------------------------------------------------------------------/* Las siguientes líneas van a provocar el siguiente efecto: cuando minimizamos la aplicación el Timer comienza a
contar y tras el tiempo especificado la ventana vuelve a su estado anterior debido al evento OnTimer. El
temporizador no estará activo hasta la próxima vez que minimicemos la ventana. */
Tema 3.2.2.- Componentes en C++ Builder
12
Clases de Formularios y Aplicaciones
Métodos y eventos de TApplication
// Creamos el evento
void __fastcall TForm1::IniciarTimer(TObject *Sender)
{
/* Implementamos el método IniciarTimer sin olvidarnos de declararlo como público con:
void __fastcall IniciarTimer(TObject *Sender); */
Timer1->Enabled = true;
}
// Creamos el evento
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Application->OnDeactivate = AppDeactivate;
Application->OnMinimize = IniciarTimer;
Timer1->Interval = 1000;
}
// Creamos el evento
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Application->Restore();
Timer1->Enabled = false;
}
// Creamos el evento
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Application->Terminate();
}
//--------------------------------------------------------------------------Tema 3.2.2.- Componentes en C++ Builder
13
Clases de Formularios y Aplicaciones
Tform
La clase TForm caracteriza a los formularios en la VCL. Los formularios se emplean como ventanas
principales, cuadros de diálogo, ventanas secundarias o cualquier otro tipo de ventana que se pueda
imaginar. A continuación veremos las propiedades, métodos y eventos principales de los formularios
de forma resumida.
Propiedades de los formularios en tiempo de diseño y ejecución
Propiedad
Descripción
ActiveControl
Establece qué componente tiene el foco cuando se abre el formulario.
Enabled
Indica si el formulario está activo (si puede recibir el foco).
AutoScroll,
HorzScrollBar
VertScrollBar
Controlan conjuntamente las barras de desplazamiento de un formulario.
BorderIcons
Indica qué iconos aparecen en la barra de título de un formulario.
BorderStyle
Indica qué tipo de borde debe tener el formulario.
Caption
Indica la cadena que aparece en la barra de título del formulario mientras que Name
Name
Indica con qué nombre se refiere al formulario en la aplicación (en el código).
Color
Color de fondo del formulario.
Cursor
Especifica qué cursor se muestra cuando está sobre el formulario.
Font
Permite especificar las propiedades de la fuente de letra que se usará en el formulario. Se aplica a todos
los componentes ubicados en el formulario o componentes hijo.
Icon
Establece el icono que se verá en la barra de título cuando se muestre el formulario en tiempo de ejecución
y cuando se minimice.
Height y Width Altura y anchura (en píxels) del formulario.
ClientWidth
ClientHeight
Altura y anchura (en píxels) del área de cliente del formulario (el área de cliente es la que queda dentro de
los bordes del formulario y por debajo de la barra de título y de la barra de menú). Al modificar estas
propiedades se actualizan Width y Height.
Tema 3.2.2.- Componentes en C++ Builder
14
Clases de Formularios y Aplicaciones
Propiedades de los formularios en tiempo de diseño y ejecución
Propiedad
Descripción
Left y Top
Coordenadas X e Y del formulario (esquina superior izquierda) en la pantalla.
Position
Determina el tamaño y la posición del formulario.
FormStyle
Para especificar si un formulario es o no parte de una aplicación multiformulario.
HelpFile
HelpContext
Para especificar el fichero de ayuda asociado a la aplicación y gestionar la ayuda contextual.
Hint
Especifica el texto que debe aparecer en el cuadro de ayuda o texto de sugerencia asociado al formulario.
Este cuadro aparece cuando ocurre el evento OnHint. Por defecto se muestra únicamente el cuadro asociado
al componente sobre el que está el ratón por lo que usualmente se emplea esta propiedad para mostrar la
información extensa de este componente en una barra de estado, por ejemplo.
ShowHint
Determina si los cuadros de sugerencia estarán activados o desactivados para el formulario.
Visible
Indica si el formulario es visible o no. Los métodos Show() y ShowModal() hacen que un formulario sea
visible y lo colocan por encima de todos.
WindowState Para establecer el estado inicial del formulario (normal, minimizado o maximizado) o consultar su estado.
Propiedades de los formularios en tiempo de ejecución
Propiedad
Descripción
Active
Indica si el formulario está activo (si tiene el foco).
Canvas
El lienzo es la superficie del formulario sobre la que se puede dibujar. La propiedad Canvas da acceso a
esta superficie para dibujar líneas, mapas de bits, texto, ... en el área de cliente. Suele usarse con el gestor
del evento OnPaint
ClientRect
Coordenadas de los cuatro puntos que delimitan el área de cliente del formulario.
ModalResult
El valor devuelto cuando se cierra un formulario modal (abierto con el método ShowModal()).
FormState
Proporciona información acerca del estado en que se encuentra un formulario (si se está creando, si es
visible, si es modal, etc.).
Tema 3.2.2.- Componentes en C++ Builder
15
Clases de Formularios y Aplicaciones
Métodos de los formularios
Método
Descripción
BringToFront()
SendToBack()
Coloca al formulario en primer plano o en último, respectivamente.
Hide()
Oculta el formulario (establece la propiedad Visible a falso).
Print()
Imprime el contenido del formulario.
Show()
ShowModal()
Para mostrar formularios. ShowModal() ejecuta (abre) el formulario modalmente: debe cerrarse para
que el usuario pueda seguir trabajando con la aplicación.
Close()
CloseQuery()
Close() cierra el formulario tras llamar a CloseQuery() para asegurarse de que es correcto cerrarlo.
Esta última llama al manipulador del evento OnCloseQuery.
SetFocus()
Activa el formulario y lo coloca en primer plano, poniendo a true la propiedad Active. Además, el
componente especificado en la propiedad ActiveControl recibe el foco.
CanFocus()
Devuelve true si el formulario puede recibir el foco (si las propiedades Visible y Enabled están a true).
SetBounds()
Establece simultáneamente los valores de las propiedades Top, Left, Width y Height.
ClientToScreen()
ScreenToClient()
Convierte las coordenadas del área de cliente en coordenadas de pantalla y viceversa.
Invalidate()
Refresh()
Repaint()
Update()
Para redibujar un formulario.
Release()
Destruye un formulario y libera toda la memoria asociada.
Eventos de los formularios
Una acción puede desencadenar varios eventos y el orden en que ocurren puede ser muy importante.
Cuando se crea un formulario se generan los siguientes eventos, que enumeramos ordenadamente:
1. OnCreate.
2. OnShow.
3. OnActivate.
4. OnPaint.
Tema 3.2.2.- Componentes en C++ Builder
16
Clases de Formularios y Aplicaciones
Eventos de los formularios
De la misma manera, cuando se destruye el formulario se generan los siguientes eventos, que
enumeramos ordenadamente:
1. OnCloseQuery.
2. OnClose.
3. OnDestroy.
4. Destructor del formulario (si existe).
Evento
Descripción
OnActivate
OnDeactivate
Ocurren cuando se activa o desactiva un formulario, respectivamente. Un formulario se activa cuando
se recibe el foco y se desactiva cuando el foco pasa a otro formulario de la misma aplicación.
OnCreate
OnDestroy
OnCreate ocurre cuando se crea inicialmente el formulario (sólo ocurre un evento de este tipo por
formulario) y OnDestroy cuando se destruye.
OnClose
OnCloseQuery
El evento OnClose ocurre cuando se cierra un formulario. Hace una llamada a OnCloseQuery para
asegurarse de que es correcto cerrarlo.
OnMouseDown
OnMouseMove
Para responder a los eventos que suceden al mover el ratón o cuando se pincha con él sobre el
OnMouseUp
formulario.
OnClick
OnDblClick
OnKeyDown
OnKeyUp
OnKeyPress
Para responder a los eventos que suceden al pulsar alguna tecla sobre el formulario.
OnHelp
Ocurre cuando se recibe una petición de ayuda en el formulario.
OnHide
OnShow
Ocurren cuando se oculta o se muestra el formulario, respectivamente (cuando su propiedad Visible se
establece a false o true, respectivamente). OnShow ocurre justo antes de que el formulario se haga
visible.
OnPaint
Ocurre cuando el formulario necesita ser redibujado (refrescado). Esto ocurre muy frecuentemente, y
aunque los componentes del formulario se redibujan generalmente por sí mismos, a veces es preciso
redibujar "manualmente" el formulario.
OnResize
Ocurre cuando se modifica el tamaño del formulario, justo después de redimensionar el formulario.
Tema 3.2.2.- Componentes en C++ Builder
17
Resumen sobre la VCL
La VCL (Visual Component Library) la forman un conjunto de componentes u objetos visuales
prefabricados. Cuando incluimos un componente en una aplicación este pasa a formar parte de su
ejecutable. Podemos decir que un componente es un elemento de nuestro programa que posee
características (propiedades) y acciones (métodos) asociadas y que reaccionará o no ante una
situación producida en el entorno (evento). Un componente, por tanto, está asociado a métodos
(código de programa correspondiente a un procedimiento al que se puede acceder desde el programa),
y en muchos casos a propiedades y eventos.
Las propiedades representan los datos contenidos en el objeto.
Los métodos son las acciones que el objeto puede realizar.
Los eventos son condicionantes ante los cuales el objeto puede reaccionar.
Todo componente posee un nombre (Name) que lo
diferencia del resto de componentes de una
aplicación. Por defecto, C++ Builder asigna un valor
que tiene relación con el tipo de componente y un
número que los diferencie del resto de componentes.
Una propiedad la podemos considerar como una
variable ligada al componente que posee un valor que
condicionará su funcionamiento. Algunas propiedades
están disponibles en fase de diseño y otras no, es
decir, que podremos modificar su contenido mediante
el Inspector de Objetos o lo deberemos hacer en
tiempo de ejecución.
Por ejemplo, para modificar el título de un formulario
podemos asignar el valor directamente a la propiedad
Caption desde el Inspector de Objetos o modificarla
desde código cuando ocurra un evento o cuando se
inicie la aplicación. El código asociado se incluiría en
el código del programa como muestra la figura:
Tema 3.2.2.- Componentes en C++ Builder
18
Resumen sobre la VCL
En la figura anterior aparece la línea de código Caption = "Modificación del título o Caption"; que
modificará el contenido de la propiedad en tiempo de ejecución. Si queremos hacer referencia a una
propiedad de un componente desde un procedimiento no asociado a ese componente debemos
referenciar la propiedad con el operador -> de la siguiente forma:
Form1->Caption = "Modificación del título o Caption";
Un evento es una situación que se produce durante la ejecución de un programa. Los eventos pueden
provenir del sistema, del ratón, desde teclado, etc.... Un componente podrá reaccionar ante un evento
si el tipo de componente lo tiene así predefinido, dependiendo del objetivo para el que está diseñado.
Por ejemplo, un componente TForm (formulario o ficha) tiene, por supuesto, un evento asociado a la
acción de cerrar (Sistema), en cambio, el componente TButton (botón) no lo tendrá. Cuando ocurre un
suceso durante la ejecución de nuestro programa, los componentes sobre los que se produzca
reaccionarán o no a este suceso si disponen de un evento que lo detecte. Cuando queramos incluir un
conjunto de sentencias que se ejecuten cuando se produzca un determinado suceso deberemos
asociar un conjunto de instrucciones al evento correspondiente del componente. Este grupo de
acciones se expresará en el código del programa. C++ Builder generará automáticamente la base
principal del código que se va asociar al evento, pudiendo escribir como bloque de instrucciones las
sentencias que deseemos. Por ejemplo, si pulsamos en el Inspector de Objetos del componente
formulario (Form1) sobre el evento OnClose (que se produce cuando se cierra el formulario) aparecerá
el editor de código con las líneas:
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
ShowMessage(“Cierre de la aplicación”);
}
Creándose una línea en blanco donde se sitúa el cursor y donde podemos escribir una línea de código
como la destacada en rojo. Esto nos mostrará una ventana de diálogo con el mensaje entrecomillado y
un botón OK.
Tema 3.2.2.- Componentes en C++ Builder
19
Resumen sobre la VCL
Ejemplo 95.- Propiedades, métodos y eventos sobre un formulario
Se trata de realizar un programa visual que trabaje con propiedades, métodos y eventos de un
formulario para realizar las operaciones que iremos describiendo paso a paso.
En el inspector de objetos (Object Inspector) hacemos los siguientes cambios de propiedades del
formulario:
1.- Ponemos en false los valores de biMinimize y biMaximize de BorderIcons, lo que eliminará las
opciones de maximizar y minimizar en tiempo de ejecución.
2.- A la propiedad BorderStyle le damos el valor bsSingle, impidiendo que la ventana sea
dimensionable en la fase de ejecución.
3.- Asignamos a la propiedad Position el valor psScreenCenter, con lo que la ventana siempre
aparezca centrada en pantalla.
4.- Establecemos la propiedad Cursor con el valor crHandPoint y cuando el puntero del ratón esté
situado sobre el formulario aparezca el cursor como una mano.
5.- Establecemos unas dimensiones del formulario de 150x300 pixels.
Accedemos a la ventana de código con F12, o con el botón de acceso rápido Toggle Form/Unit o bien
desde menú view y escribimos justo debajo de la línea Tform *Form1; la sentencia int ncolor; con la
que definiremos una variable global de tipo entero que, en nuestro programa podrá tomar los valores 1,
2, 3 ó 4.
Entre las llaves que definen el constructor del formulario (líneas que siguen en gris) tecleamos la línea
que vemos destacada en negro .
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Caption = "Modificación del título o Caption";
}
Tema 3.2.2.- Componentes en C++ Builder
20
Resumen sobre la VCL
Ejemplo 95.- Propiedades, métodos y eventos sobre un formulario
Hacemos doble clic sobre el evento OnClose del Inspector de Objetos teniendo seleccionado el
componente Form1 y sobre el gestor de evento que se genera (gris) tecleamos la línea de código en
negro.
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
ShowMessage("Cierre de la aplicación");
}
Hacemos doble clic en el evento OnCreate y escribimos el siguiente código:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
ncolor=1;
Form1->Color=clRed;
}
En este caso no sería necesario anteponer a la propiedad Color el componente al que corresponde
porque la función corresponde al propio formulario. También podríamos usar el puntero this
escribiendo this->Color=clRed; , aunque tampoco es necesario en este caso.
Generamos el evento OnCloseQuery, que se producirá cuando se solicite el cierre del formulario, y
escribimos el siguiente código:
void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if (Application->MessageBox("¿Esta seguro?","Va a cerrar la aplicación",MB_YESNO) == ID_YES)
CanClose=true;
else
CanClose=false;
}
Conseguimos que se pregunte al usuario si quiere o no abandonar el programa, evitándolo si su
respuesta es no.
Tema 3.2.2.- Componentes en C++ Builder
21
Resumen sobre la VCL
Ejemplo 95.- Propiedades, métodos y eventos sobre un formulario
Finalmente, hacemos doble clic sobre el evento OnClick de forma que cada vez que se pulse el ratón
aparezca el fondo del formulario de uno de los 4 colores que escogemos con el código siguiente.
void __fastcall TForm1::FormClick(TObject *Sender)
{
switch (ncolor)
{
case 1:Color=clMaroon; break;
case 2:Color=clPurple; break;
case 3:Color=clGreen; break;
default:Color=clRed;
ncolor=0;
}
ncolor++;
}
Guardamos el programa, depuramos los posibles errores de compilación, linkado y ejecución hasta
ejecutar el programa y la ventana tendrá la siguiente apariencia al solicitar su cierre:
Tema 3.2.2.- Componentes en C++ Builder
22
Componentes
Ya hemos visto que los componentes que podemos insertar en nuestros formularios están organizados
en carpetas (pestañas o páginas) en la Paleta de Componentes del IDE. Los componentes pueden ser
visibles y no visibles.
Pestaña Standar. Estos componentes son los elementos de control más comunes de Windows.
Componente ¿Visible?
Descripción breve
MainMenu
No
Diseño de barras de menús junto con sus correspondientes menús desplegables.
PopUpMenu
No
Diseño de menús contextuales o emergentes que se muestras al hacer clic con el botón
derecho del ratón.
Label
Si
Para mostrar texto no accesible por el usuario, como son los títulos.
Edit
Si
Presenta un área donde el usuario puede introducir o modificar texto en una sola línea.
Memo
Si
Presenta un área donde el usuario puede introducir o modificar varias líneas de texto.
Button
Si
Un botón permite que los usuarios lo seleccionen para realizar una operación.
CheckBox
Si
Casilla de verificación, para alternativas tipo Sí/No, Verdadero/Falso o Activado/Desactivado.
Los CheckBox son independientes entre sí, ya que las opciones que representan no son
excluyentes entre ellas.
RadioButton
Si
Para representar opciones donde sólo está disponible una de ellas.
ListBox
Si
Lista de opciones para que el usuario seleccione una o varias de ellas.
ComboBox
Si
Conjunta la funcionalidad del Edit y del ListBox para presentar una lista de opciones.
ScrollBar
Si
Barra de desplazamiento para poder desplazar en pantalla la parte visible de una lista o ficha,
o trasladarse por un rango en incrementos.
GroupBox
Si
Agrupar componentes relacionados en una ficha.
RadioGroup
Si
Agrupar RadioButton en una ficha.
Panel
Si
Agrupar componentes y creación de barras de estado.
Tema 3.2.2.- Componentes en C++ Builder
23
Componentes
Pestaña Standar
Componente ¿Visible?
Descripción breve
Frames
Si
Contenedor de componentes que puede anidarse en otros frames o formularios.
ActionList
No
Mantiene una lista de las acciones que pueden ser usadas por componentes y controles,
como opciones de menú y botones.
Ejemplo 96.- Modificación y consulta de propiedades en tiempo de ejecución
Se trata de retomar el ejemplo 3 donde diseñamos un formulario con varios campos y establecer
el código necesario sobre los gestores de eventos para realizar las operaciones que citamos.
Sobre el evento OnCreate:
▫ Modificamos la propiedad Caption para que aparezca Ejemplo 96
▫ Si el color del Form es clBtnFace lo cambiamos a clWhite
▫ Establecemos la propiedad Checked del CheckBox a false
▫ Hacemos que se oculten los dos RadioButtom
▫ Crear y trabajar con otros gestores de eventos que describiremos una vez realizadas las
operaciones anteriores.
En primer lugar creamos un nuevo directorio denominado ejemplo 96 y abrimos el ejemplo 3 tal y como
lo dejamos anteriormente. Clicamos en File/Save As... y guardamos en nuestro nuevo directorio y
también File/Save Project As ... para archivar el proyecto cambiando el nombre de Ejemplo3 a
Ejemplo96. Con esto tendremos los archivos necesarios mínimos para el proyecto. El código asociado
al evento OnCreate será:
FormPrincipal->Caption = "Ejemplo 96";
if (FormPrincipal->Color == clBtnFace) // Lectura
FormPrincipal->Color = clWhite; // Escritura
CheckBoxOpciones->Checked = false; // Escritura
RadioButtonOp1->Hide();
RadioButtonOp2->Hide();
/* Hide() es el método que oculta el componente sobre el que se aplica. */
Tema 3.2.2.- Componentes en C++ Builder
24
Componentes
Ejemplo 96.- Modificación y consulta de propiedades en tiempo de ejecución
Hasta este momento el aspecto de la aplicación en tiempo de ejecución será
Una vez llegados a este punto vamos a dar sentidos
a los botones, a la casilla de selección, a las
opciones de selección (ahora no visibles) y a la
etiqueta que por ahora no es visible (propiedad
Caption vacía). Procedemos a:
Construir el gestor del evento asociado a modificar
el componente de selección CheckBox de forma que
cuando se active (inicialmente está desactivado) se
muestren los dos RadioButtom y se active el botón
de OK. Cuando se desactive, los RadioButtom se
volverán a ocultar y el botón de OK se desactivará.
if (CheckBoxOpciones->Checked == true)
Para ello, escribiremos el gestor asociado al evento
{
OnClick del componente CheckBox:
RadioButtonOp1->Show();
RadioButtonOp2->Show();
RadioButtonOp1->Checked = true;
ButtonOK->Enabled = true;
}
else
{
RadioButtonOp1->Hide();
RadioButtonOp2->Hide();
ButtonOK->Enabled = false;
LabelSalida->Caption = "";
}
Tema 3.2.2.- Componentes en C++ Builder
25
Componentes
Ejemplo 96.- Modificación y consulta de propiedades en tiempo de ejecución
Finalmente, escribiremos el gestor del evento asociado a hacer clic sobre el botón OK, que está
operativo (propiedad Enabled) únicamente cuando el CheckBox está activado, y en consecuencia,
cuando pueden emplearse los RadioButtom. Haremos además que en la etiqueta vacía se muestre un
texto alusivo al texto introducido (o no) en el Edit y a la opción elegida. Este evento será:
if (RadioButtonOp1->Checked)
{
if (EditNombre->Text=="")
LabelSalida->Caption="Ha escogido la Opción 1, D./Dª. sin identificar";
else
LabelSalida->Caption="Ha escogido la Opción 1, D./Dª. " + EditNombre->Text;
}
else
{
if (EditNombre->Text == "")
LabelSalida->Caption = "Ha escogido la Opción 2, D./Dª. sin identificar";
else
LabelSalida->Caption = "Ha escogido la Opción 2, D./Dª. " + EditNombre->Text;
}
Tema 3.2.2.- Componentes en C++ Builder
26
Conversión entre tipos
Cuando estudiamos la clase AnsiString vimos que resultaba especialmente útil la conversión entre
tipos, por lo que vamos a analizar algunas de las rutinas de conversión entre tipos.
StrToInt
Convierte un AnsiString que representa un número entero (en notación decimal o hexadecimal) a un
número. Su sintaxis es la siguiente: StrToInt(const AnsiString S);. StrToInt convierte la cadena S de
tipo AnsiString, que representa un número de tipo entero en notación decimal o hexadecimal, en un
número. Si la S no representa número válido, StrToInt ejecuta una excepción EconvertError.
Ejemplo 97.- Uso de StrToInt
Situamos en un formulario dos elementos Edit y un elemento Button. Cuando pulsemos el botón,
el código convierte los valores introducidos en los Edit a números enteros, los suma, y muestra un
mensaje que indica la suma. El fichero .cpp quedaría en los gestores de eventos de la siguiente forma:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int i1, i2; //Declara i1 e i2 como enteros
i1 = StrToInt(Edit1->Text);
//Convierte a entero el Text que introducimos en Edit1, que deberá ser
// un número entero, y asigna el valor a i1
i2 = StrToInt(Edit2->Text);
//Convierte a entero el Text que introducimos en Edit2, que deberá ser
// un número entero, y asigna el valor a i2
ShowMessage("Suma: " + IntToStr(i1 + i2));
// Suma los valores i1 e i2 (un entero) y convierte el resultado en un
// string que se muestra como mensaje emergente.
}
//--------------------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender)
{
Edit1->Text="";
Edit2->Text="";
}
Tema 3.2.2.- Componentes en C++ Builder
27
Conversión entre tipos
Recordemos lo que pasaba con la
suma de enteros con números dentro
del rango del tipo int.
En cambio cuando tecleamos un
número fuera de rango lo que ocurre
es:
Efectivamente, el número introducido no es un valor entero válido,
por lo que se ejecuta una excepción EconvertError antes de
efectuar la operación señalada. Dicho de otra forma, la suma se
realiza en complemento a 1 y, mientras los datos introducidos
sean enteros válidos, el procesador efectuará la suma dentro de
rango sin lanzar una excepción EconvertError. De esta forma se
evita que el procesador realice operaciones no válidas mediante
comandos de programación, pero en cambio surge un error en la
programación que debemos tener especialmente presente.
Tema 3.2.2.- Componentes en C++ Builder
28
Conversión entre tipos
El problema lo podemos resolver utilizando el siguiente procedimiento, del que vemos el resultado:
Ejemplo 97b.- Uso de StrToInt
Situamos en un formulario tres elementos Edit, dos label y un elemento Button. Cuando pulsemos
el botón, el código convierte los valores introducidos en los Edit a números enteros de 64 bits, los
suma, y muestra en el tercer Edit la suma. El fichero .cpp quedaría en los gestores de eventos de la
siguiente forma:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
__int64 i1, i2;
i1 = StrToInt64(Edit1->Text);
i2 = StrToInt64(Edit2->Text);
Edit3->Text = i1+ i2;
}
//--------------------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender)
{
Edit1->Text="";
Edit2->Text="";
Edit3->Text="";
}
Tema 3.2.2.- Componentes en C++ Builder
29
Conversión entre tipos
StrToIntDef
Convierte un AnsiString que representa un número entero a un número. Su sintaxis es la siguiente:
StrToIntDef(const System::AnsiString S, int Default);
StrToIntDef convierte la cadena S de tipo AnsiString, que representa un número de tipo entero en un
número. Si la S no representa número válido, StrToIntDef devuelve el entero introducido por defecto en
int Default, evitando así la excepción EconvertError que se produce en StrToInt.
Ejemplo 98.- Uso de StrToIntDef
Veamos un ejemplo que utiliza dos elementos Label, dos Edit y un Button de forma que el usuario
introduce en dato de entrada un número entero, clica sobre el botón de ejecución y en el campo
correspondiente a dato de salida aparece el número tecleado si es un entero válido, en caso contrario
aparecerá el número 0 introducido por defecto. El código para el OnClick del botón será el siguiente:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int Numero = StrToIntDef(Edit1->Text, 0);
Edit2->Text = IntToStr(Numero);
}
Los resultados son:
Tema 3.2.2.- Componentes en C++ Builder
30
Conversión entre tipos
IntToStr
Convierte un número entero en un AnsiString. Su sintaxis, cuando trabajamos con tipo int, es la
siguiente:
IntToStr(int Value);
Su sintaxis, cuando trabajamos con tipo __int64, es la siguiente:
IntToStr(__int64 Value);
Es decir puede trabajar con cualquier dato de tipo int.
En el ejemplo de StrToInt hemos puesto la línea siguiente: Edit3->Text = i1+i2;. El texto del Edit3 era la
suma i1+i2 , que es un número entero (también es una cadena) puesto que lo son i1 e i2, pero lo más
correcto es convertir de forma efectiva el número entero en un AnsiString que es lo que “en realidad”
puede mostrar un Edit. Lo más correcto en el ejemplo citado será:
Para tipo int:
int i1, i2; // 1
i1 = StrToInt(Edit1->Text);
i2 = StrToInt(Edit2->Text);
Edit3->Text = IntToStr(i1+i2); //2
// 1: Datos de tipo int
// 2: Como i1 e i2 son tipo int, IntToStr trabajo con tipo int
Para tipo __int64:
__int64 i1, i2; // 1
i1 = StrToInt64(Edit1->Text);
i2 = StrToInt64(Edit2->Text);
Edit3->Text = IntToStr(i1+i2); //2
// 1: Datos de tipo int64
// 2: Como i1 e i2 son tipo int64, IntToStr trabajo con tipo int64
Tema 3.2.2.- Componentes en C++ Builder
31
Conversión entre tipos
StrToFloat
Convierte un AnsiString a un valor de coma flotante. Su sintaxis es la siguiente:
StrToFloat(const AnsiString S);
StrToFloat convierte la cadena AnsiString S a un valor de coma flotante. La cadena S puede contener
opcionalmente un signo + o -, una cadena de dígitos con un punto decimal, una ‘E' o ‘e' seguida por un
número entero con signo. Los espacios en blanco son ignorados.
La variable global DecimalSeparator define el carácter usado como punto decimal. En la cadena no se
pueden usar separadores de miles ni símbolos de moneda. Si la S no contiene un valor válido,
StrToFloat lanza una excepción ECONVERTERROR.
FloatToStr
Convierte un valor en coma flotante a un AnsiString. Su sintaxis es la siguiente:
FloatToStr(Extended Valor);
FloatToStr convierte el valor en coma flotante dado por Valor a una cadena. En general, el formato de
conversión numérica emplea 15 dígitos significativos.
Extended hace referencia a los tipos reales descritos anteriormente.
FloatToStrF
Convierte un valor en coma flotante a un AnsiString usando un formato que debemos especificar en
cuanto a precisión y número de dígitos. Su sintaxis es la siguiente:
FloatToStrF(Extended Valor, TfloatFormat Formato, int Precision, int Digitos);
FloatToStrF convierte el valor en coma flotante especificado por Valor a su representación como
cadena de caracteres (string). El parámetro Valor es el valor a convertir. El parámetro precisión
especifica la precisión de valor. Debería ser inferior o igual a 7 para valores sencillos, menor o igual a
15 para valores de tipo Doble, y menor o igual a 18 para los valores de tipo real descritos. El número de
dígitos y los parámetros de formato controlan la forma de conversión en cadena.
Para todos los formatos, los caracteres usados como coma decimal y separador de miles se definen en
las variables globales DecimalSeparator y ThousandSeparator respectivamente.
Si el valor dado es una cadena YO (no un número), la cadena resultante es 'YO'. Si el valor dado es el
infinito positivo, la cadena resultante es 'INF'. Si el valor dado es el infinito negativo, la cadena
resultante es '-INF '.
Tema 3.2.2.- Componentes en C++ Builder
32
Conversión entre tipos
StrToCurr
Convierte un AnsiString en un objeto tipo Currency. Su sintaxis es la siguiente:
StrToCurr(const AnsiString S);
CurrToStr y CurrToStrF
Convierte un currency en representación de tipo cadena sin y con formato respectivamente. Su sintaxis
es la siguiente:
CurrToStr(Currency value);
CurrToStrF(System:: Currency Value, TFloatFormat Format, int Digits);
StrToDate
Convierte una cadena AnsiString a un objeto TdateTime con la siguiente sintaxis:
StrToDate(const AnsiString S);
Llama a StrToDate para analizar una cadena que especifica una fecha. Si la S no contiene una fecha
válida, StrToDate lanza una excepción ECONVERTERROR
TDateTime es una clase de C++ basada en el tipo de datos de fecha y hora de Delphi. La clase
TDateTime es un miembro heredado de datos val declarado como double que contiene los valores de
fecha y hora. La parte entera de un TDateTime es el número de días que han pasado desde 12/30/1899.
La parte fraccionaria de un valor TDateTime es la hora de ese día.
DateToStr
Convierte un objeto TdateTime a un AnsiString con la siguiente sintaxis:
DateToStr(System::TDateTime Date);
Ejemplo 99.- ¿Que día de la semana es?
Sobre un formulario situamos varios Label, un Edit y un Button. Cuando introduzcamos en el edit
un dato con el formato DD-MM-YY, la cadena será convertida a un valor TdateTime que será usado para
calcular el día de la semana que representa, mostrándonos además la fecha actual.
Tema 3.2.2.- Componentes en C++ Builder
33
Conversión entre tipos
Ejemplo 99.- ¿Que día de la semana es?
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DateSeparator = '-'; //Cambia el separador / por ShortDateFormat = "d/m/yyyy"; //Cambia el formato de m/d/yyyy a d/m/yyyy
Label2->Caption = DateToStr(Date()); //Fecha actual del sistema
char dias[7][10]={"Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sabado" };
TDateTime dia = StrToDate(Edit1->Text); //1
Label4->Caption = dias[dia.DayOfWeek() - 1]; //Mostramos el resultado obtenido
//1 Convertimos de String a Date almacenandolo en dia del tipo TDateTime
}
StrToTime
Convierte una cadena AnsiString a un objeto TdateTime con la siguiente sintaxis:
StrToTime(const AnsiString S);
El parámetro S se forma con dos o tres numeros, separados por un caracter definido en la variable
global TimeSeparator, y seguidos opcionalmente del indicador AM o PM. Los números representan las
horas, minutos y, opcionalmente, los segundos. Si la hora va seguida de AM o PM se asume un formato
de reloj de 12 horas y si no se incluye el indicador el formato es de 24 horas.
TimeToStr
Convierte un objeto TdateTime a un AnsiString con la siguiente sintaxis:
TimeToStr(System::TDateTime Time);
Tema 3.2.2.- Componentes en C++ Builder
34
Conversión entre tipos
DateTimeToStr
Convierte un objeto TdateTime a un AnsiString con la siguiente sintaxis:
DateTimeToStr(const System::TDateTime DateTime);
Ejemplo 100.- Buenos días o buenas tardes
Veamos un programa que salude con buenos días o buenas tardes según la hora introducida.
Además vamos a mostrar la fecha y la hora con las conversiones vistas.
El código es:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
DateSeparator = '-'; //Cambia el separador / por ShortDateFormat = "d/m/yyyy"; //Cambia el formato de m/d/yyyy a d/m/yyyy
TDateTime hora = StrToTime(Edit1->Text); //1
if (hora < (TDateTime) 0.50 ) //2
Edit2->Text="Buenos días";
else
Edit2->Text="Buenas tardes";
// 1 Convertimos el texto de Edit1 (dado en formato HH:MM:SS) a formato Tdate Time
// asignado el valor a la variable hora
//2 Según sea antes de las 12 o después de las salude se emite uno u otro saludo
TimeSeparator = '_';
Label3->Caption = TimeToStr(Time());
Label5->Caption = DateToStr(Date()); //Fecha actual del sistema
Label7->Caption = DateTimeToStr(Now());
}
Tema 3.2.2.- Componentes en C++ Builder
35
Conversión entre tipos
Ejemplo 100.- Buenos días o buenas tardes
Algunos resultados.
IntToHex
Convierte a notación hexadecimal un entero. Su sintaxis es la siguiente:
IntToHex(int Valor, int Digitos);
IntToHex(__int64 Valor, int Digitos);
Antes de ver un ejemplo de conversión a hexadecimal diremos que la conversión se realiza carácter a
carácter dando como resultado un carácter UNICODE. UNICODE es un juego de caracteres que emplea
dos bytes para representar cada carácter.
Tema 3.2.2.- Componentes en C++ Builder
36
Conversión entre tipos
IntToHex
Códigos UNICODE de los números:
0030 - 0039 -> 0 - 9 ISO - LATIN-1
Códigos UNICODE de las letras y otros caracteres:
0024
Signo de $
0041 - 005A
Mayusculas A a Z
005F
_(guión bajo)
0061 - 007A
Minusculas a a z
00C0 - 00D6
À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ñ Ò Ó Ô Õ Ö
00D8 - 00F6
ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïõñòóôõö
00F8 - 00FF
øùúûüýþÿ
Ejemplo 101.- Conversión a Hexadecimal
Sobre un formulario situaremos, entre otros, un Edit, un Button y un Label de forma que en el
Label aparezca la conversión a hexadecimal de la cadena introducida en el Edit.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString EditText = Edit1->Text;
Label2->Caption = "";
for (int i=1;i<=EditText.Length();i++)
{
Label2->Caption = Label2->Caption + IntToHex(EditText[i],4) + " ";
}
}
Tema 3.2.2.- Componentes en C++ Builder
37
Componentes
Label
Este componente se utiliza para desplegar textos o mensajes estáticos dentro de los formularios,
textos tales como encabezados, solicitud al usuario del programa para que proporcione algún dato o
información (edad, sueldo, etc.), en cierta forma hace las funciones de printf, cout, etc., pero solo
cuando se considera el aspecto de mensajes.
También es un objeto en C++Builder y por tanto tiene asociados sus propias propiedades, métodos y
eventos. Como su uso normal es dentro de un objeto Form, muchas propiedades que se definan para
el objeto Form1, el objeto Label1 las va a heredar.
La propiedad Caption es la que contiene el mensaje a mostrar en la pantalla, que por defecto es su
nombre inicial, pero se puede cambiar haciendo clic en la propiedad Caption del Inspector de Objetos,
teniendo seleccionado Label en el formulario y escribir el texto que deseemos. También podemos
cambiar la propiedad Caption en tiempo de ejecución mediante una línea de programa como la
siguiente: Label1->Caption = ”Hola mundo...”;
Su uso se limita a mostrar resultados e información al usuario, debido a que este no puede editarlo. No
puede contener el foco en una aplicación.
Su principales propiedades son:
Name: Es el nombre lógico con el que se referencia al componente.
Caption: Permite modificar el texto que se muestra.
Font: Modifica la fuente, estilo de fuente, tamaño, etc. del caption.
Alignment: Especifica la alineación del texto (derecha, izquierda o centro).
Button, BitBtn y SpeedButton
Button es un botón estándar de Windows, mientras los que los otros dos (pestaña Additional) amplían
sus funcionalidades como permitir incluir un bitmap.
Button es el componente más empleado, ya que normalmente contiene el código principal del
programa y su activación por el usuario provoca que se realicen los principales procesos del problema
planteado (aquí es donde se va a capturar datos, realizar operaciones, etc.).
Tema 3.2.2.- Componentes en C++ Builder
38
Componentes
Button, BitBtn y SpeedButton
De este componente manejaremos su propiedad Caption para indicar acciones, etiquetándolo con
palabras como Ok, Aceptar, Exe, ejecutar, etc. , y su evento OnClick para activarlo, siendo en dicho
evento donde se construye el código del programa.
Lo dicho anteriormente no significa que sea un componente necesario en los programas, ya que el
código se puede asociar a cualquier evento de cualquier formulario u otro componente del programa,
pero el manejo de Windows nos tiene acostumbrados al empleo del botón OK o Aceptar.
Este botón puede activar su evento OnClick, cuando el usuario presione la tecla Enter poniendo su
propiedad Default en true. Igualmente puede activar su evento OnClick cuando el usuario, presione la
tecla ESC tan solo con poner la propiedad Cancel en true. Estas opciones no están disponibles para
SpeedButton. Sus principales propiedades son:
Name: Nombre lógico con el que se referencia al componente.
Caption: Texto del botón.
Font: Modifica la fuente, estilo de fuente, tamaño, etc. del caption.
Height y Width: Alto y ancho del botón en pixels.
Left y Top: Posición superior izquierda del extremo superior izquierdo del botón relativa al del
formulario en pixels.
Enabled: Habilita o deshabilita la respuesta del botón a eventos.
Hint: Texto de ayuda a pista rápida. Para podamos ver el Hint debe colocarse la propiedad
ShowHint en true. Estas propiedades se encuentran en la mayoría de los componentes
visuales.
Visible: Determina cuando aparece el botón en el formulario.
Glyph (sólo en BitBtn y SpeedButton): permite especificar el bitmap que aparece en el botón.
Kind (sólo en BitBtn): determina el tipo de algunos bitmap predefinidos.
Flat (sólo en SpeedButton): hace desaparecer el efecto 3D de los botones.
Down (sólo en SpeedButton): especifica cuando el botón está presionado. Para quedar
presionado la propiedad GroupIndex debe ser distinta de cero.
TabOrder: especifica el orden en el que los componentes tendrán el foco.
Tema 3.2.2.- Componentes en C++ Builder
39
Componentes
Button, BitBtn y SpeedButton
Sus principales eventos son:
OnClick: ocurre cuando se hace click sobre el botón.
OnMouseMove: ocurre cuando se mueve el mouse sobre el botón.
Un método muy empleado es:
SetFocus: coloca el foco en el botón.
Edit
La función principal de este componente visual es manejar todos los procesos de entrada y salida
(input/output) del programa. El componente Edit, es el equivalente a las variables en cualquier lenguaje de
programación, mas la instrucción de captura o despliegue correspondiente, es decir;
a) En PASCAL: Read (Ciudad) -> Edit1
b) En C: printf("%d", sueldo) -> Edit2
c) En C++, cin.get(nombre,30) -> Edit3
Es decir, que este componente permite capturar datos y también, como en el caso del componente Label,
desplegar datos, textos, mensajes o resultados de operaciones, usando su propiedad Text. Esta propiedad,
así como la propiedad Caption en Label, permiten igualarse a muchos procesos básicos, es decir es fácil
igualar Text o Caption a un dato, una variable, otro Text o Caption, o una expresión algebraica normal, como
en los siguientes ejemplos:
Edit1->Text = 5;
Label2->Caption = "Palabra";
Edit3->Text = 87/ 6.2 ;
Su valor por defecto es Edit1 y es en su propiedad Text donde se modifica, generalmente al principio de un
programa se deja en blanco, y al ejecutarse el programa, el usuario lo llena con los datos solicitados o el
programa lo llena con el resultado de las operaciones. Cuando un usuario lo carga con un dato, este es
almacenado como tipo texto, independientemente de lo que haya escrito el usuario.
Para resolver el problema de usar datos numéricos dentro de Text de un componente Edit, en operaciones
matemáticas, basta agregarle a la propiedad Text, las funciones de conversión vistas, como .ToInt() o
.ToDouble(), como se muestra en los siguientes ejemplos.
Edit3->Text= Edit2->Text.ToInt() * 5;
Edit5->Text= 3 * pow( Edit2->Text.ToDouble(), double (4) );
Tema 3.2.2.- Componentes en C++ Builder
40
Componentes
Edit
Si, por ejemplo, se pide resolver el problema de multiplicar dos números cualesquiera, se utilizarán
tres componentes Edit (multiplicando, multiplicador, producto) como si fuesen tres variables simples
directamente.
El problema puede resolver de la siguiente manera:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit3->Text=Edit1->Text.ToInt()* Edit2->Text.ToInt();
}
Y un posible resultado puede ser:
Observamos como el componente Edit permite capturar datos por parte del usuario del programa.
Si se realizan divisiones con componentes Edit debemos recordar que al menos uno de ellos sea
double, porque de lo contrario se trunca la parte fraccionaria.
Para resolver el problema de conversión de datos o variables numéricas a Texto de un componente
Edit, donde se tiene una variable numérica cargada, con un resultado o dato numérico y se pretende
mandarla a un componente Edit o Label para su despliegue, existen dos manera sencillas, que son:
•Usando la clase AnsiString, que puede recibir como argumentos o parámetros una variable de
tipo entera o double y convertirla directamente a una string, que es el tipo de dato que espera el
componente Edit o el componente Label para su despliegue, por ejemplo:
Tema 3.2.2.- Componentes en C++ Builder
41
Componentes
Edit
int a; // área de declaración de variables
double b;
a = Edit1->Text.ToInt(); // área de captura de datos
b = Edit2->Text.ToDouble();
a = a+3; // área de operaciones
b = b *5.1; // área de despliegue y conversión de números a strings o Edits
Label3->Caption = AnsiString(a);
Edit4->Text = AnsiString(b);
Como se observa se puede transferir variables numéricas tanto a Label como a Edit mediante la clase
AnsiString, sin embargo es mas sencillo usar el método que se usa en el programa dado de ejemplo
para la multiplicación, es decir considerar los componentes Edit como variables normales.
•Para el caso de resultados decimales , la salida incluye todo el conjunto de decimales
asociados a un tipo double (muchos ceros), para resolver este problema se pueden usar
directamente algunos de los métodos asociados a la clase AnsiString, por ejemplo uno de esos
métodos es; FormatFloat("string de formato", var double);
La string de formato contiene una serie de símbolos literales que se utilizan para darle el formato de
salida deseado, esto símbolos o constantes literales junto con algunos ejemplos de salida con el
formato que producen son:
0
1234
-1234
1
0
0.00
1234.00
-1234.00
0.50
0.00
#.##
1234
-1234
.5
#,##0.00
1,234.00
-1,234.00
0.50
0.00
#,##0.00;(#,##0.00)
1,234.00
(1,234.00)
0.50
0.00
#,##0.00;;Zero
1,234.00
-1,234.00
0.50
Zero
0.000E+00
1.234E+03
-1.234E+03
5.000E-01
0.000E+00
#.###E-0
1.234E3
-1.234E3
5E-1
0E0
Tema 3.2.2.- Componentes en C++ Builder
42
Componentes
Edit
Por ejemplo:
double a; // área de declaración de variables
a = Edit1->Text.ToDouble(); // captura y conversión de datos
a = a/3.1416 ; // operaciones
Edit2->Text= FormatFloat("###,###.##", a); // conversión y despliegue de datos con formato
Veamos un ejemplo muy similar al de multiplicar asociando a Button1 la siguiente línea de comandos:
Edit3->Text= FormatFloat("###,###.##",Edit1->Text.ToDouble()/ Edit2->Text.ToDouble());
En la figura vemos algunos posibles resultados:
Ejemplo 102.- Calcular el área de un triángulo
Vamos a construir un programa que nos facilite el modelo de solución del área del triángulo
conocidas la base y la altura. Construimos un formulario similar a:
Tema 3.2.2.- Componentes en C++ Builder
43
Componentes
Ejemplo 102.- Calcular el área de un triángulo
El código asociado al evento OnClick del componente Button quedará como sigue:
Edit3->Text=FormatFloat("###.##",Edit1->Text.ToDouble()*Edit2->Text.ToDouble()/2);
MaskEdit
Este componente de la pestaña Adittional es muy similar en su uso al componente Edit, excepto que
proporciona una mascara especializada para el formato de datos, es decir se puede usar para que el
usuario proporcione datos con formatos bien definidos, como son valores numéricos que incluyan
puntos y comas por ejemplo 3,345.87, o que incluyan símbolos, o para el caso de fechas que lleven su
propio separador como por ejemplo 16/06/2003.
También se puede usar, para asegurar
que el dato proporcionado por el usuario,
solo incluya números, o solo contenga
letras, etc. Para dar formato al dato que el
usuario debe proporcionar basta con
hacer doble clic en la propiedad EditMask
en (Inspector de Objetos), para desplegar
la ventana que vemos.
Observamos en la parte derecha de la
ventana algunos ejemplos de mascaras
de edición.
Tema 3.2.2.- Componentes en C++ Builder
44
Componentes
MaskEdit
En la ventanilla superior izquierda se colocan los caracteres especiales de edición y en la ventanilla inferior
izquierda se muestra el formato que adquiere y se pueden proporcionar datos para probar el formato
diseñado. Los principales caracteres especiales de edición son:
Carácter
Significado
!
Los carácteres opcionales aparecen en blanco
>
Todos los caracteres que le siguen se pasan a mayúsculas hasta el final de la máscara o hasta que se
encuentra el carácter <.
<
Todos los caracteres que le siguen se pasan a minúsculas hasta el final de la máscara o hasta que se
encuentra el carácter >.
<>
Los caracteres que siguen aparecen en mayúsculas o minúsculas según sean tecleados por el usuario.
\
El carácter siguiente es un carácter literal.
L
Requiere una letra mayúscula o minúscula en esta posición
l
Permite una letra es esta posición pero no la requiere
A
Requiere un carácter alfanumérico (letras y/o números) en esta posición
a
Permite un carácter alfanumérico en esta posición pero no lo requiere
C
Requiere un carácter arbitrario en esta posición.
c
Permite un carácter arbitrario en esta posición pero no lo requiere
0
Requiere un numero en esta posición
9
Permite un numero pero no lo requiere
#
Permite un numero y signos mas y menos en esta posición pero no lo requiere
:
Separador de horas, minutos y segundos para funciones horarias.
/
Separador de meses, días y años para funciones de fecha.
;
Se utiliza para separar los tres campos o partes de que consta una mascara
_
Para insertar espacios en blanco en el texto de la mascara
Tema 3.2.2.- Componentes en C++ Builder
45
Componentes
MaskEdit
Cualquier carácter que no aparezca en la tabla anterior puede aparecer en una máscara, pero se tomara
como un literal cualquiera, es decir se insertará automáticamente y el cursor saltará a una posición
posterior. El segundo campo de una mascara es un carácter simple que indica que carácter literal debe
ser incluido como parte del texto del componente MaskEdit, por ejemplo (000)_000-000;0;*. Un 0 en el
segundo campo indica que solo deben capturarse los nueve dígitos marcados con 0, en lugar de los 13
que tiene la mascara. El tercer campo de la mascara es el carácter que queremos que aparezca en lugar
de espacios en blancos.
Para procesar MaskEdit deberemos usar solo Text y no Text.ToDouble() y recuérdese que este formato
es para capturar datos, no para mostrarlos, puesto que para este caso se usa FormatFloat().
ComboBox
Existen multitud de ocasiones en donde el usuario del programa tiene que proporcionar datos que
provienen de un conjunto finito y muy pequeño de posibles respuestas, lo que significa que cada vez
que se ejecute el programa, el usuario deberá proporcionar las mismas respuestas. Por ejemplo
capitales de provincia en Andalucía, donde las posibles respuestas son: Almería, Cádiz, Córdoba,
Granada, Huelva, Jaén, Málaga o Sevilla; o en la situación de preguntar por el sexo (Hombre, Mujer),
etc. Para situaciones como esta, existen componentes que permiten programar por adelantado las
posibles respuestas, y el usuario solo debe seleccionar la respuesta apropiada, en lugar de tener que
escribirla. Este componente es el ComboBox, que nos permite definir en primera instancia un conjunto
de datos, valores o respuestas asociados a un componente de edición cualquiera, de forma que el
usuario tendrá la oportunidad de seleccionar un dato del conjunto de datos o respuestas ya definido. El
componente ComboBox tiene dos partes:
– Una parte de encabezado, para poner el nombre del grupo de respuestas (por ejemplo capitales de
provincia, sexo, etc.), que se carga usando la propiedad Text del componente; y
– Una segunda parte que es la lista de opciones o respuestas que se debe cargar cuando se diseña la
ventana. Para la inclusión de datos debemos hacer doble clic en la propiedad Items en el Inspector
de objetos y nos saldrá el siguiente editor de strings o cadenas:
Tema 3.2.2.- Componentes en C++ Builder
46
Componentes
ComboBox
En tiempo de ejecución del programa, toda la lista de respuestas, estará a la vista del usuario, para que
seleccione la deseada. Basta que este pulse sobre la flechita que esta al lado del encabezado. Para
procesar este componente debemos usar su propiedad Text de manera normal, es decir si la respuesta
se desea de tipo string usaremos ComboBox1->Text, y si la respuesta se quiere numérica debemos
convertir Text a ToInt() o ToDouble(). Por ejemplo, ComboBox1->Text.ToDouble().
Panel
Para poder organizar correctamente todos los datos e información que aparecen en las aplicaciones
disponemos de dos métodos, bien trabajar con dos o más ventanas o bien utilizar alguno de los
componentes de agrupamiento disponibles. El componente Panel es el más sencillo y común de los
componentes de agrupamiento y se utiliza para poner un panel, cuadro o marco dentro de una ventana.
El componente Panel puede contener toda una serie lógica de otros componentes. Tan solo se debe
recordar que primero debemos colocar todos los paneles en el formulario y encima de ellos los
componentes que contendrán.
Tema 3.2.2.- Componentes en C++ Builder
47
Componentes
Panel
Este componente también tiene una serie de propiedades que le dan una mejor presentación usando
las propiedades BevelInner, BevelOuter, BevelWidth, y BorderWidth.
Es decir, podemos dividir una ventana en varias partes, por ejemplo en un panel se ponen los
componentes donde se capturan los datos de un problema y en otro panel se ponen los datos de
salida.
Para modificar programas construidos sin paneles, el procedimiento para agregarlos es:
0. Mover todos los componentes a alguna parte de la ventana en la que no molesten. Si es necesario
se amplía la ventana.
1. Colocar los componentes panel en su posición.
2. Seleccionamos con un clic el Componente a relocalizar.
3. Seleccionamos del menú Edit la entrada Copy o mejor Cut (CTRL+C o CRTL+X)
4. Clic dentro del panel, donde queremos el componente.
5. Seleccionamos del menú Edit la entrada Paste (CTRL+V).
6. Readaptamos la ventana al tamaño adecuado.
GroupBox
Este componente es muy similar al componente panel, excepto que incluye una pestaña que permite
dejar mas claro el propósito del grupo. El texto que identifica el propósito general del grupo se escribe
dentro de la propiedad Caption en el Inspector de Objetos, teniendo seleccionado este componente
GroupBox.
Además de sus propiedades, métodos y eventos propios, como todos los componentes de este tipo,
hereda las propiedades, métodos y eventos de todos los controles generales de tipo Windows.
Ejemplo 103.- Componentes de agrupamiento
Vamos a reconstruir el ejemplo de cálculo del área de un triángulo utilizando un componente
panel y un groupbox.
Tema 3.2.2.- Componentes en C++ Builder
48
Componentes
Múltiples ventanas
Un problema muy común en programación visual es el de poder crear, controlar y administrar dos o
más formularios o ventanas desde una misma aplicación o proyecto.
Lo primero que hay que entender para poder resolver este problema es que en C++Builder, cada
formulario o ventana tiene asociados ciertos recursos especiales, ademas de los componentes que
contiene relacionados todos ellos en un archivo, que por defecto, toma el nombre de Unit1.cpp. Es
decir, si se crea un segundo formulario o ventana, dicho formulario, junto con sus recursos,
componentes, etc., se encontraría contenido en el archivo llamado "Unit2.cpp" y así sucesivamente.
Para crear un segundo formulario (Form2), se puede usar el icono de New Form de la barra de
herramientas, o bien la entrada New Form del menú File.
El segundo formulario se construye normalmente, pero queda el problema de donde situar el botón de
ordenes, y la respuesta es que se pone en el primer formulario o ventana principal del programa. El
proceso en este botón es similar al de los programas anteriores, es decir primero se capturan los datos
(pantalla o ventana de captura), luego se resuelve las operaciones y finalmente se traspasan los datos
a los componentes de la segunda ventana. Para poder realizar este proceso la sintaxis general es
ahora:
Nombre_formulario -> Nombre_componente -> Nombre_propiedad
Los siguientes ejemplos aclararán estos conceptos:
Form5->Edit3->Text=Form1->Edit2->Text; //1
int alfa = Form3->Edit4->Text.ToInt(); //2
// 1. El contenido de la propiedad Text del Edit2 de Form1 se pasa a la propiedad Text del Edit3 del Form5.
// 2. La variable tipo int alfa toma como valor el contenido, convertido a tipo int, del Edit4 del formulario Form3.
Observamos que procesar elementos de distintas ventanas, es, inicialmente, sencillo, pero además
existen ciertas condiciones que deberán cuidarse para que estos procesos funcionen, y estas
condiciones son:
Tema 3.2.2.- Componentes en C++ Builder
49
Componentes
Múltiples ventanas
0. Crear y diseñar todas las ventanas junto con sus componentes y programas.
1. Cualquier ventana que mencione o contenga una referencia dentro de su código a otra ventana,
deberá incluir en su Unit respectiva, la unidad (Unit) de la otra forma o ventana.
2. Para incluir la unidad (Unit) de la otra ventana debemos tener seleccionada la ventana que llama y
usar la orden Include Unit del menú File, que mostrará una lista con todas las unidades (Unit) que se
han diseñado, y debemos seleccionar la apropiada que se incluirá automáticamente en la ventana
actual.
3. Si una ventana referencia dos o más ventanas diferentes debemos usar la orden File/Include Unit,
tantas veces como sea necesario.
Este procedimiento permite construir programas con dos o más ventanas, pero el problema es que
todas ellas estarán a la vista del usuario, para resolver este problema, el procedimiento más sencillo es
poner en False la propiedad visible de la ventana que se quiera tener oculta y poner cualquiera de las
siguientes instrucciones en el código del programa para que aparezcan o desaparezcan a voluntad:
Form2->Visible = true;
Form2->Show(); // similar a la anterior, pero mas corta
Form2->ShowModal(); // no permite acceder a la primera ventana hasta que se cierra la segunda ventana
Si tenemos formularios de mas, o que ya no se quieren usar, o que están mal construidas se pueden
quitar del proyecto usando el icono Remove File from Project de la barra de herramientas, y
seleccionando la unidad que contiene el formulario a eliminar.
Ejemplo 104.- Múltiples ventanas
Vamos a realizar una aplicación que contenga en la ventana principal los siguientes
componentes: BitBtn, SpeedButton, MaskEdit y ComboBox. Respondiendo a distintos eventos se
deben mostrar ventanas para cada componentes bien con Show o bien con ShowModal que expliquen
de forma visible la principal utilidad de cada componente y sus principales propiedades.
Tema 3.2.2.- Componentes en C++ Builder
50
Asignación de memoria
En tiempo de ejecución de un programa toda la información que necesite manipular deberá estar, en un
momento u otro, en la memoria RAM del ordenador. Sabemos que la memoria se divide en celdas de 8
bits (1 byte) y que a cada una de las cuales le corresponde una dirección.
Ejemplo 105.- Direcciones de memoria.
Realizar una serie de declaraciones de variables y punteros para posteriormente mostrar el valor
de dichas variables y su correspondiente dirección de memoria utilizando para ello componentes
Label.
Tiempo de ejecución
Tiempo de diseño
Tema 3.2.2.- Componentes en C++ Builder
51
Asignación de memoria
Operadores new y delete
Inicialmente, un puntero no apunta a ningún sitio y, para poder usarlo, tendremos que asignarle un
bloque de memoria y obtener su dirección. La cantidad de memoria asignada puede determinarlo el
tipo propio del puntero, que se indica detrás de new, encargándose este de localizar un bloque de
memoria adecuado en tamaño, reservarlo para el programa, almacenar la dirección del puntero y
permitirnos el acceso al valor apuntado por él.
A diferencia de la asignación de memoria estática, la memoria asignada por new está libre al comienzo
del programa reservándose solamente cuando se llama a este operador. Cuando la memoria asignada
con new no nos sea útil tendremos que liberarla, ya que a diferencia de lo que ocurre con una variable,
la liberación no es automática. Para liberar la memoria se emplea el operador delete, al que pasaremos
como parámetro el puntero que contiene la dirección de memoria del bloque a liberar y que es
habitualmente el mismo que el de new. Un código cómo el siguiente origina el resultado que vemos.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
int *Pnumero;
Pnumero = new int;
Edit1->Text= AnsiString(*Pnumero);
*Pnumero = 125;
Edit2->Text = AnsiString(*Pnumero);
delete Pnumero;
}
Cuando asignamos memoria con el operador new es posible especificar un valor inicial dándolo entre
paréntesis detrás del tipo, por ejemplo Pnumero = new int(125) asigna memoria e inicializa.
A veces es necesario asignar memoria no solamente para un número o un carácter, lo que podemos
hacer es especificar el tamaño en el tipo de puntero. Supongamos por ejemplo que queremos reservar
memoria para almacenar 25000 enteros. Es evidente que no vamos a crear 25000 identificadores,
aunque si podríamos tener como recurso crear una matriz con 25000 elementos.
Tema 3.2.2.- Componentes en C++ Builder
52
Asignación de memoria
Operadores new y delete
La solución de la matriz solamente es valida si se conoce de antemano el número exacto de elementos,
porque si dicho número se determina externamente, será difícil crear una matriz del tamaño adecuado
sin que resulte, a veces pequeña, o a veces grande, desperdiciando memoria.
Para este tipo de casos es posible asignar un bloque de memoria del tamaño que nosotros deseemos
mediante los operadores new y delete, indicando dicho tamaño entre corchetes. Al utilizar delete
dispondremos detrás del operador unos corchetes vacíos, indicando que lo que se libera es una matriz.
Ejemplo 106.- Punteros y matrices
Ejemplo en el que empleamos la asignación de memoria dinámica mediante matrices,
inicializamos los elementos y mostramos resultados tanto de direcciones de memoria como del
contenido de las mismas. Diseñamos un formulario con un aspecto como el de la figura:
Tema 3.2.2.- Componentes en C++ Builder
53
Asignación de memoria
Ejemplo 106.- Punteros y matrices
El código es:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int *PunteroNumero; //Puntero a entero
PunteroNumero = new int[5]; //Asignamos memoria para 5 int
//Inicializamos los 5 elementos
PunteroNumero[0] = 100;
PunteroNumero[1] = 200;
PunteroNumero[2] = 300;
PunteroNumero[3] = 400;
PunteroNumero[4] = 500;
//Mostramos en los Edit el contenido y la dirección de memoria
Edit1->Text = AnsiString(PunteroNumero[0]);
Edit2->Text = AnsiString(PunteroNumero[1]);
Edit3->Text = AnsiString(PunteroNumero[2]);
Edit4->Text = AnsiString(PunteroNumero[3]);
Edit5->Text = AnsiString(PunteroNumero[4]);
Edit6->Text = AnsiString((unsigned int) &PunteroNumero[0]);
Edit7->Text = AnsiString((unsigned int) &PunteroNumero[1]);
Edit8->Text = AnsiString((unsigned int) &PunteroNumero[2]);
Edit9->Text = AnsiString((unsigned int) &PunteroNumero[3]);
Edit10->Text = AnsiString((unsigned int) &PunteroNumero[4]);
delete [] PunteroNumero; //Liberamos la memoria asignada
}
Tema 3.2.2.- Componentes en C++ Builder
54
Componentes
Ejemplo 107.- Sentencias if anidadas, ¿Cuál es el menor de tres números? Con componentes
Sobre un formulario vamos a situar dos componentes GroupBox de la pestaña Standard, a uno de
ellos le vamos a llamar Entrada de datos y al otro El menor es. Sobre el primero situamos tres
componentes Label y tres Edit (cambiando la propiedad name como A, B y C respectivamente), y sobre
el segundo un componente Edit con la propiedad name establecida a Menor, además de un BitBtn en el
que seleccionamos bkOK para la propiedad Kind. El aspecto inicial del proyecto lo vemos en la figura
siguiente:
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
float datoA, datoB, datoC, Resultado;
datoA = StrToFloat(A->Text);
datoB = StrToFloat(B->Text);
datoC = StrToFloat(C->Text);
if (datoA < datoB)
if (datoA < datoC)
Resultado = datoA;
else
Resultado = datoC;
else
if (datoB < datoC)
Resultado = datoB;
else
Resultado = datoC;
Menor->Text = FloatToStr(Resultado);
}
Tema 3.2.2.- Componentes en C++ Builder
55
Componentes
CheckBox
Este componente permite al usuario seleccionar una opción o tomar una decisión directamente en
pantalla, es decir en tiempo de ejecución. Es en la propiedad Text del componente donde se debe
escribir el sentido que queremos dar a la selección.
Ejemplo 108.- Decisiones con CheckBox y componente SpeedButton
Vamos a crear un nuevo proyecto y sobre el formulario principal situamos cuatro componentes
SpeedButton (pestaña Additional) y cuatro componentes CheckBox (pestaña Standard). Distribuimos y
modificamos la propiedad Caption de forma que quede algo similar a la figura siguiente. Hacemos
doble clic sobre cada uno de los botones e incluimos el siguiente código:
SpeedButton1
CheckBox1->Checked=true;
CheckBox2->Checked=false;
CheckBox3->Checked=false;
CheckBox4->Checked=false;
SpeedButton2
CheckBox2->Checked=true;
CheckBox1->Checked=false;
CheckBox3->Checked=false;
CheckBox4->Checked=false;
SpeedButton3
CheckBox3->Checked=true;
CheckBox1->Checked=false;
CheckBox2->Checked=false;
CheckBox4->Checked=false;
SpeedButton4
CheckBox4->Checked=true;
CheckBox1->Checked=false;
CheckBox2->Checked=false;
CheckBox3->Checked=false;
Hemos utilizado la propiedad booleana Checked de los componentes CheckBox para hacer que trabaje
con una sola selección.
Naturalmente los CheckBox pueden seleccionarse todos, aunque en el programa del ejemplo no
parezca lo más apropiado.
Tema 3.2.2.- Componentes en C++ Builder
56
Componentes
RadioButton y RadioGroup
El componente RadioButton se utiliza para presentar al usuario un conjunto de opciones mutuamente
excluyentes entre si, es decir si el usuario selecciona un componente RadioButton todos los demás
componentes RadioButton en el formulario, se desmarcan o deseleccionan solos.
En la propiedad Caption se pone el texto que identifica el propósito del botón y su propiedad Checked
refleja el cambio (True o False). También su evento onclick se activa automáticamente cada vez que el
usuario selecciona el RadioButton.
La situación de que sean excluyentes entre si deberá resolverse por parte del programador, es decir si
se supone un programa donde el usuario debe seleccionar uno de entre dos sexos y uno de entre
cinco municipios, en este caso se ocupan ocho RadioButton, pero como todos son mutuamente
excluyentes entre si, cuando el usuario seleccione uno de ellos, todos los demás se desmarcaran
automáticamente. Para resolver este problema se deberán usar componentes de agrupamiento, como
son el componente Panel y el componente GroupBox. Es decir se deberán encerrar en su propio panel
o GroupBox todos los RadioButton lógicos, es decir en un Panel los de sexo, en otro Panel los de
municipios, etc. De esta manera C++Builder los evalúa por separado y se puede tener seleccionado un
RadioButton en cada Panel. En la figura vemos un ejemplo de lo dicho:
Tema 3.2.2.- Componentes en C++ Builder
57
Componentes
RadioButton y RadioGroup
El componente RadioGroup es un componente especializado en la agrupación de RadioButton. Un
componente u objeto RadioGroup es una caja especial que solo contiene componentes RadioButton,
también cuando el usuario marca o selecciona uno de ellos, todos los demás se desmarcan o
deseleccionan.
Para añadir los RadioButton al componente RadioGroup debemos editar la propiedad Items en el
Inspector de Objetos, que nos muestra el minieditor de strings. Debemos recordar que cada línea en el
editor corresponderá a un RadioButton dentro del RadioGroup.
Para procesar o programar un determinado RadioButton usareremos la propiedad ItemIndex que queda
cargada con el numero de RadioButton seleccionado por el usuario. Por ejemplo:
if(Form1->RadioGroup1->ItemIndex==4)
{
código a ejecutar si el usuario selecciona
el RadioButton4 del RadioGroup1
};
También se pueden desplegar los botones en una o más columnas, usando la propiedad Columns en el
Inspector de Objetos, para indicarle cuantas columnas de RadioButton se quieren manejar.
El ejemplo anterior resuelto con este componente podría tener un aspecto como el siguiente:
Tema 3.2.2.- Componentes en C++ Builder
58
Componentes
ListBox
Componente que permite procesar un conjunto de elementos de tipo string. Se puede añadir, eliminar e
insertar ítems en la lista usando los métodos Add, Delete e Insert respectivamente de la propiedad
Items. La propiedad Columns permite que ListBox tenga varias columnas y los items se pueden
clasificar u ordenar usando la propiedad Sorted. Las propiedades MultiSelect y ExtendedSelect
permiten al usuario hacer selecciones múltiples. Para determinar que ítem en particular esta
seleccionado debemos validar la propiedad Selected y para conocer cuantos ítems se han
seleccionado consultar los valores de la propiedad SelCount. La propiedad ItemIndex se utiliza para
seleccionar la posición o índice de un ítem o elemento en la lista. La propiedad Style establece los
estilos de ListBox, que son: lbStandard; LbOwnerDrawFixed; LbOwnerDrawVariable; LbVirtual y
LbVirtualOwnerDraw.
Ejemplo 109.- Números, su cuadrado y su raíz cuadrada.
Vamos
a
desplegar
los
números
enteros
comprendidos entre 15 y 25, su cuadrado y su raíz
cuadrada utilizando componentes ListBox y su
método Add de la propiedad Items. Para este
problema situaremos sobre el formulario principal
Form1, tres componentes label con su font
seleccionado en color rojo, tres componentes ListBox
y un componente Button que en su evento OnClick
contendrá los bucles o ciclos for y la carga de los
componentes ListBox.
Tema 3.2.2.- Componentes en C++ Builder
59
Componentes
Ejemplo 110.- Tablas de multiplicar.
Vamos a implementar un programa que muestre las tablas de multiplicar hasta el 15 de la forma
en que estamos acostumbrados a verlas. Para ello vamos a emplear dos componentes ya conocidos, el
componente RadioGroup y el componente ListBox. Emplearemos el método Add(valor) en la propiedad
Items de ListBox para cargar todos sus elementos o valores en tiempo de ejecución del programa y la
propiedad ItemIndex del componente RadioGroup; con código asociado al evento OnClick del
elemento RadioGroup y sentencias condicionales y bucles.
Para este problema situaremos sobre el formulario principal Form1 los elementos necesarios para que
el aspecto inicial del formulario en tiempo de diseño es el siguiente:
El código del programa adecuando el resto de ItemIndex podría ser el
siguiente:
void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
int x;
if(Form1->RadioGroup1->ItemIndex==0)
{
ListBox1->Items->Clear();
for (x=0 ; x<=15 ; x++)
{ListBox1->Items->Add(AnsiString("1 x ")+(x)+AnsiString(" = ")+(1*x));};
};
...
Sentencias similares para resto de ItemIndex
...
}
Tema 3.2.2.- Componentes en C++ Builder
60
Componentes
Ejemplo 110.- Tablas de multiplicar.
El programa en ejecución es:
Ejemplo 111.- Más tablas de multiplicar.
Vamos a mejorar el ejemplo anterior permitiendo al usuario entrar el número del que desea
obtener la tabla y el número de items que quiere obtener de la misma. Para ello vamos a emplear el
componente ListBox y el método Add(valor) en la propiedad Items de ListBox para cargar todos sus
elementos o valores en tiempo de ejecución del programa.
Para esto situaremos sobre el formulario principal Form1 los elementos necesarios para que el
aspecto inicial del formulario en tiempo de diseño sea similar al siguiente:
Tema 3.2.2.- Componentes en C++ Builder
61
Componentes
Ejemplo 111.- Más tablas de multiplicar.
Observese el cambio de nombre y de icono en el
formulario.
A continuación vemos el código completo del
programa ya comentado.
void __fastcall TForm1::Button1Click(TObject *Sender)
{
/* Declaramos e inicializamos las variables enteras x, y, z
x será el número del que queremos obtener la tabla
asociado a Edit1 z será el número de items que queramos
obtener asociado a Edit2 y será la variable empleada en
el bucle */
int x=0, y=0, z=0;
ListBox1->Items->Clear();
/* Borramos el contenido de ListBox para cada ejecución
y Cambiamos el contenido de los Edit a entero y
asignamos su valor a la variable correspondiente*/
x = StrToInt(Edit1->Text);
z = StrToInt(Edit2->Text);
// Ejecutamos el bucle hasta alcanzar el número de items indicado por z
while(y<=z)
{
// Añadimos contenido a ListBox
{ListBox1->Items->Add(AnsiString(" ")+ (x)+AnsiString(" x ")+(y)+AnsiString(" = ")+(x*y));};
y++;
};
}
Tema 3.2.2.- Componentes en C++ Builder
62
Componentes
Ejemplo 111.- Más tablas de multiplicar.
void __fastcall TForm1::FormCreate(TObject *Sender)
{
/* Asociado al evento OnCreate del Form borramos el contenido de los Edit*/
Edit1->Text="";
Edit2->Text="";
}
//--------------------------------------------------------------------------void __fastcall TForm1::Edit1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
/* Establecemos el foco en Edit1 asociado al evento OnMouseMove */
Edit1->SetFocus();
}
//---------------------------------------------------------------------------
Tema 3.2.2.- Componentes en C++ Builder
63
Componentes
Trabajo con componentes Edit, Buttom y Label
Edit
La principal finalidad de un Edit es permitir la entrada de un texto por parte del usuario que se almacena
en su propiedad Text, a la que podemos dar un valor inicial en tiempo de diseño. Este componente no
cuenta con la propiedad Caption, por lo que se suele disponer una etiqueta de texto adjunta que sirve
como título.
Existe un componente en la pestaña Additional que se compone de un Label y de un Edit, el LabeledEdit,
que resulta sencillo de manejar cuando se conocen los dos componentes de forma individual.
Cuando en tiempo de ejecución el usuario modifica el contenido de un Edit, su propiedad Modified se
establece como true. Nosotros podemos, mediante código, comprobar el valor de esta propiedad y, en
caso de que proceda, recuperar la entrada realizada por el usuario leyendo la propiedad Text.
Longitud del Texto
Por defecto el control Edit no pone ningún límite a la cantidad de texto que el usuario puede introducir y,
en caso de que sea necesario, desplazará el contenido actual a medida que se introducen nuevos
caracteres. Si es necesario, podemos limitar el número de caracteres que es posible introducir mediante
la propiedad MaxLength. El valor 0 indica que no hay un límite establecido y cualquier otro número entero
fija la longitud máxima de la propiedad Text.
Selección de texto
Mientras se edita el contenido de un control Edit, el usuario puede marcar una porción del texto, mediante
la combinación de la tecla Shitf y los cursores o bien con el ratón, con el fin de realizar alguna operación
que le afecte, como puede ser eliminarlo o copiarlo al portapapeles.
En cualquier momento podemos saber qué texto es el que hay seleccionado en el control, para lo que
disponemos de las propiedades SelStart, SelLength y SelText. La primera contiene el carácter a partir del
cual se ha seleccionado, sabiendo que el primero de los existentes es el carácter 0. La segunda propiedad
contiene el número de caracteres que hay marcados y la tercera contiene el texto.
El valor de estas propiedades también puede ser establecido por el código de nuestro programa,
seleccionando automáticamente el texto que nos interese. Si deseamos marcar todo el texto contenido en
el control podemos realizar una simple llamada al método SelectAll().
Tema 3.2.2.- Componentes en C++ Builder
64
Componentes
Trabajo con componentes Edit, Buttom y Label
Las operaciones de copiar, cortar y pegar con el portapapeles (clipboard), pueden ser también
realizadas mediante código usando los métodos adecuados.
Método ClearSelection() elimina el texto que hay seleccionado.
Método CopyToClipboard() copia el texto al portapapeles.
Método CutToClipboard() copia el texto al portapapeles y lo elimina del campo de edición.
PasteFromClipboard() permite recuperar el texto que hay en el portapapeles insertándolo en Edit en la
posición actual del cursor.
Texto de sólo lectura y oculto
Si lo que queremos es solamente mostrar un valor en un componente Edit e impedir que el usuario
pueda modificarlo basta con establecer la propiedad ReadOnly a true. Si lo que queremos es que al
solicitar cualquier tipo de dato éste no sea visible por terceras personas (caso típico de las
contraseñas o password) podemos conseguirlo con la propiedad PasswordChar haciendo que el Edit
vaya representando cada uno de los caracteres introducidos mediante un cierto símbolo, como puede
ser un asterisco o el carácter que asignemos a la propiedad.
Controles de entrada
Hay ocasiones en las que es necesario garantizar que todas las letras sean facilitadas en mayúsculas o
en minúsculas con el fin de evitar posteriores fallos de comparación. Mediante la propiedad CharCase
podemos forzar estas situaciones asignándole los valores ecNormal, ecUpperCase o ecLowerCase.
Buttom
Para dotar a un botón de una tecla de acceso rápido utilizable con la tecla Alt (Alternate) basta con
anteponer el carácter & a la letra que queremos que lo active, que aparecerá subrayada.
Es normal que en un formulario existan varios botones pudiendo dos de ellos ser activados pulsando la
tecla Enter o la tecla Esc. Si la propiedad Default tiene el valor true el botón actuará como botón por
defecto, es decir, que se activará cuando se pulse la tecla Enter. Si Cancel está a true, el botón será el
botón de cancelación o tecla Esc.
Podemos pulsar el botón utilizando el cursor del ratón, la tecla de acceso rápido, desplazándonos hasta él
con la tecla Tab y pulsando la barra espaciadora, con la tecla Enter si es el botón por defecto, o con la
tecla Esc si es el botón de cancelación.
Tema 3.2.2.- Componentes en C++ Builder
65
Componentes
Trabajo con componentes Edit, Buttom y Label
Label
Una etiqueta Label es un componente que presenta un texto en el formulario (propiedad Caption) pero
que no puede tomar el foco de entrada ni podemos acceder a él con la tecla Tab. Sólo recibe eventos de
ratón.
Propiedad
AutoSize
Alignment
Uso
Valores
El tamaño de la etiqueta se ajusta automáticamente al contenido de ésta o no.
true o false
Alineación del texto
Izquierda: taLeftJustify
Derecha: taRightJustify
Centro: taCenter
Tiene sentido cuando la etiqueta se usa como título de otro control. Sirve para
Nombre del control que
FocusControl que la etiqueta de texto sepa a qué control debe pasar el foco de entrada cuando
recibe el foco.
se pulse la tecla de acceso rápido (&).
Ejemplo 112.- Componentes Edit, Buttom y Label
Resolveremos el ejemplo paso a paso
Por un lado vamos a colocar sobre un Form con Caption = Trabajo con componentes Edit, Buttom
y Label un componente Panel del que eliminamos el Caption y establecemos propiedad Color en
clAqua y Width = 480.
Insertamos en el Panel una etiqueta estableciendo a false la propiedad AutoSize y
redimensionamos su tamaño de forma que ocupe prácticamente todo el ancho del panel. Asignamos a
la etiqueta el Color clYellow y comprobamos que la propiedad Alignment tiene el valor taLeftJustify. El
valor de Caption va a ser Esto es una etiqueta.
Insertar en panel tres botones de la forma siguiente:
Buttom1: Caption = Izquierda Buttom2 : Caption = Centro y Buttom3: Caption = Derecha
Establecemos a true propiedad Default de Buttom1 (Izquierda) y a la propiedad Cancel de Buttom3
(Derecha).
Generamos el evento OnClick de Buttom1 y asignamos, mediante código, el valor taLeftJustify a la
propiedad Alignment de la etiqueta. Repetimos para los otros botones asignando los valores taCenter y
taRightJustify.
Tema 3.2.2.- Componentes en C++ Builder
66
Componentes
Trabajo con componentes Edit, Buttom y Label
Ejemplo 112.- Componentes Edit, Buttom y Label
Modificar lo necesario para permitir el acceso mediante teclas rápidas a cada uno de los botones
y establecer el color de fondo de la etiqueta al que actualmente tenga el panel cuando el ratón esté
situado sobre la misma.
Insertamos en el formulario tres Edit, que estarán encabezados por tres Label y tres botones para
que tenga el aspecto siguiente:
El primer Edit, que recibirá el foco desde su etiqueta (propiedad FocusControl) lo utilizaremos
para comprobar el funcionamiento de las propiedades MaxLength, a la que asignaremos el valor 10, y
PasswordChar, a la que asignaremos el valor *.
El segundo Edit, que recibirá el foco desde su Label lo usaremos para ver cómo podemos
controlar la entrada de caracteres, permitiendo tan sólo la introducción de dígitos numéricos. Para ello
vamos a generar el siguiente gestor de eventos OnKeyPress.
Tema 3.2.2.- Componentes en C++ Builder
67
Componentes
Trabajo con componentes Edit, Buttom y Label
Ejemplo 112.- Componentes Edit, Buttom y Label
void __fastcall TForm1::Edit2KeyPress(TObject *Sender, char &Key)
{
if ((Key < '0' || Key > '9') && Key != 8) Key=0;
/* Se comprueba que el carácter sea un dígito o la tecla de borrado.
Los caracteres se encierran entre comillas simples porque estamos comparando un carácter tipo char.
Asignar a Key el valor 0 es anular la pulsación. */
}
El último Edit (recibe el foco de su Label) lo vamos a usar para probar los métodos de copiar,
borrar y pegar el texto seleccionado. Será al pulsar cualquiera de los tres botones que hemos
dispuesto debajo cuando se realice la acción de copiado, borrado o pegado, gracias al código que
asociaremos al evento OnClick de cada uno de los botones de la forma que se muestra a continuación.
void __fastcall TForm1::Button4Click(TObject *Sender)
{
Edit3->SelectAll();
Edit3->CopyToClipboard();
Edit3->SetFocus();
}
void __fastcall TForm1::Button5Click(TObject *Sender)
{
Edit3->ClearSelection();
Edit3->SetFocus();
}
void __fastcall TForm1::Button6Click(TObject *Sender)
{
Edit3->PasteFromClipboard();
Edit3->SetFocus();
}
Tema 3.2.2.- Componentes en C++ Builder
68
Componentes
Tipos de propiedades
Las
propiedades
de
los
componentes de la VCL tienen
asignado un tipo de dato que
determina los valores que esta
puede tomar. Hay propiedades
de tipo bool (Visible), otras de
tipo string (Caption) y otras de
tipo enumerado (BorderIcons)
que solamente pueden tomar
valores de una lista prefijada.
A continuación vemos lo que
muestra
la
ayuda
de
BorderIcons.
Indica que la propiedad
BorderIcons de un formulario
es del tipo TborderIcon es de
tipo enumerado, y que, por
tanto, sólo puede tomar los
valores preestablecidos.
Tema 3.2.2.- Componentes en C++ Builder
69
Componentes
Tipos de propiedades
Ejemplo 113.- Propiedad BorderIcons
Realizar una aplicación para trabajar con esta propiedad en
tiempo de ejecución.
Partimos de un diseño similar al siguiente, en el que al botón Salir le
hemos establecido su propiedad Visible a false.
Asociamos a los botones de minimizar el código siguiente.
Para botón Desactivar
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TBorderIcons VarBorderIcon = BorderIcons;
VarBorderIcon >> biMinimize;
BorderIcons = VarBorderIcon;
}
Para botón Activar
void __fastcall TForm1::Button2Click(TObject *Sender)
{
TBorderIcons VarBorderIcon = BorderIcons;
VarBorderIcon << biMinimize;
BorderIcons = VarBorderIcon;
}
El resto de botones es similar trabajando con el valor enumerado correspondiente.
Tema 3.2.2.- Componentes en C++ Builder
70
Componentes
Trabajo con componentes Memo, CheckBox, RadioButton y RadioGroup
Memo
Ya hemos visto el uso del componente Edit para solicitar al usuario alguna entrada, pero esta no puede
tener mas que una línea. Cuando necesitemos una entrada de texto que ocupe varias líneas podemos
usar un componente Memo que posee muchas propiedades de las vistas para el Edit (ReadOnly,
MaxLength, Text, ...), así como con los métodos relacionados con las operaciones del portapapeles.
Un Memo puede tener barras de desplazamiento o ScrollBars, permitiendo trabajar con líneas más
largas que el espacio horizontal disponible y con más líneas de las que es posible mostrar de forma
simultánea. La propiedad de tipo enumerado TScrollBars permite el uso de estas barras de
desplazamiento. Esta propiedad puede tomar los valores:
0 ssNone
//Ninguna
1 ssVertical
//Sólo la vertical
2 ssHorizontal //Sólo la horizontal
3 ssBoth
//Las dos
El texto que contiene un Memo es accesible mediante la propiedad Text, al igual que en un Edit. Pero
resulta más útil y conveniente acceder a ese texto línea a línea, para lo que el componente dispone de
la propiedad Lines que es de tipo Strings.
Sus dos métodos más interesantes tienen relación con guardar o recuperar el texto en un archivo en
disco y son SaveToFile() y LoadFromFile(), que tienen como único parámetro el nombre del fichero
donde se va a guardar o del que se va a recuperar la información del Memo.
Otra propiedad muy interesante es Count con la que podemos averiguar en cada momento cuántas
líneas tiene simplemente haciendo: Memo1->Lines->Count.
Un componente Memo tiene la posibilidad de trabajar con las teclas Enter y Tab como parte de la
edición del texto siempre que él esté activo. Pero, por defecto, estas teclas tienen su función propia en
un formulario. Para que al pulsar la tecla Enter el componente Memo la reconozca como salto de línea y
no como activación de, por ejemplo, el botón por defecto, debemos asignar el valor true a la propiedad
WantReturns. Lo mismo ocurre con la propiedad WantTabs, que si está activada permitirá insertar
tabulaciones en el texto en lugar de pasar el foco de entrada al siguiente componente del formulario.
Tema 3.2.2.- Componentes en C++ Builder
71
Componentes
Trabajo con componentes Memo, CheckBox, RadioButton y RadioGroup
CheckBox
Este componente permite mostrar y seleccionar información de tipo bool, representándose los dos
estados posibles visualmente mediante una casilla, que puede contener o no en su interior una marca.
La propiedad Checked nos permite saber el estado actual del componente y, como no, modificarlo;
estando a true cuando esté marcado y a false en caso contrario.
Podemos poner todos los componentes CheckBox que necesitemos en un formulario, no afecto el
hecho de que alguno de ellos esté activo al resto, es decir no son opciones excluyente entre sí. Para
que varias opciones sean excluyentes se usan componentes RadioButton.
Lo más común es agrupar los componentes CheckBox en un contenedor denominado GroupBox que
tiene la posibilidad de asignar un título común a los componentes CheckBox que lo componen.
RadioButton y RadioGroup
El componente RadioButton también cuenta con una propiedad Checked en la que se almacena su
estado. Si tenemos que usar varios RadioButton en un formulario y que se destinen a solicitar datos
diferentes que tengan, a su vez, opciones exclusivas entre sí, debemos usar componentes RadioGroup.
Para establecer las opciones de un RadioGroup tendremos que editar el contenido de la propiedad
Items, que es de tipo Strings. En modo diseño haremos doble clic sobre la propiedad Items para abrir el
editor específico, añadiendo los títulos de las opciones que deseemos mostrar. En tiempo de ejecución
podremos usar los métodos Add(), Append(), Insert() y Clear() para añadir o eliminar elementos. Los
elementos RadioButton existentes en un RadioGroup se numeran con un índice que comienza en 0.
Este índice nos servirá para saber qué opción es la que está activa o bien para establecerla, mediante
la propiedad ItemIndex. De esta forma no es necesario comprobar la propiedad Checked de cada uno
de los RadioButton que aparece en el RadioGroup.
Tema 3.2.2.- Componentes en C++ Builder
72
Componentes
Trabajo con componentes Memo, CheckBox, RadioButton y RadioGroup
Ejemplo 114.- Trabajo con componentes Memo, CheckBox, RadioButton y RadioGroup
Vamos a realizar una aplicación para mostrar el uso de estos componentes, sus propiedades y
los métodos descritos en este apartado.
Comenzamos una nueva aplicación e incluimos en el Form los siguientes componentes: Tres Label, un
Memo, un GroupBox, dos CheckBox dentro de un GroupBox, un RadioGroup y dos Button, de forma
que inicialmente tengamos un aspecto como el que vemos a continuación:
Continuamos dando los pasos necesarios para conseguir como código fuente del Unit asociado al
Form el que vemos seguidamente:
Tema 3.2.2.- Componentes en C++ Builder
73
Componentes
Tema 3.2.2.- Componentes en C++ Builder
74
Componentes
Tema 3.2.2.- Componentes en C++ Builder
75
Componentes
Tema 3.2.2.- Componentes en C++ Builder
76
Componentes
Trabajo con ListBox
Se trata de un componente que nos permite mostrar listas de elementos de las que es posible
seleccionar uno o varios. Tiene un funcionamiento parecido al del RadioGroup, aunque visualmente su
aspecto es diferente. Los elementos del ListBox están contenidos en la propiedad Items, que, como
sabemos, es un objeto de tipo Strings. En tiempo de diseño podemos usar el editor de código asociado
para incluir los elementos que queramos en la lista simplemente haciendo doble clic sobre la propiedad
Items. En cambio, en tiempo de ejecución, podemos usar los métodos siguientes:
Método
Descripción
Add()
Una cadena de texto es el parámetro que la añade como un nuevo elemento al final de la lista, salvo que
la propiedad Sorted del ListBox esté a true, en cuyo caso se insertará en la posición que le corresponda.
Insert()
Toma dos parámetros, de los que el primero es la posición en la que se desea insertar el elemento y el
segundo el texto a añadir.
Delete()
Método que nos permite eliminar el elemento de la lista del que facilitamos su índice.
Clear()
Elimina todas las cadenas existentes sin necesidad de suministrarle parámetros.
IndexOf()
Move()
Devuelve el índice de la cadena dada como parámetro. Si retorna -1 la cadena no se encuentra.
Damos el índice en que se encuentra actualmente y el índice correspondiente al punto al que se desea
mover.
Exchange()
Similar a Move() lo que hace es intercambiar las posiciones de los elementos correspondientes.
SaveToFile()
Guarda el contenido en un archivo en disco, debiendo facilitar el nombre.
LoadFromFile() Recupera la lista de elementos de un archivo cuyo nombre se facilita como parámetro.
La propiedad ItemIndex del ListBox indica en cada momento qué elemento hay seleccionado. Un valor 1 indica que no hay ninguno seleccionado. Cuando contiene más elementos de los que puede mostrar
de forma simultánea aparece una barra de desplazamiento vertical.
Tema 3.2.2.- Componentes en C++ Builder
77
Componentes
Trabajo con ListBox
Ejemplo 115.- Trabajo con ListBox
Realizar un programa que nos permitirá añadir elementos a un ListBox en tiempo de ejecución
con el texto que se facilite en un Edit. También se podrá añadir antes y después de la selección,
eliminar el elemento seleccionado o eliminar todos los elementos del ListBox. Mediante un
componente CheckBox habilitaremos la ordenación de los elementos.
Comenzamos por diseñar un formulario como el siguiente:
Al botón Añadir le establecemos la propiedad Default a true para permitir la inserción mediante la tecla
Enter del texto introducido en el Edit y al botón Borrar le establecemos la propiedad Enabled a false
para que este no esté activo si no tenemos ningún elemento seleccionado.
El resto del proceso es ir creando los gestores de eventos que vemos seguidamente con el código que
debemos insertar en los mismos.
Tema 3.2.2.- Componentes en C++ Builder
78
Componentes
Trabajo con ListBox
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ListBox1->Items->Add(Edit1->Text);
Edit1->SelectAll(); // Selecciona el contenido del Edit
}
//--------------------------------------------------------------------------void __fastcall TForm1::ListBox1Click(TObject *Sender)
{
/* Activación o desactivación del botón borrar según haya o no
seleccionado algún elemento del ListBox */
Button6->Enabled=ListBox1->ItemIndex != -1;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button6Click(TObject *Sender)
{
// Eliminamos el texto seleccionado
ListBox1->Items->Delete(ListBox1->ItemIndex);
// Desactivamos el botón de Eliminar
Button6->Enabled=false;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button7Click(TObject *Sender)
{
// Borramos todo
ListBox1->Items->Clear();
}
//--------------------------------------------------------------------------Tema 3.2.2.- Componentes en C++ Builder
79
Componentes
Trabajo con ListBox
void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
// Activamos o desactivamos la ordenación
ListBox1->Sorted=CheckBox1->Checked;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button2Click(TObject *Sender)
{
// Insertamos delante del elemento seleccionado
ListBox1->Items->Insert(ListBox1->ItemIndex,Edit1->Text);
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button3Click(TObject *Sender)
{
// Insertamos detrás del elemento seleccionado
ListBox1->Items->Insert(ListBox1->ItemIndex+1,Edit1->Text);
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button4Click(TObject *Sender)
{
// Movemos arriba la selección
if (ListBox1->ItemIndex != -1)
ListBox1->Items->Move(ListBox1->ItemIndex,ListBox1->ItemIndex-1);
else
ShowMessage("No hay nada seleccionado");
}
//--------------------------------------------------------------------------Tema 3.2.2.- Componentes en C++ Builder
80
Componentes
Trabajo con ListBox
void __fastcall TForm1::Button5Click(TObject *Sender)
{
// Cambiamos la selección con el primer elemento de la lista
if (ListBox1->ItemIndex != -1)
ListBox1->Items->Exchange(ListBox1->ItemIndex,0);
else
ShowMessage("No hay nada seleccionado");
}
Trabajo con ComboBox o listas combinadas
En el apartado anterior hemos usado un ListBox para guardar una lista de elementos procedentes de
un Edit. El componente ComboBox es la unión de un Edit y un ListBox incorporando las funciones de
ambos componentes y, por tanto, las propiedades Text, MaxLenggth, Items, ItemIndex, etc. El
funcionamiento y aspecto de un ComboBox dependen de su propiedad Style que es de tipo
TComboBoxStyle, pudiendo tomar, entre otros, los valores siguientes:
Valor
Descripción
csDropDown
Se trata del estilo establecido por defecto y presenta un Edit en el que es posible introducir texto. El
botón del extremos derecho despliega una lista con los elementos que contiene.
csSimple
El ComboBox aparece como un Edit sin botón ni lista desplegable adjunta. Para recorrer los elementos
de ésta debemos usar las teclas de cursor arriba y abajo.
csDropDownList
Con este valor se permite al usuario seleccionar uno de los valores de la lista pero no puede introducir
texto alguno.
Ejemplo 116.- Trabajo con ComboBox
Realizar un programa para controlar la propiedad Style de un ComboBox mediante las tres
opciones suministradas por un componente RadioGroup.
Tema 3.2.2.- Componentes en C++ Builder
81
Componentes
Trabajo con ListBox
Antes de comenzar con el ejemplo vamos a describir el operador static_cast que se usa en las
propiedades tipo enumerado para referirse a los valores con su nombre mediante una conversión de la
posición que ocupa el valor dentro de los posibles (comenzando por la posición 0). EstSu sintaxis
básica es:
static_cast <tipo_enumerado> (posición del valor)
Diseñamos un formulario similar al siguiente:
Situamos un ComboBox al que establecemos como valor csDropDown para la propiedad Style y
eliminamos el contenido de su propiedad Text.
También situamos un RadioGroup con las tres opciones que vemos y que nos van a permitir cambiar el
estilo del ComboBox en tiempo de ejecución.
Veamos en dos fases el código necesario para nuestros propósitos:
Por un lado deberemos controlar cada pulsación de tecla sobre el ComboBox, mediante el evento
OnKeyPress, para que en el momento en que se detecte la pulsación de la tecla Enter se almacene el
texto en el ComboBox pero ignorando la pulsación de dicha tecla. El código que deberemos escribir es
el siguiente:
Tema 3.2.2.- Componentes en C++ Builder
82
Componentes
Trabajo con ListBox
void __fastcall TForm1::ComboBox1KeyPress(TObject *Sender, char &Key)
{
if (Key == 13) // Tecla Enter
{
ComboBox1->Items->Add(ComboBox1->Text);
ComboBox1->SelectAll();
Key=0;
}
}
Por otro lado debemos hacer la propiedad ItemIndex=0 para el componente RadioGroup y controlar su
evento OnClick para establecer el estilo adecuado para el ComboBox según la opción que
seleccionemos. Esta asignación se realizará de forma directa llevando a cabo una conversión de tipo
de la forma siguiente:
void __fastcall TForm1::RadioGroup1Click(TObject *Sender)
{
ComboBox1->Style= static_cast <TcomboBoxStyle> (RadioGroup1->ItemIndex);
}
Ejemplo 117.- Raíces con funciones
Vamos a establecer una función con asignación de un valor por defecto a uno de sus parámetros
con el fin de que, por defecto, calcule la raíz cuadrada del número especificado.
Recordemos que si en la declaración de una función asignamos valores por defecto a los parámetros
no será indispensable facilitar el valor en la llamada a la función en aquel o aquellos que hayamos
especificado por defecto. Para asignar un valor por defecto a un parámetro basta con utilizar el
operador de asignación detrás del nombre del parámetro facilitando a continuación el valor, todo ello
naturalmente en la cabecera de la función, entre los paréntesis, y estando de acuerdo el valor con el
tipo especificado.
Tema 3.2.2.- Componentes en C++ Builder
83
Componentes
Ejemplo 117.- Raíces con funciones
Comenzamos por situar un formulario con las siguientes propiedades:
Height = 150 y Width = 350
Caption = Raíces
BorderIcon: biMinimize = false, biMaximize = false y biSystemMenu = false. Esto hará que la
ventana no presente los iconos ni de maximizar, ni de minimizar ni de cerrar. Tampoco presentará el
icono ni el menú contextual asociado.
BorderStyle = bsSingle. Hará que se presente un borde de una línea sencilla y el tamaño de la
ventana no será escalable.
Position = poScreenCenter. La ventana de la aplicación aparecerá centrada en la pantalla.
Sobre el formulario situamos:
Un componente ListBox con Height = 70 y Width = 330
Un botón con Caption = &Salir.
Ambos componentes los alineamos Center in windows.
El aspecto en tiempo de diseño será:
Tema 3.2.2.- Componentes en C++ Builder
84
Componentes
Ejemplo 117.- Raíces con funciones
El código completo del programa es:
#include <vcl.h>
#pragma hdrstop
#include <math.h> //Para usar pow()
#include "Codigo.h"
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//--------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------------------AnsiString AlmacenDatos; /*Declaracion global de un AnsiString para ir guardando los resultados obtenidos con
los datos que se pasen */
//--------------------------------------------------------------------------/* Declaramos la función Raiz con los parámetros:
Argumento de tipo __int64 para trabajo con números grandes
Indice de tipo int con valor por defecto 2 */
void Raiz(__int64 Argumento, int Indice=2)
{
/* En Almacen de Datos vamos guardando las cadenas y los valores pasados o por defecto de los parámetros. El
cálcula de la raiz lo realizamos con la función pow() */
Tema 3.2.2.- Componentes en C++ Builder
85
Componentes
Ejemplo 117.- Raices con funciones
AlmacenDatos = "La raiz de Indice " + AnsiString(Indice) + " del número " + AnsiString(Argumento)+
" es: " + AnsiString(pow(Argumento,1.0/Indice));
}
//MOSTRMOS LOS RESULTADOS ASOCIADOS A: TForm1::FormCreate
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Raiz(16); //Pasamos un parámetro (se calcula la raiz cuadrada)
ListBox1->Items->Add(AlmacenDatos); //Añadimos los resultados
Raiz(27,3); //Pasamos los dos argumentos (se calcula la raiz cúbica)
ListBox1->Items->Add(AlmacenDatos); //Añadimos los resultados
Raiz(30517578125,5); //Pasamos los dos argumentos (se calcula la raiz quinta)
ListBox1->Items->Add(AlmacenDatos); //Añadimos los resultados
Raiz(999,15); //Pasamos los dos argumentos (se calcula la raiz 15)
ListBox1->Items->Add(AlmacenDatos); //Añadimos los resultados
Raiz(3); //Pasamos un parámetro (se calcula de nuevo la raiz cuadrada)
ListBox1->Items->Add(AlmacenDatos); //Añadimos los resultados
}
//--------------------------------------------------------------------------//NECESITAMOS UN BOTON PORQUE HEMOS DESABILITADO LOS ICONOS PARA CERRAR
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Application->Terminate();
}
Tema 3.2.2.- Componentes en C++ Builder
86
Componentes
Trabajo con FormStyle
Las opciones de FormStyle son: fsNormal, fsMDIChild, fsMDIForm y fsStayOnTop y se emplea si
queremos que en una aplicación un formulario contenga a otros. Este tratamiento de formularios se
denomina Multiple Document Interface (Interface de Documento Múltiple) y hace muy fácil este tipo de
aplicaciones.
Valor
fsNormal
Significado
El formulario no es ni ventana MDI padre ni ventana MDI hijo.
fsMDIChild
El formulario es una ventana MDI hijo.
fsMDIForm
El formulario es una ventana MDI padre.
El formulario permanece sobre todo en el escritorio y sobre otros formularios del proyecto, excepto sobre los que
fsStayOnTop también tiene la propiedad FormStyle a fsStayOnTop. Si un formulario fsStayOnTop lanza otro del mismo tipo,
ninguno permanecerá coherentemente sobre el otro.
Si el formulario es el principal su propiedad FormStyle debe ser fsMDIForm. No es aconsejable cambiar
FormStyle en tiempo de ejecución.
Ejemplo 118.- Uso de FormStyle
0.- Se trata de realizar un programa multiventana para trabajar con esta propiedad y aprender su
comportamiento en tiempo de ejecución. Seguimos el siguiente proceso:
1.- Creamos una nueva aplicación con File/New Application y, con el inspector de objetos, cambiamos,
la propiedad FormStyle a fsMDIForm, el Caption a “Formulario Principal”, Height = 200, Widht = 430 y
fijamos Position a poScreenCenter.
2.- Añadimos un segundo formulario al proyecto con File/New Form. A este formulario le cambiamos la
propiedad Caption a “Formulario secundario Hijo” (podemos tener varias ventanas secundarias), la
propiedad FormStyle la cambiamos a la opción fsMDIChild, Height = 100, Widht = 400 y fijamos Position
a poScreenCenter.
3.- Añadimos un tercer formulario al proyecto con File/New Form. A este formulario le cambiamos la
propiedad Caption a “Formulario secundario StayOnTop”, la propiedad FormStyle la cambiamos a la
opción fsStayOnTop, Height = 95, Widht = 360 y fijamos Position a poScreenCenter.
4.- Añadimos un botón y obtenemos una situación similar a:
Tema 3.2.2.- Componentes en C++ Builder
87
Componentes
Trabajo con FormStyle
El formulario hijo solo se puede mover, minimizar
o maximizar dentro del principal en cambio el
StayOnTop se mueve independientemente.
Tema 3.2.2.- Componentes en C++ Builder
88
Componentes
Propiedad Icon
Por defecto, si no se selecciona ninguno, Builder presenta el icono propio de las aplicaciones C++
Builder. Se puede cambiar haciendo doble clic en el botón Load, para seleccionar el archivo del icono
deseado. Esta propiedad busca archivos con extensión .ico. C++ Builder tiene una biblioteca de
archivos .ico en la carpeta:
\\Archivos de programa\Archivos comunes\Borland Shared\Images\Icons\
El compilador dispone de un editor de iconos que se puede seleccionar en el menú principal:
Tools/Image Editor para experimentar con él. En la figura vemos su aspecto con el icono chip cargado.
Tema 3.2.2.- Componentes en C++ Builder
89
Componentes
Propiedad Position
Determina donde se desplegará el formulario en la pantalla del PC en el momento de la ejecución.
Valor
Efecto en tiempo de ejecución
poDesigned
El formulario aparece en tiempo de ejecución con el tamaño y la posición que tenía de
diseño
poDefault
El formulario aparece en una posición de la pantalla con una altura y una anchura
determinadas por Windows. Cada vez que ejecutemos la aplicación, el formulario se
moverá levemente abajo y a la derecha.
El formulario se muestra con el tamaño con que se creó en tiempo del diseño, pero
poDefaultPosOnly Windows elige su posición respecto a la pantalla. Cada vez que ejecutemos la aplicación,
el formulario se moverá levemente abajo y a la derecha.
poDefaultSizeOnly
El formulario aparece en el lugar donde estaba en tiempo de diseño, pero Windows elige
su tamaño.
poScreenCenter
El formulario aparece en el lugar donde estaba en tiempo de diseño, pero posicionado en
el centro de la pantalla.
Propiedad WindowState
Esta propiedad muestra las características del formulario en tiempo de ejecución.
Valor
Efecto en tiempo de ejecución
wsNormal
El formulario aparece de la manera en que se definió en el momento de crearse
(dimensiones y posición).
wsMinimized
El formulario aparece minimizado en pantalla en tiempo de ejecución.
wsMaximized
El formulario aparece maximizado en pantalla en tiempo de ejecución.
Ejemplo 119.- Propiedades y eventos
Se trata de un ejemplo de uso de algunas de las propiedades de las citadas y de algunos eventos
tanto de teclado como de ratón.
Debemos disponer un formulario similar a:
Tema 3.2.2.- Componentes en C++ Builder
90
Componentes
Ejemplo 119.- Propiedades y eventos
Los efectos de los botones Maximizar, Minimizar y Salir los vamos a asociar a los eventos OnClick para
efectuar esas operaciones.
Para botón Maximizar: WindowState=wsMaximized;
Para botón Maximizar: WindowState=wsMinimized;
Para botón Maximizar: Application->Terminate();
El efecto del botón Normal va a ser devolver la ventana a su estado normal asociándolo al evento
OnMouseMove del ratón.
Para botón Normal: WindowState=wsNormal;
Para el botón ¿Mantenemos pulsada una tecla del ratón? y la etiequeta que tiene a la derecha vamos a
trabajar con los eventos OnMouseDown y OnMouseUp de forma que mientras tengamos pulsada la tecla
izquierda del ratón sobre el botón la etiqueta muestre SI y en caso contrario NO.
void __fastcall TForm1::Button5MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
Label1->Caption="SI";
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button5MouseUp(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
Label1->Caption="NO";
Tema 3.2.2.- Componentes en C++ Builder
}
91
Componentes
Ejemplo 119.- Propiedades y eventos
Para el botón Tecla pulsada y su etiqueta de la derecha vamos a generar un evento OnKeyPress de forma que
cuando el botón tenga el foco la etiqueta nos muestre la tecla que hemos pulsado.
void __fastcall TForm1::Button6KeyPress(TObject *Sender, char &Key)
{
char keyString[2];
keyString[0] = Key;
strcpy(&keyString[1], "");
Label2->Caption= keyString;
}
Ahora añadimos un nuevo formulario con un Label y hacemos que tenga algo parecido a:
No debemos olvidar File/Include Unit ... para tener en Unit1 #include "Unit2.h". Para este Form vamos a
generar un evento OnResize al que asociamos el código:
void __fastcall TForm2::FormResize(TObject *Sender)
{
Label1->Left = (ClientWidth/2) - (Label1->Width/2);
Label1->Top = (ClientHeight/2) - (Label1->Height/2);
}
Finalmente para el botón Otro Form generamos su evento OnClick y hacemos que muestre el segundo
formulario de forma modal.
void __fastcall TForm1::Button7Click(TObject *Sender)
{
Form2->ShowModal();
}
Tema 3.2.2.- Componentes en C++ Builder
92
Componentes
Ejemplo 120.- Eventos DragOver y DragDrop
Creamos una aplicación para trabajar con estos eventos y el formulario tendrá un componente
ListBox y tres Label, cada uno con la fuente que se especifica.
Label 1: Britannic Bold - Negrita - Cursiva - 10 Puntos – Azul
Label 2: Arial - Normal - 12 Puntos - Rojo
Label 3: Courier New - Negrita - Subrayado - 8 Puntos - Verde
Para probar el funcionamiento seleccionamos un Label, arrastramos hasta el ListBox y soltamos,
cambiando el texto del mismo al aspecto del Label seleccionado.
El formulario debe tener un aspecto similar a:
La propiedad DragMode de los Label debe ser dmAutomatic de lo que nos aseguramos asociando la
propiedad al evento OnCreate del formulario.
El código del programa es:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Label1->DragMode = dmAutomatic;
Label2->DragMode = dmAutomatic;
Label3->DragMode = dmAutomatic;
}
Tema 3.2.2.- Componentes en C++ Builder
93
Componentes
Ejemplo 120.- Eventos DragOver y DragDrop
void __fastcall TForm1::ListBox1DragOver(TObject *Sender, TObject *Source,
int X, int Y, TDragState State, bool &Accept)
{
Accept = Source->ClassNameIs("TLabel");
}
//--------------------------------------------------------------------------void __fastcall TForm1::ListBox1DragDrop(TObject *Sender, TObject *Source,
int X, int Y)
{
if (Sender->ClassNameIs("TListBox") && Source->ClassNameIs("TLabel"))
{
TListBox *Puntero = (TListBox *)Sender;
Puntero->Font = ((TLabel *)Source)->Font;
Puntero->Color = ((TLabel *)Source)->Color;
}
}
Eventos OnHide y OnPaint. Trabajo con la propiedad Canvas del Form
La propiedad TCanvas de un formulario permite dibujar en su área de cliente. Canvas se usa en el
evento OnPaint del formulario. El método Draw de Canvas tienen una sintaxis como:
Draw(int X, int Y, TGraphic* Grafico);
Dibujándo el gráfico especificado por el parámetro Grafico en el canvas y la localización que indican
las coordenadas X e Y. Tendremos por tanto que facilitar un ámbito global de acceso del tipo:
Graphics::TBitmap *Grafico;
El evento OnHide ocurre cuando el formulario se oculta, es decir cuando su propiedad Visible se pone
en false.
Tema 3.2.2.- Componentes en C++ Builder
94
Componentes
Ejemplo 121.- Eventos OnHide y OnPaint. Trabajo con la propiedad Canvas del Form
Vamos a implementar una aplicación con dos formularios que permita mediante la pulsación de
un botón mostrar el otro formulario dibujando en cada uno de ellos una imagen diferente mediante la
propiedad Canvas del formulario. Debemos también permitir que la aplicación se cierre desde
cualquiera de los formularios.
Comenzamos por construir dos formularios con un Label y un Button con el aspecto que mostramos,
estando los Label con su propiedad Caption vacía y situados a la izquierda de los botones. Ambos
formularios tienen su propiedad Height = 250 y Width a 190 y 240 respectivamente.
El código del primer Form es:
//--------------------------------------------------------------------------#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h" //File/Incude Unit ...
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
Tema 3.2.2.- Componentes en C++ Builder
95
Componentes
TForm1 *Form1;
Graphics::TBitmap *Grafico; //Ambito global de acceso
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2->Show();
this->Hide();
}
void __fastcall TForm1::FormHide(TObject *Sender)
{
Form2->Label1->Caption = "Athenea oculta";
}
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Form1->Canvas->Draw(0, 0, Grafico); //Dibuja el grafico en Canvas
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Grafico = new Graphics::TBitmap(); //Crea objeto bitmap
//Carga bitmap
Grafico->LoadFromFile("C:\\ARCHIVOS DE PROGRAMA\\ARCHIVOS COMUNES\\BORLAND
SHARED\\IMAGES\\SPLASH\\16COLOR\\ATHENA.BMP");
}
Tema 3.2.2.- Componentes en C++ Builder
96
Componentes
El código del segundo Form es:
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
#include "Unit1.h" //File/Incude Unit ...
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
Graphics::TBitmap *Grafico1; //Ambito global de acceso
__fastcall TForm2::TForm2(TComponent* Owner)
: Tform(Owner) { }
void __fastcall TForm2::Button1Click(TObject *Sender)
{ Form1->Show();
this->Hide(); }
void __fastcall TForm2::FormHide(TObject *Sender)
{ Form1->Label1->Caption = "Tierra oculta"; }
void __fastcall TForm2::FormPaint(TObject *Sender)
{ Form2->Canvas->Draw(0, 0, ElGrafico1); //Dibuja el grafico en Canvas }
void __fastcall TForm2::FormCreate(TObject *Sender)
{ Grafico1 = new Graphics::TBitmap(); //Crea objeto bitmap
//Carga bitmap
Grafico1->LoadFromFile("C:\\ARCHIVOS DE PROGRAMA\\ARCHIVOS COMUNES\\BORLAND SHARED\\
IMAGES\\SPLASH\\16COLOR\\EARTH.BMP");
}
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
Form1->Close(); //Cerramos el Form principal
}
Tema 3.2.2.- Componentes en C++ Builder
97
Componentes
Trabajo con ficheros: la clase ofstream
En el fichero Fstream.h se define la clase ofstream que permite trabajar con ficheros. Para esto
debemos declarar una variable debiendo ser el tipo de dicha variable cualquiera de las tres clases
siguientes:
Clase de objeto
Especialización
ifstream
Entrada de datos desde un archivo
ofstream
Salida de datos a un archivo
fstream
Lectura y escritura en un archivo abierto
Para declarar el fichero de salida lo haremos con algo similar a:
ofstream Fichero("Archivo de Prueba.txt",ios::trunc).
El constructor de la clase toma como primer parámetro el nombre del archivo a asociar al objeto y
como segundo el modo de apertura, que está formado por uno o más de los indicadores definidos en la
clase ios siguientes:
Indicador
Modo
Ejemplos de código
in
Apertura para entrada
out
Apertura para salida
app
Apertura para añadir
ate
Puntero final archivo tras apertura
trunc
Eliminar contenido actual del archivo
noreplace Fallo en apertura si el archivo existe
nocreate
Fallo en apertura si el archivo no existe
binary
Apertura en modo binario, no de texto
//Trabajar con archivos de salida sin ninguna asociación
ofstream F;
//Abrir fichero existente para lectura
ifstream F(“Fichero”);
//Abrir fichero para escritura creandolo
ofstream F(“Fichero”);
//Abrir fichero para lectura y escritura
fstream F(“Fichero”,ios::int |ios::out);
//Abrir fichero para escritura y generar error si existe
ofstream F(“Fichero”,ios::noreplace);
//Abrir fichero existente y si no existe no lo crea.
fstream F(“Fichero”,ios::nocreate);
//Abrir fichero en modo binario truncando el contenido actual. fstream
F(“Fichero”,ios::trunc|ios::binary);
El constructor de la clase ifstream tiene como valor por defecto para el segundo parámetro ios::in y el
constructor de ofstream ios::out.
Tema 3.2.2.- Componentes en C++ Builder
98
Componentes
ProgressBar, StaticText y Animate
Vamos a usar el ejemplo para describir estos componentes.
Ejemplo 122.- Uso de ProgressBar, StaticText y Animate
Se trata de realizar un ejercicio que almacene los 15000 primeros números en un fichero txt, que
una barra de progreso nos muestre el avance que se produce, nos aparezca un número indicativo del
progreso sobre la barra y que se muestre un objeto animado tipo folio volando entre carpetas.
Vamos a diseñar un formulario con altura 165, anchura 315 y centrado en pantalla sobre el que
situamos un objeto ProgressBar (Pestaña Win32) con alineación alBotton, Max=15000 y Step=1; un
objeto Animate (Pestaña Win32) con Active = false, CommonAVI = aviCopyFile, Repetitions = 1,
StarFrame = 1, StopFrame = 20 y Visible = false.; un objeto StaticText con su Caption vacío y centrado
sobre ProgressBar en vertical y en horizontal estableciendoles una fuente color rojo de 10 puntos y en
negrita; y finalmente colocamos un botón y un CheckBox para tener un diseño similar a:
Seguidamente vemos el código comentado completo de esta aplicación.
Tema 3.2.2.- Componentes en C++ Builder
99
Componentes
ProgressBar, StaticText y Animate
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <FStream.h> // la clase ofstream está definida en este fichero
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
/* Con el CheckBox vamos a conmutar la propiedad Smooth de la barra de progreso
Smooth=false hace que la barra sea segmentada y Smooth=true que sea continua */
if(CheckBox1->Checked==false)
ProgressBar1->Smooth=false;
else
ProgressBar1->Smooth=true;
// Creamos el fichero borrando su contenido cuando se crea si ya existe
ofstream Fichero("Archivo de Prueba.txt",ios::trunc);
Cursor = crHourGlass;
Button1->Enabled = false;
Tema 3.2.2.- Componentes en C++ Builder
100
Componentes
ProgressBar, StaticText y Animate
// Recorremos un bucle para los 15000 valores
for (int N=0; N<15000; N++)
{
Animate1->Active=true;
Animate1->Visible=true;
Animate1->Repetitions = 3;
Animate1->Timers=ProgressBar1->Position;
// Texto a mostrar en la etiqueta StaticText
StaticText1->Caption=AnsiString(ProgressBar1->Position*100/15000+1) + " %";
// Método de Application que interrumpe la ejecución de una solicitud a fin
// de que pueda procesar la cola de mensajes
Application->ProcessMessages();
// Desplazamiento a la izquierda de forma que Fichero se va completando sin dejar espacios en blanco.
Fichero << N;
// Método StepIt para avanzar (actualizar) según lo establecido en la propiedad Step de ProgressBar.
ProgressBar1->StepIt();
}
Fichero.close(); // Método para cerrar el archivo
// Establecimiento de las condiciones iniciales
ProgressBar1->Position=0;
Button1->Enabled = true;
Cursor = crDefault;
StaticText1->Caption="";
Animate1->Visible=false;
}
Tema 3.2.2.- Componentes en C++ Builder
101
a
l
e
d
Fin
s
e
r
p
n
ó
i
c
a
t
en
Tema 3.2.2.- Componentes en C++ Builder
102

Documentos relacionados