SlideShare uma empresa Scribd logo
1 de 102
Baixar para ler offline
1
Tema 3.2.2.- Componentes en C++ Builder
Técnicas de Programación
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
3.2.- Programación C++ con Builder C++
2
Tema 3.2.2.- Componentes en C++ Builder
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.
Aplicación
VCL
S.O. Windows
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.
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
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
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.
3
Tema 3.2.2.- Componentes en C++ Builder
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
TPersistent
TComponent
Ttimer, Ttable, ...
TControl
TGraphicControl
TpaintBox ...
TWinControl
Tbutton, Tpanel, ...
Componentes
visibles
Componentes
no visibles
La VCL hace un uso
extensivo del concepto de
herencia. El objetivo final de
la VCL es crear clases que
representan a componentes,
aunque algunas clases no
hagan referencia a
componentes concretos:
realizan tareas de gestión
interna y se emplean como
clases bases para derivar
mediante herencia otras
clases. En la figura
mostramos una pequeña
parte de la jerarquía de
clases que forman la VCL.
4
Tema 3.2.2.- Componentes en C++ Builder
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.
5
Tema 3.2.2.- Componentes en C++ Builder
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().
6
Tema 3.2.2.- Componentes en C++ Builder
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);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
Métodos Initialize(), CreateForm() y Run().
Además aparece el método Title por haber
puesto un título a nuestra aplicación
Como Application se crea automáticamente no aparece
en la paleta de componentes ni está disponible en el
inspector de objetos para manipular "visualmente" sus
propiedades.
En cualquier caso, algunas propiedades pueden
establecerse en tiempo de diseño seleccionando las
páginas Forms o Applicaction en Project/Options.
7
Tema 3.2.2.- Componentes en C++ Builder
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.
8
Tema 3.2.2.- Componentes en C++ Builder
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.
9
Tema 3.2.2.- Componentes en C++ Builder
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; }
}
10
Tema 3.2.2.- Componentes en C++ Builder
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.
11
Tema 3.2.2.- Componentes en C++ Builder
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.
12
Tema 3.2.2.- Componentes en C++ Builder
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. */
13
Tema 3.2.2.- Componentes en C++ Builder
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();
}
//---------------------------------------------------------------------------
14
Tema 3.2.2.- Componentes en C++ Builder
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.
15
Tema 3.2.2.- Componentes en C++ Builder
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.).
16
Tema 3.2.2.- Componentes en C++ Builder
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.
17
Tema 3.2.2.- Componentes en C++ Builder
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
OnMouseUp
OnClick
OnDblClick
Para responder a los eventos que suceden al mover el ratón o cuando se pincha con él sobre el
formulario.
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.
18
Tema 3.2.2.- Componentes en C++ Builder
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:
19
Tema 3.2.2.- Componentes en C++ Builder
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.
20
Tema 3.2.2.- Componentes en C++ Builder
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";
}
21
Tema 3.2.2.- Componentes en C++ Builder
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.
22
Tema 3.2.2.- Componentes en C++ Builder
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:
23
Tema 3.2.2.- Componentes en C++ Builder
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.
24
Tema 3.2.2.- Componentes en C++ Builder
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. */
25
Tema 3.2.2.- Componentes en C++ Builder
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á
if (CheckBoxOpciones->Checked == true)
{
RadioButtonOp1->Show();
RadioButtonOp2->Show();
RadioButtonOp1->Checked = true;
ButtonOK->Enabled = true;
}
else
{
RadioButtonOp1->Hide();
RadioButtonOp2->Hide();
ButtonOK->Enabled = false;
LabelSalida->Caption = "";
}
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á.
Para ello, escribiremos el gestor asociado al evento
OnClick del componente CheckBox:
26
Tema 3.2.2.- Componentes en C++ Builder
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;
}
27
Tema 3.2.2.- Componentes en C++ Builder
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="";
}
28
Tema 3.2.2.- Componentes en C++ Builder
Conversión entre tipos
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.
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:
29
Tema 3.2.2.- Componentes en C++ Builder
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="";
}
30
Tema 3.2.2.- Componentes en C++ Builder
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:
31
Tema 3.2.2.- Componentes en C++ Builder
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
32
Tema 3.2.2.- Componentes en C++ Builder
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 '.
33
Tema 3.2.2.- Componentes en C++ Builder
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.
34
Tema 3.2.2.- Componentes en C++ Builder
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);
35
Tema 3.2.2.- Componentes en C++ Builder
Conversión entre tipos
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());
}
DateTimeToStr
Convierte un objeto TdateTime a un AnsiString con la siguiente sintaxis:
DateTimeToStr(const System::TDateTime DateTime);
36
Tema 3.2.2.- Componentes en C++ Builder
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.
37
Tema 3.2.2.- Componentes en C++ Builder
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) + " ";
}
}
38
Tema 3.2.2.- Componentes en C++ Builder
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.).
39
Tema 3.2.2.- Componentes en C++ Builder
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.
40
Tema 3.2.2.- Componentes en C++ Builder
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) );
41
Tema 3.2.2.- Componentes en C++ Builder
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:
42
Tema 3.2.2.- Componentes en C++ Builder
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
43
Tema 3.2.2.- Componentes en C++ Builder
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:
44
Tema 3.2.2.- Componentes en C++ Builder
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.
45
Tema 3.2.2.- Componentes en C++ Builder
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
46
Tema 3.2.2.- Componentes en C++ Builder
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:
47
Tema 3.2.2.- Componentes en C++ Builder
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.
48
Tema 3.2.2.- Componentes en C++ Builder
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.
49
Tema 3.2.2.- Componentes en C++ Builder
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:
50
Tema 3.2.2.- Componentes en C++ Builder
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.
51
Tema 3.2.2.- Componentes en C++ Builder
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 diseño
Tiempo de ejecución
52
Tema 3.2.2.- Componentes en C++ Builder
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.
53
Tema 3.2.2.- Componentes en C++ Builder
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:
54
Tema 3.2.2.- Componentes en C++ Builder
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
}
55
Tema 3.2.2.- Componentes en C++ Builder
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);
}
56
Tema 3.2.2.- Componentes en C++ Builder
Componentes
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:
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.
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;
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.
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;
57
Tema 3.2.2.- Componentes en C++ Builder
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:
58
Tema 3.2.2.- Componentes en C++ Builder
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:
59
Tema 3.2.2.- Componentes en C++ Builder
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.
60
Tema 3.2.2.- Componentes en C++ Builder
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
...
}
61
Tema 3.2.2.- Componentes en C++ Builder
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:
62
Tema 3.2.2.- Componentes en C++ Builder
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++;
};
}
63
Tema 3.2.2.- Componentes en C++ Builder
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();
}
//---------------------------------------------------------------------------
64
Tema 3.2.2.- Componentes en C++ Builder
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().
65
Tema 3.2.2.- Componentes en C++ Builder
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.
66
Tema 3.2.2.- Componentes en C++ Builder
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 Uso Valores
AutoSize El tamaño de la etiqueta se ajusta automáticamente al contenido de ésta o no. true o false
Alignment Alineación del texto
Izquierda: taLeftJustify
Derecha: taRightJustify
Centro: taCenter
FocusControl
Tiene sentido cuando la etiqueta se usa como título de otro control. Sirve para
que la etiqueta de texto sepa a qué control debe pasar el foco de entrada cuando
se pulse la tecla de acceso rápido (&).
Nombre del control que
recibe el foco.
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.
67
Tema 3.2.2.- Componentes en C++ Builder
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.
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder
Componentes C++ Builder

