Este
ejemplo muestra el uso de los componentes y controles tipos TMemo (Control
que aloja, muestra y actualiza líneas de un Texto), TToolBar (Control
Barra de tareas, con botones gráficos),TMenu (Componente que genera
el Menú encabezando una Forma o Ventana), TActionList, TImageList
(Componentes para centralizar acciones provenientes de Menu y ToolBar),
TOpenDialog, TSaveDialog y TPrintDialog (Ventanas predefinidas de diálogos
para abrir, guardar e imprimir archivos, respectivamente). Observe
que algunos componentes no son objetos visibles directamente en la forma.
Como no son directamente visibles ni manipulables, pueden colocarse en cualquier
lugar en la forma. Su colocación significa que hay una funcionalidad
asociada que se activa por acciones del usuario. El componente
TMenu presenta una barra en el borde superior de la forma con las opciones
de menú principal creadas por el programador, con formato y funcionamiento
al estilo de Windows. Los tres componente de tipo Diálogo se presentan
y activan cuando el programador lo ordene, en respuesta generalmente
a alguna opción de menú o de algún botón. Tiene
igualmente el estilo de presenación y funcionamiento de Windows.
El contenido de los archivos que confroman la aplicación se muestra en forma de tablas, en la columna izquierda el código en ObjectPascal y en la derecha explicaciones y comentarios. |
En
los archivos de programa (.dpr y .pas), las líneas
que son generadas automáticamente por Delphi están en color
amarillo; en blanco sólo las que el programador tuvo que agregar.
Aparecen resaltadas en ambos casos las palabras reservadas de ObjectPascal,
tal como lo hace el Editor de Delphi.
Son tres los archivos que conforman la aplicación: ConToolBar.dpr: es el archivo raíz o índice del proyecto, de extensión .dpr (Delphi PRoject); ConToolBarU.pas: es la Unit que contiene la programación correspondiente a la forma de interfaz de usuario; ConToolBarU.dfm: es parte de la visualización en modo texto de la Forma diseñada por el programador como interfaz de usuario. Este archivo de extensión .dfm (Delphi ForM) contiene las declaraciones correspondientes al diseño de la Forma; es generado por Delphi transcribiendo la construcción que hace el usuario en forma visual. No hace falta que el programador vea este archivo ni debe modificar manualmente el texto, Delphi se encarga de su actualización cada vez que visualmente se modifique la apariencia o el contenido de la Forma asociada, ya sea por acciones directas sobre la Forma o modificando propiedades con el Object Inspector . |
Dieseņo de la Forma de Intefaz de Usuario
program
ConToolBar;
uses
{$R *.RES} begin
|
Para proyectos diseñados con formas de interfaz gráfica para usuarios, Delphi genera el archivo de extensión .dpr. En la sección uses coloca los nombres y las ubicaciones de todas las Units incorporadas al proyecto, además de la referencia a la Delphi-Unit Forms, que contiene la Clase TForm, clase primitiva de todas las formas. |
unit
ConToolBarU;
interface uses
|
En la sección
interface
se colocan todas las declaraciones o definiciones.
Delphi genera la lista de Units utilizadas
en la aplicación,
|
type
TForm1 = class(TForm) |
Tipo de clase de forma generado con todos los componentes y controles colocados por el programador en la forma. |
ImageList1: TImageList; | Para que la aplicación muestre las opciones de menú con íconos y una barra de tareas con botones equivalentes a las opciones de menú (ToolBar), es necesario agregar a la forma un componente de clase TImageList, de donde Delphi toma las imágenes. Oprimiendo el segundo botón con el componente de clase TImageList seleccionado en la forma, aparec un menú. Seleccione la primera opción para abrir el diálogo de selección de imágenes. Para agregar imágenes necesita tener una colección de imágenes disponibles. Por ejemplo, tomarlas de .../Borland Shared/Images/Buttons y modificarlas si quiere a su gusto con el Image Editor,accesible desde el menú Tools de Delphi o con cualquier editor gráfico. Delphi numera las imágenes a partir de 0 para referenciarlas en otros componentes o controles. |
ActionList1: TActionList; | Componente de clase TActionList para definir una lista de acciones que permite compartir una misma acción entre distintos controles, como botones y opciones de menús. |
ActionNew: TAction; ActionOpen: TAction; ActionSave: TAction; ActionSaveAs: TAction; ActionPrint: TAction; |
En este ejemplo se definen
las acciones de un editor de texto para: Crear nuevo texto, Abrir archivo
de texto, Guardar y Guardar asignando nombre e Imprimir el texto.
Relacione la lista de acciones con la lista de imágenes seleccionando
el componente de clase TImageList
en la casilla Images
de las Propiedades en el ObjectInspector.
Para
definir las acciones de la lista, oprimir el segundo botón con el
componente TActionList
seleccionado para que se despliegue un menú. Seleccione la primera
opción para abrir el diálogo de definición de acciones. Agregue acciones a la lista y defina en el ObjectInspector las propiedades
deseadas: Name
(del objeto Action
en en el programa: ActionNew, ActionOpe, etc., en este caso), Caption
(leyenda que aparecerá cuando se asocie la acción a una opción
de un menú),
Hint
(leyenda que aparecerá cuando se asocie la acción a un botón,
al pasar el punto del ratón sobre él), y muy importante,
ImageIndex
que asocia la acción con una de las imágenes, por su número
de referencia en la lista de imágenes.
|
MainMenu1:
TMainMenu;
File1: TMenuItem; New1: TMenuItem; Open1: TMenuItem; Save: TMenuItem; SaveAs: TMenuItem; Exit1: TMenuItem; Misc1: TMenuItem; Print: TMenuItem; |
Desplegando
la propiedad Items
de un componente TMainMenu;
o seleccionando el componente en la forma, oprimiendo el segundo botón
y seleccionando la primera opción, Delphi presenta un editor de
Menús para definir opciones y subopciones de clase TMenuItem.
En este ejemplo se crean dos opciones en el menú principal: File
y Misc,
File
con las subopciones
New,
Open,
Save,
Save
As y Exit
y Misc
con la subopción Print,
las cuales se asocian a las acciones de la lista de acciones ActionNew,
ActionOpen,
ActionSave,
ActionSaveAs
y ActionPrint,
respectivamente. Ellas también podrán activarse desde la
Barra de Tareas. Esta asociación se establece seleccionando la casilla
Action
en las Propiedades en el ObjectInspector, desplegando la lista de
acciones -ya debe estar definido el componente
TActionList-
y seleccionando la acción que se quiere hacer corresponder, con
lo cual Delphi automáticamente le transfiere las demás propiedades
comunes al objeto de clase TAction
y le transfiere así mismo el nombre del método de ejecución
de la acción al evento OnClick
.
La opción Exit en este ejemplo se crea independientemente de las acciones definidas, como puede hacerse también con todo el menú si no se desea tener formas distintas de activación de las acciones y por lo tanto, no es necesario definier una lista de acciones. En ese caso, las propiedades de la opción se asignan manualmente en el ObjectInspector así como la asignación del evento OnClick (ocurre cuando el usuario selecciona la opción) en Events. |
ToolBar1:
TToolBar;
ToolNew1: TToolButton; ToolOpen1: TToolButton; ToolSaveAs: TToolButton; ToolSave: TToolButton; |
TToolBar es un tipo de Control que permite colocar botones para que los usuarios puedan activar -generalmente en forma alternativa a las opciones de un menú- acciones en la aplicación. Oprimiendo es segundo botón con el componente de clase TToolBar seleccionado en la forma, aparec un menú. Seleccione la primera opción para agregar un nuevo botón o la segunda para agregar un separador. En este ejemplo se agregaron 4 botones para asociarlos a las acciones definidas en el componente TActionList, tal como se hizo con las opciones de menú. Para asociar cada botón a una acción, seleccione la casilla Action en las Propiedades del ObjectInspector, despliegue la lista de acciones definidas y seleccione la adecuada con lo cual Delphi automáticamente le transfiere las otras propiedades comunes al objeto de clase TAction y le transfiere el nombre del método de la acción al evento OnClick en Events. |
Memo1: TMemo; | El componente de clase TMemo se usa para alojar el contenido de un archivo de texto, el cual puede ser editado por el usuario (agregar, borrar, marcar, cortar, copiar, pegar, eliminar). |
OpenDialog1:
TOpenDialog;
SaveDialog1: TSaveDialog; PrintDialog1: TPrintDialog; |
Componentes para presentar diálogos de apertura de archivo, de guardado y de impresión, respectivamente. |
procedure
ActionNewExecute(Sender: TObject);
procedure ActionOpenExecute(Sender: TObject); procedure ActionSaveExecute(Sender: TObject); procedure ActionSaveAsExecute(Sender: TObject); procedure ActionPrintExecute(Sender: TObject); procedure Exit1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormActivate(Sender: TObject); |
Procedimientos de atención a los eventos del usuario: OnClick en las subopciones del Menu o en los botones del ToolBar (asignados por Delphi a los eventos OnExecute en las acciones de la lista definida), al cerrar la forma (OnClose) y al activarse la forma al inicio de la ejecución de la aplicación. |
private
{ Private declarations } NombreArchivo: string; public { Public declarations } end; var
implementation {$R *.DFM} |
Se agregó otro atributo, NombreArchivo, para mantener el nombre del archivo mostrado en el Control de clase TMemo. |
procedure
TForm1.ActionNewExecute(Sender: TObject);
begin ActionSaveExecute(Sender); Memo1.Clear; NombreArchivo:=''; end; |
En atención
al evento OnClick
en la opción File/New del menú o en el botón
correspondiente de la barra de tareas, se ejecuta el método definido
para la acción asociada en el componente de clase TAction
definido en el componente de clase TActionList.
Primero se invoca el método asociado al evento File/Save para que en caso de que haya un texto en el control Memo1, pueda guardárselo a un archivo antes de limpiar el área de texto. Luego se limpia el área y se asigna el string nulo al nombre del archivo indicando que no hay ninguno definido. |
procedure
TForm1.ActionOpenExecute(Sender: TObject);
begin ActionSaveExecute(Sender); if OpenDialog1.Execute then begin Memo1.Clear; NombreArchivo:=OpenDialog1.FileName; Memo1.Lines.LoadFromFile(NombreArchivo); end else ShowMessage('Cancelado'); end; |
En atención
al evento OnClick
en la opción File/Open del menú o en el botón
correspondiente de la barra de tareas, se ejecuta el método definido
para la acción asociada en el componente de clase TAction
definido en el componente de clase TActionList.
Primero se invoca el método asociado al evento File/Save para que en caso de que haya un texto en el control Memo1, se pueda guardarlo a un archivo antes de reemplazar el texto con el contenido del archivo que se vaya a abrir. Luego se hace desplegar la ventana de Diálogo OpenDialog1, directamente, invocando su método Execute. El método-función devuelve Truesi el usuario elige o suministra un nombre de archivo y sale aceptando, nombre que el Objeto OpenDialog1 guarda en la propiedad FileName. Se limpia el contenido del Memo y luego el contenido del archivo se coloca en la propiedad Lines del componente Memo1, usando el método LoadFromFile. Como aquí no se valida la existencia del archivo, pudiera ocurrir un error fatal en caso de que el archivo no exista. |
procedure
TForm1.ActionSaveAsExecute(Sender:
TObject);
begin if not SaveDialog1.Execute then ShowMessage('Cancelado') else begin NombreArchivo:=SaveDialog1.FileName; Memo1.Lines.SaveToFile(NombreArchivo); Memo1.Modified:=false; end end; |
En atención al evento
OnClick
en la opción File/SaveAs del menú o en el botón
correspondiente de la barra de tareas, se ejecuta el método definido
para la acción asociada en el componente de clase TAction
definido en el componente de clase TActionList.
Primero se hace desplejar la ventana de Diálogo SaveDialog1, directamente, invocando su método Execute. El método-función devuelve True si el usuario elige o suministra un nombre de archivo y sale aceptando, nombre que el Objeto SaveDialog1 guarda en la propiedad FileName. El archivo se crea y guarda con el contenido de la propiedad Linesdel componente Memo1, usando el método SaveToFile. En caso de que el usuario hubiera hecho alguna modificación al contenido del objeto Memo1, el archivo quedará guardado con las modificaciones. Se coloca la propiedad Modified del Memo en falso indicando que al momento los contenidos del Memo y del archivo son idénticos. (Delphi automáticamante revierte el valor de esta propiedad cuando el usuario hace cualquier modificación al contenido del Memo). |
procedure
TForm1.ActionPrintExecute(Sender: TObject);
var i, x, y, h: integer; begin if not PrintDialog1.Execute then ShowMessage('Canceloado') else with Printer do begin BeginDoc; x:=10; y:=10; h:=Canvas.TextHeight('T')+1; for i:=0 to Memo1.Lines.Count-1 do begin Canvas.TextOut(x,y,Memo1.Lines[i]); Inc(y,h); end; EndDoc; end; end; |
En atención
al evento OnClick
en la opción File/Print del menú o en el botón
correspondiente de la barra de tareas, se ejecuta el método definido
para la acción asociada en el componente de clase TAction
definido en el componente de clase TActionList.
Primero se hace desplegar la caja o ventana de Diálogo PrintDialog1, directamente, invocando su método Execute. El método-función devuelve False si el usuario cancela la impresión. Si no, se procede a usar el objeto global Printer, predefinido en la Unit Printers, utilizando sus métodos BeginDoc y EndDoc, encerrando el código para definir el contenido de la propiedad Canvas de clase TCanvas que representa el área de impresión (Ver las propiedades y métodos de la clase TCanvas en el Help). Al ejecutarse el método EndDoc, Delphi coloca el contenido de la impresión en la cola de impresión de la impresora activa de Windows. |
procedure
TForm1.Exit1Click(Sender: TObject);
begin ActionSaveExecute(Sender); Close; end; |
En atención a la selección de la opción File/Exit se ejecuta el método asociado al evento OnClick. Primero se invoca el método asociado al evento File/Save para que en caso de que haya un texto en el control Memo1, pueda guardarse a un archivo antes de hace cerrar la Forma, con lo cual termina la ejecución de la aplicación. |
procedure
TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin ActionSaveExecute(Sender); Action:=caFree; end; |
En atención
al evento de cerrado de la forma, se ejecuta su método asociado.
Delphi genera en en encabezado de este tipo de método la inclusión
de un parámetro calificado con la palabra var,
lo cual indica que se trata de una referencia
a una variable definida en el entorno que invoca al método.
En el caso de eventos de usuario, ese entorno es el sistema operativo Windows
que es quien recibe y reacciona a cada evento del usuario, invocando el
procedimiento que se le haya asociado. Ese parámetro de nombre Action
sirve para informarle a Windows si debe terminar la aplicación
(valor caFree)
o debe dejar que continúe activa (valor caNone).
En este caso, después de invocar el método asociado al evento File/Save para que en caso de que haya un texto en el control Memo1, pueda guardarse a un archivo antes de hace cerrar la Forma. Luego se coloca el valor del parámetro y termina la ejecución del método, con lo cual la variable en el entorno de Windows queda con el valor caFree, para que Windows actúe en consecuencia. |
procedure
TForm1.ActionSaveExecute(Sender: TObject);
begin if (NombreArchivo='') then if (Memo1.Lines.Count>0) then ActionSaveAsExecute(Sender) else else if Memo1.Modified then if MessageDlg('Archivo modificado. ¿Guardarlo?', mtConfirmation,[mbYes,mbNo],0)=mrYes then begin Memo1.Lines.SaveToFile(NombreArchivo); Memo1.Modified:=false; end; end; |
En atención
al evento OnClick
en la opción File/Save del menú o en el botón
correspondiente de la barra de tareas, se ejecuta el método definido
para la acción asociada en el componente de clase TAction
definido en el componente de clase TActionList.
También es invocada su ejecución desde otros métodos,
como desde el método Exit1Click
asociado al evento OnClick
de la opción de menú Exit.
Primero se revisa si no se ha cargado ningún archivo (NombreArchivo es nulo) y si hay algún contenido en el Memo. Si es así, se invoca la acción de guardar asignando nombre. Si sí hay un archivo cargado y fué modificado, se pregunta al usuario si desea guardar el texto modificado en el archivo (sobreescribiendo). (Ver sintaxis del procedimiento MessageDlg, de la Unit Dialogs, en el Help). En caso afirmativo se guarda y se coloca la propiedad Modified del Memo en falso indicando que al momento los contenidos del Memo y del archivo son idénticos. (Delphi automáticamante revierte el valor de esta propiedad cuando el usuario hace cualquier modificación al contenido del Memo). |
procedure
TForm1.FormActivate(Sender: TObject);
begin NombreArchivo:=''; Memo1.Clear; end; end. |
Si el progrmador asocia un método al evento OnActivate de la forma, el método se ejecuta después que Windows ha iniciado la ejecución de la aplicación y creado la forma, en el momento en el que la activa. En este caso, se inicializa el atributo NombreArchivo al string nulo y se limpia el área del control Memo1. |
Forma
ConToolBarU.dfm
vista
como texto
object
Form1: TForm1
Left = 467 Top = 218 Width = 417 Height = 295 Caption = 'Editor con Menu y ToolBar' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] Menu = MainMenu1 OldCreateOrder = False OnActivate = FormActivate OnClose = FormClose PixelsPerInch = 96 TextHeight = 13 object ToolBar1: TToolBar Left = 0 Top = 0 Width = 409 Height = 33 BorderWidth = 1 Caption = 'ToolBar1' Color = clBtnFace EdgeBorders = [ebTop, ebBottom] EdgeInner = esLowered Images = ImageList1 ParentColor = False TabOrder = 0 object ToolNew1: TToolButton Left = 0 Top = 2 Action = ActionNew ParentShowHint = False ShowHint = True end object ToolOpen1: TToolButton Left = 23 Top = 2 Action = ActionOpen ParentShowHint = False ShowHint = True end object ToolSaveAs: TToolButton Left = 46 Top = 2 Action = ActionSaveAs ParentShowHint = False ShowHint = True end object ToolSave: TToolButton Left = 69 Top = 2 Action = ActionSave ParentShowHint = False ShowHint = True end object ToolPrinter: TToolButton Left = 92 Top = 2 Action = ActionPrint ParentShowHint = False ShowHint = True end end object Memo1: TMemo Left = 0 Top = 33 Width = 409 Height = 216 Align = alClient Color = clNavy Font.Charset = ANSI_CHARSET Font.Color = clYellow Font.Height = -11 Font.Name = 'Courier New' Font.Style = [] Lines.Strings = ( '') ParentFont = False ScrollBars = ssVertical TabOrder = 1 end object MainMenu1: TMainMenu Images = ImageList1 Top = 40 object File1: TMenuItem Caption = '&File' object New1: TMenuItem Action = ActionNew end object Open1: TMenuItem Action = ActionOpen end object Save: TMenuItem Action = ActionSave end object SaveAs: TMenuItem Action = ActionSaveAs end object Exit1: TMenuItem Caption = '&Exit' OnClick = Exit1Click end end object Misc1: TMenuItem Caption = '&Misc' object Print: TMenuItem Action = ActionPrint end end end object ActionList1: TActionList Images = ImageList1 Left = 16 Top = 216 object ActionNew: TAction Category = '(All Categories)' Caption = 'New' Hint = 'New' ImageIndex = 0 OnExecute = ActionNewExecute end object ActionOpen: TAction Category = '(All Categories)' Caption = '&Open' Hint = 'Open' ImageIndex = 1 OnExecute = ActionOpenExecute end object ActionSaveAs: TAction Category = '(All Categories)' Caption = 'Save &As...' Hint = 'Save As' ImageIndex = 2 OnExecute = ActionSaveAsExecute end object ActionPrint: TAction Category = '(All Categories)' Caption = '&Print' Hint = 'Print' ImageIndex = 3 OnExecute = ActionPrintExecute end object ActionSave: TAction Category = '(All Categories)' Caption = '&Save' Hint = 'Save' ImageIndex = 4 OnExecute = ActionSaveExecute end end object ImageList1: TImageList Left = 64 Top = 216 Bitmap = { 3620000.............Datos de las imágenes..............003E07F} end object OpenDialog1: TOpenDialog Left = 32 Top = 40 end object SaveDialog1: TSaveDialog Left = 64 Top = 40 end object PrintDialog1: TPrintDialog Left = 96 Top = 40 end end |