Mais conteúdo relacionado

Mais procurados

Diseño en-el-nivel-de-componentes
Diseño en-el-nivel-de-componentesDiseño en-el-nivel-de-componentes
Diseño en-el-nivel-de-componentesAndresRealp1
 
Calidad en el desarrollo de software
Calidad en el desarrollo de softwareCalidad en el desarrollo de software
Calidad en el desarrollo de softwareNoe Moctezuma
 
introduction to c #
introduction to c #introduction to c #
introduction to c #Sireesh K
 
Desarrollando un API con REST
Desarrollando un API con RESTDesarrollando un API con REST
Desarrollando un API con RESTAlex Puig
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxtakshilkunadia
 
asp.net Webconfiguration
asp.net Webconfigurationasp.net Webconfiguration
asp.net WebconfigurationMa Kik
 
Configuring Parallel Approvers Notification
Configuring Parallel Approvers NotificationConfiguring Parallel Approvers Notification
Configuring Parallel Approvers NotificationFeras Ahmad
 
Chapter1 introduction to asp.net
Chapter1  introduction to asp.netChapter1  introduction to asp.net
Chapter1 introduction to asp.netmentorrbuddy
 
Oracle ebs how to obtain environment variable value using sql query
Oracle ebs how to obtain environment variable value using sql queryOracle ebs how to obtain environment variable value using sql query
Oracle ebs how to obtain environment variable value using sql queryRyan Ramroop FCCA
 
C# Tutorial
C# Tutorial C# Tutorial
C# Tutorial Jm Ramos
 
Object Oriented Programming In .Net
Object Oriented Programming In .NetObject Oriented Programming In .Net
Object Oriented Programming In .NetGreg Sohl
 

Mais procurados (20)

Diseño en-el-nivel-de-componentes
Diseño en-el-nivel-de-componentesDiseño en-el-nivel-de-componentes
Diseño en-el-nivel-de-componentes
 
Calidad en el desarrollo de software
Calidad en el desarrollo de softwareCalidad en el desarrollo de software
Calidad en el desarrollo de software
 
introduction to c #
introduction to c #introduction to c #
introduction to c #
 
Desarrollando un API con REST
Desarrollando un API con RESTDesarrollando un API con REST
Desarrollando un API con REST
 
Kotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptxKotlin Basics & Introduction to Jetpack Compose.pptx
Kotlin Basics & Introduction to Jetpack Compose.pptx
 
Android Basic Components
Android Basic ComponentsAndroid Basic Components
Android Basic Components
 
asp.net Webconfiguration
asp.net Webconfigurationasp.net Webconfiguration
asp.net Webconfiguration
 
Configuring Parallel Approvers Notification
Configuring Parallel Approvers NotificationConfiguring Parallel Approvers Notification
Configuring Parallel Approvers Notification
 
Chapter1 introduction to asp.net
Chapter1  introduction to asp.netChapter1  introduction to asp.net
Chapter1 introduction to asp.net
 
Android Button
Android ButtonAndroid Button
Android Button
 
SOA y Web Services
SOA y Web ServicesSOA y Web Services
SOA y Web Services
 
Visual studio
Visual studioVisual studio
Visual studio
 
.Net Core 1.0 vs .NET Framework
.Net Core 1.0 vs .NET Framework.Net Core 1.0 vs .NET Framework
.Net Core 1.0 vs .NET Framework
 
Retrofit
RetrofitRetrofit
Retrofit
 
Oracle ebs how to obtain environment variable value using sql query
Oracle ebs how to obtain environment variable value using sql queryOracle ebs how to obtain environment variable value using sql query
Oracle ebs how to obtain environment variable value using sql query
 
Java Swing
Java SwingJava Swing
Java Swing
 
C# Tutorial
C# Tutorial C# Tutorial
C# Tutorial
 
JAVA PROGRAMMING- GUI Programming with Swing - The Swing Buttons
JAVA PROGRAMMING- GUI Programming with Swing - The Swing ButtonsJAVA PROGRAMMING- GUI Programming with Swing - The Swing Buttons
JAVA PROGRAMMING- GUI Programming with Swing - The Swing Buttons
 
ASP.NET Web form
ASP.NET Web formASP.NET Web form
ASP.NET Web form
 
Object Oriented Programming In .Net
Object Oriented Programming In .NetObject Oriented Programming In .Net
Object Oriented Programming In .Net
 

Semelhante a Componentes C++ Builder (20)

Visual Basic
Visual BasicVisual Basic
Visual Basic
 
Informe programación Elimenez gonzalez
Informe programación Elimenez gonzalezInforme programación Elimenez gonzalez
Informe programación Elimenez gonzalez
 
Trabajo de programacion
Trabajo de programacionTrabajo de programacion
Trabajo de programacion
 
Trabajo programacion jose (1)
Trabajo programacion jose (1)Trabajo programacion jose (1)
Trabajo programacion jose (1)
 
Visual Basic
Visual BasicVisual Basic
Visual Basic
 
Trabajo de fundamentos de visual basic
Trabajo de fundamentos de visual basicTrabajo de fundamentos de visual basic
Trabajo de fundamentos de visual basic
 
Visual Basic
Visual BasicVisual Basic
Visual Basic
 
Eymi paredes informe programacion
Eymi paredes informe programacionEymi paredes informe programacion
Eymi paredes informe programacion
 
Luis jose coronel num 42
Luis jose coronel num 42Luis jose coronel num 42
Luis jose coronel num 42
 
Maria Añez
Maria AñezMaria Añez
Maria Añez
 
Kairubys rodriguez
Kairubys rodriguezKairubys rodriguez
Kairubys rodriguez
 
Visual basic
Visual basicVisual basic
Visual basic
 
Generalidades de visual basic 8
Generalidades de visual basic 8Generalidades de visual basic 8
Generalidades de visual basic 8
 
Franle ocanto
Franle ocantoFranle ocanto
Franle ocanto
 
Apuntes vb6
Apuntes vb6Apuntes vb6
Apuntes vb6
 
Generalidades de visual basic 8
Generalidades de visual basic 8Generalidades de visual basic 8
Generalidades de visual basic 8
 
Programacion 5% Karolayn Cardozo 28.252.584
Programacion 5% Karolayn Cardozo 28.252.584Programacion 5% Karolayn Cardozo 28.252.584
Programacion 5% Karolayn Cardozo 28.252.584
 
Raul andrade
Raul andradeRaul andrade
Raul andrade
 
Visualbasic6.0
Visualbasic6.0Visualbasic6.0
Visualbasic6.0
 
Guia 0 vb induccion
Guia 0 vb    induccionGuia 0 vb    induccion
Guia 0 vb induccion
 

Último

FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIAL
FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIALFUNDAMENTOS DE LA INTELIGENCIA ARTIFICIAL
FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIALPamelaGranda5
 
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdf
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdfINFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdf
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdfsolidalilaalvaradoro
 
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdf
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdfNOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdf
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdflinderlauradelacruz
 
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADO
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADOIPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADO
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADOEdisonRebattaRojas1
 
Teoría de la contingencia en las organizaciones
Teoría de la contingencia en las organizacionesTeoría de la contingencia en las organizaciones
Teoría de la contingencia en las organizacionesCarlosRozo19
 
Ecuacion Diferencial de Clairaut, Ejercicios Resueltos
Ecuacion Diferencial de Clairaut, Ejercicios ResueltosEcuacion Diferencial de Clairaut, Ejercicios Resueltos
Ecuacion Diferencial de Clairaut, Ejercicios ResueltosManuel Alejandro Vivas Riverol
 
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOS
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOSEJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOS
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOSLuisLopez273366
 
gestion y optimizacion de procesos proyecto
gestion y optimizacion de procesos proyectogestion y optimizacion de procesos proyecto
gestion y optimizacion de procesos proyectoclopez37
 
Parciales y Semestral Profesor David cedeño
Parciales y Semestral Profesor David cedeñoParciales y Semestral Profesor David cedeño
Parciales y Semestral Profesor David cedeñomonicabetancur29
 
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdf
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdfESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdf
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdffredyflores58
 
Presentación GP Nº03.ppt reapso general maqinas electricas
Presentación GP Nº03.ppt  reapso general maqinas electricasPresentación GP Nº03.ppt  reapso general maqinas electricas
Presentación GP Nº03.ppt reapso general maqinas electricasANDREJEANPIERREMACHU
 
Wal-Mart batalla con RFID...............
Wal-Mart batalla con RFID...............Wal-Mart batalla con RFID...............
Wal-Mart batalla con RFID...............osoriosantiago887
 
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICA
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICAPROBLEMAS RELACIONADOS RESUELTOS DE GENETICA
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICAMaxiMus221
 
thinner-acrilico-ac-205- ficha tecnica msds
thinner-acrilico-ac-205- ficha tecnica msdsthinner-acrilico-ac-205- ficha tecnica msds
thinner-acrilico-ac-205- ficha tecnica msdsfioticona20395
 
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdf
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdfS03 - Perfil del ingeniero industrial UTP - DIAPOS.pdf
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdfroycordovabocanegra7
 
Portafolio Stanley PT fichas Tecnicas.pptx
Portafolio Stanley PT fichas Tecnicas.pptxPortafolio Stanley PT fichas Tecnicas.pptx
Portafolio Stanley PT fichas Tecnicas.pptxdhernandeza2310
 
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdf
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdfTR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdf
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdfFRANCISCOJUSTOSIERRA
 
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICA
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICADEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICA
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICAJulyDelPilarMorenoQu
 
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2ErnestoContreras39
 
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdf
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdfS02 - Campo de acción. Cualidades del Ingeniero Industrial.pdf
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdfroycordovabocanegra7
 

Último (20)

FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIAL
FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIALFUNDAMENTOS DE LA INTELIGENCIA ARTIFICIAL
FUNDAMENTOS DE LA INTELIGENCIA ARTIFICIAL
 
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdf
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdfINFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdf
INFORME DE LA DE PROBLEMÁTICA AMBIENTAL 2 UNIDAD FINAL. PDF.pdf
 
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdf
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdfNOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdf
NOJA-581-08 NOJA Power OSM15-27-38 Guia de Producto - es.pdf
 
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADO
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADOIPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADO
IPERC INSTALACION DE EQUIPOS DE AIRE ACONDICIONADO
 
Teoría de la contingencia en las organizaciones
Teoría de la contingencia en las organizacionesTeoría de la contingencia en las organizaciones
Teoría de la contingencia en las organizaciones
 
Ecuacion Diferencial de Clairaut, Ejercicios Resueltos
Ecuacion Diferencial de Clairaut, Ejercicios ResueltosEcuacion Diferencial de Clairaut, Ejercicios Resueltos
Ecuacion Diferencial de Clairaut, Ejercicios Resueltos
 
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOS
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOSEJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOS
EJERCICIOS DE PROPIEDADES INDICES DE MECÁNICA DE SUELOS
 
gestion y optimizacion de procesos proyecto
gestion y optimizacion de procesos proyectogestion y optimizacion de procesos proyecto
gestion y optimizacion de procesos proyecto
 
Parciales y Semestral Profesor David cedeño
Parciales y Semestral Profesor David cedeñoParciales y Semestral Profesor David cedeño
Parciales y Semestral Profesor David cedeño
 
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdf
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdfESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdf
ESTADISTICA RESUELTO SAN JUAN SOLUCIONARIO CORRECTO.pdf
 
Presentación GP Nº03.ppt reapso general maqinas electricas
Presentación GP Nº03.ppt  reapso general maqinas electricasPresentación GP Nº03.ppt  reapso general maqinas electricas
Presentación GP Nº03.ppt reapso general maqinas electricas
 
Wal-Mart batalla con RFID...............
Wal-Mart batalla con RFID...............Wal-Mart batalla con RFID...............
Wal-Mart batalla con RFID...............
 
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICA
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICAPROBLEMAS RELACIONADOS RESUELTOS DE GENETICA
PROBLEMAS RELACIONADOS RESUELTOS DE GENETICA
 
thinner-acrilico-ac-205- ficha tecnica msds
thinner-acrilico-ac-205- ficha tecnica msdsthinner-acrilico-ac-205- ficha tecnica msds
thinner-acrilico-ac-205- ficha tecnica msds
 
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdf
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdfS03 - Perfil del ingeniero industrial UTP - DIAPOS.pdf
S03 - Perfil del ingeniero industrial UTP - DIAPOS.pdf
 
Portafolio Stanley PT fichas Tecnicas.pptx
Portafolio Stanley PT fichas Tecnicas.pptxPortafolio Stanley PT fichas Tecnicas.pptx
Portafolio Stanley PT fichas Tecnicas.pptx
 
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdf
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdfTR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdf
TR-514 (3) - DOS COLUMNAS PASCUA 2024 3.4 8.4.24.pdf
 
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICA
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICADEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICA
DEFENSA ALIMENTARIA EN LA INDUSTRIA PLASTICA
 
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2
DOCUMENTO DE MODELO DISEÑO DE MEZCLA 210 KG CM2
 
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdf
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdfS02 - Campo de acción. Cualidades del Ingeniero Industrial.pdf
S02 - Campo de acción. Cualidades del Ingeniero Industrial.pdf
 

Componentes C++ Builder

  • 1. 1 Tema 3.2.2.- Componentes en C++ Builder Técnicas de Programación 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 3.2.- Programación C++ con Builder C++
  • 2. 2 Tema 3.2.2.- Componentes en C++ Builder 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. Aplicación VCL S.O. Windows 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. 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 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 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.
  • 3. 3 Tema 3.2.2.- Componentes en C++ Builder 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 TPersistent TComponent Ttimer, Ttable, ... TControl TGraphicControl TpaintBox ... TWinControl Tbutton, Tpanel, ... Componentes visibles Componentes no visibles La VCL hace un uso extensivo del concepto de herencia. El objetivo final de la VCL es crear clases que representan a componentes, aunque algunas clases no hagan referencia a componentes concretos: realizan tareas de gestión interna y se emplean como clases bases para derivar mediante herencia otras clases. En la figura mostramos una pequeña parte de la jerarquía de clases que forman la VCL.
  • 4. 4 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 5. 5 Tema 3.2.2.- Componentes en C++ Builder 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().
  • 6. 6 Tema 3.2.2.- Componentes en C++ Builder 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); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); } } return 0; } Métodos Initialize(), CreateForm() y Run(). Además aparece el método Title por haber puesto un título a nuestra aplicación Como Application se crea automáticamente no aparece en la paleta de componentes ni está disponible en el inspector de objetos para manipular "visualmente" sus propiedades. En cualquier caso, algunas propiedades pueden establecerse en tiempo de diseño seleccionando las páginas Forms o Applicaction en Project/Options.
  • 7. 7 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 8. 8 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 9. 9 Tema 3.2.2.- Componentes en C++ Builder 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; } }
  • 10. 10 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 11. 11 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 12. 12 Tema 3.2.2.- Componentes en C++ Builder 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. */
  • 13. 13 Tema 3.2.2.- Componentes en C++ Builder 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(); } //---------------------------------------------------------------------------
  • 14. 14 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 15. 15 Tema 3.2.2.- Componentes en C++ Builder 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.).
  • 16. 16 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 17. 17 Tema 3.2.2.- Componentes en C++ Builder 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 OnMouseUp OnClick OnDblClick Para responder a los eventos que suceden al mover el ratón o cuando se pincha con él sobre el formulario. 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.
  • 18. 18 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 19. 19 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 20. 20 Tema 3.2.2.- Componentes en C++ Builder 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"; }
  • 21. 21 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 22. 22 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 23. 23 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 24. 24 Tema 3.2.2.- Componentes en C++ Builder 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. */
  • 25. 25 Tema 3.2.2.- Componentes en C++ Builder 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á if (CheckBoxOpciones->Checked == true) { RadioButtonOp1->Show(); RadioButtonOp2->Show(); RadioButtonOp1->Checked = true; ButtonOK->Enabled = true; } else { RadioButtonOp1->Hide(); RadioButtonOp2->Hide(); ButtonOK->Enabled = false; LabelSalida->Caption = ""; } 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á. Para ello, escribiremos el gestor asociado al evento OnClick del componente CheckBox:
  • 26. 26 Tema 3.2.2.- Componentes en C++ Builder 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; }
  • 27. 27 Tema 3.2.2.- Componentes en C++ Builder 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=""; }
  • 28. 28 Tema 3.2.2.- Componentes en C++ Builder Conversión entre tipos 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. 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:
  • 29. 29 Tema 3.2.2.- Componentes en C++ Builder 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=""; }
  • 30. 30 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 31. 31 Tema 3.2.2.- Componentes en C++ Builder 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
  • 32. 32 Tema 3.2.2.- Componentes en C++ Builder 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 '.
  • 33. 33 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 34. 34 Tema 3.2.2.- Componentes en C++ Builder 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);
  • 35. 35 Tema 3.2.2.- Componentes en C++ Builder Conversión entre tipos 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()); } DateTimeToStr Convierte un objeto TdateTime a un AnsiString con la siguiente sintaxis: DateTimeToStr(const System::TDateTime DateTime);
  • 36. 36 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 37. 37 Tema 3.2.2.- Componentes en C++ Builder 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) + " "; } }
  • 38. 38 Tema 3.2.2.- Componentes en C++ Builder 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.).
  • 39. 39 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 40. 40 Tema 3.2.2.- Componentes en C++ Builder 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) );
  • 41. 41 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 42. 42 Tema 3.2.2.- Componentes en C++ Builder 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
  • 43. 43 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 44. 44 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 45. 45 Tema 3.2.2.- Componentes en C++ Builder 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
  • 46. 46 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 47. 47 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 48. 48 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 49. 49 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 50. 50 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 51. 51 Tema 3.2.2.- Componentes en C++ Builder 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 diseño Tiempo de ejecución
  • 52. 52 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 53. 53 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 54. 54 Tema 3.2.2.- Componentes en C++ Builder 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 }
  • 55. 55 Tema 3.2.2.- Componentes en C++ Builder 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); }
  • 56. 56 Tema 3.2.2.- Componentes en C++ Builder Componentes 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: 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. 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; 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. 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;
  • 57. 57 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 58. 58 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 59. 59 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 60. 60 Tema 3.2.2.- Componentes en C++ Builder 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 ... }
  • 61. 61 Tema 3.2.2.- Componentes en C++ Builder 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:
  • 62. 62 Tema 3.2.2.- Componentes en C++ Builder 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++; }; }
  • 63. 63 Tema 3.2.2.- Componentes en C++ Builder 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(); } //---------------------------------------------------------------------------
  • 64. 64 Tema 3.2.2.- Componentes en C++ Builder 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().
  • 65. 65 Tema 3.2.2.- Componentes en C++ Builder 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.
  • 66. 66 Tema 3.2.2.- Componentes en C++ Builder 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 Uso Valores AutoSize El tamaño de la etiqueta se ajusta automáticamente al contenido de ésta o no. true o false Alignment Alineación del texto Izquierda: taLeftJustify Derecha: taRightJustify Centro: taCenter FocusControl Tiene sentido cuando la etiqueta se usa como título de otro control. Sirve para que la etiqueta de texto sepa a qué control debe pasar el foco de entrada cuando se pulse la tecla de acceso rápido (&). Nombre del control que recibe el foco. 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.
  • 67. 67 Tema 3.2.2.- Componentes en C++ Builder 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.