Curso Delphi. Lección 09B  

Send By: Ariel Bustamante
Web : N.A.
Email: N.A.
Date: 07/03/03

Tip accessed 898 times

 


QUERY

El componente Query ya quedó explicado en la Lección 8, ahora vamos a realizar un pequeño proyecto para ver uno de los infinitos usos que podemos darle al mismo. Si algo tiene de curioso el siguiente proyecto es que sin dejar de ser una importante aplicación, para diseñarla, no hay que escribir una sola línea de código; bueno, quizás una sola línea si le ponemos un botón para cerrarla. Creamos en Leccion9 la sub-carpeta SQL y abrimos Delphi, guardamos la Unit como Main (¡que original!) y el project como SQL, al Caption de la ficha le ponemos 'Una aplicación con QUERY'. En la Ficha colocaremos un DBNavigator, un DataSource y un componente Query que encontrarás en la Pestaña/DataAcces.
Para este proyecto utilizaremos la Tabla Clientes.dbf que viene diseñada en la aplicación Delphi bajo el alias DBDemos.
Vamos a la Propiedad/DatabaseName de Query, desplegamos la ventana y seleccionamos DBdemos. Ahora vamos a la Propiedad/DataSet del DataSource1 y seleccionamos a Query1 y en la Propiedad/DataSource del DBNavigator1, seleccionamos DataSource1. En Query1 nos vamos a su Propiedad/SQL hacemos doble clic en la misma y se abre la ventana String List Editor, allí escribimos Select * from "Clientes.dbf " Clientes. Atención a la forma de escribir este parámetro, no debe haber espacio de separación entre las comillas y el nombre de la tabla. La Propiedad/RequestLive de Query1 la pasamos a True. Ahora hacemos doble clic sobre el componente Query1 y nos aparece una ventana llamada Form1.Query1, posicionados en esta ventana clicamos el botón derecho del ratón, seleccionamos Add Fields y nos aparece en una nueva ventana el listado de todos los campos disponibles de la tabla Clientes, clicamos OK en este listado y todos los campos pasan a la ventana Form1.Query1. Seleccionamos el primer campo (LAST_NAME) y observaremos que en el Inspector aparecen todas las propiedades que podríamos modificar del mismo, de momento vamos a modificar una sola la DisplayLabel, esta modificación no afectará al campo de la tabla que se seguirá llamando igual si no, que como lo dice la propiedad, modificará la Label del display. Cuando lo veas en funcionamiento, no necesitarás más explicaciones. Modificamos traduciendo al castellano el DisplayLabel de unos cuantos o todos los campos que sepamos su traducción. Una vez acabado esta operación, prácticamenete has acabado el proyecto. Selecciona el primer campo (LAST_NAME) y arrástralo con el ratón a la superficie de la ficha, sueltalo, un DBEdit titulado con una Label encima aparecerá en la Form, continúa con el siguiente hasta depositarlos todos, verás que se "transforman" todos en un componente DBEdit a exepción del último que es un DBImage. Pon la Propiedad/Active del Query en True y ya verás los registros de la tabla, pasa la ficha a wsMaximized y ejecuta el project. En tiempo de ejecución navega por los diferentes registros y comprobarás lo dicho en un principio: "sin una línea de código". Puedes modificar los registros (contenidos dentro de los DBEdit) a tu gusto, eso es por la Propiedad/RequestLive que pasamos a True, en False la tabla sería de solo lectura. Verás también las etiquetas (Labels) a las cuales has modificado su Caption en la Propiedad/DisplayLabel. Por último nos queda por señalar un nuevo componente que ha aparecido en nuestro proyecto el DBImage imprescindible para mostrar campos Image o Picture en una aplicación. Si te interesa repetir este proyecto, puedes hacerlo exactamente igual cambiando solamente el parámetro en el String List editor por este: select * from "biolife.db" category, esta tabla contiene también un DBMemo. Considero innecesario copiar el código fuente de este proyecto.



Intercambio dinámico de datos (DDE)

Una aplicación cliente-servidor no es otra cosa que dos aplicaciones (una cliente, la otra servidor) intercambiando datos entre sí, para darle una terminología técnica a esta operación diríamos que una vez establecida una comunicación entre ambas aplicaciones estas empiezan las transferencias DDE, que pueden ser automáticas entre ellas o través de la solicitud de una a la otra. Un ejemplo de perogrullo sería tu Internet Explorer y tu servidor de Internet. En Delphi tenemos cuatro componentes diseñados para aplicaciones DDE el DdeClienteItem, el DdeClienteConv, el DdeServerItem y el DdeServerConv, un mínimo de traducción ya te va dando las pautas de cuales corresponden a una aplicación y cuales a la otra, solo nos quedan pendientes esos términos Item y Conv. Como es costumbre en la estructuras de estas lecciones no les llevaré por terrenos demasiados farragosos para explicarles un mínimo de teoría, Conv es quien establece la Conversación entre las dos aplicaciones (como un módem lo hace desde el PC a la red), la mayoría de las aplicaciones utilizan solo un componente apellidado Conv, aunque si usara varios caminos de comunicación, también serían varios los Conv. Item es quien representa los datos que circularán por esa vía de comunicación establecida, igual a Conv se necesita por lo general un solo componente Item, aunque si fueran varios los tipos de datos a transferir, tendríamos que disponer de más componentes.

CLIENTE-SERVIDOR

Aplicación servidor

A continuación un pequeño proyecto cliente-servidor que aunque elemental, nos dará las pautas elementales para desarrollar este tipo de aplicaciones.
Creamos la sub-carpeta ClieServ, guardamos el project con el nombre de Servidor1 y la Unit con el nombre de Servidor, en el Caption de La Form ponemos
"Programa Servidor" (sin comillas) y el Name de Form1 será FServidor. Como siempre la costumbre de llamar las cosas por su nombre y más en este tipo de proyectos donde vamos a desarrollar dos aplicaciones en una. En este tipo de proyectos siempre se debe empezar siempre por crear primero el programa servidor, cuando avancemos en el diseño comprenderás el por que de este orden. A la ficha le damos un alto de 600 y un ancho de 500, la ubicamos lo más a la derecha del escritorio y guardamos nuevamente el project. Si ahora ejecutas el programa, verás que la ventana se crea posicionada en ese sitio, dejando el margen izquierdo libre para la aplicación cliente. Depositamos en la ficha: de la Pestaña/System un DdeServerItem, de la Additional un BitBtn y de la Standard un Memo.
Al Memo le damos una altura de 500, un ancho de 450 y le borramos de su Propiedad/Lines el texto Memo1, colocamos el BitBtn debajo del Memo y le pasamos su Propiedad/Kind a bkClose. Al cambiar esta propiedad ya no hace falta escribir ninguna línea de código para que este botón nos cierre la aplicación. En el Evento/OnActivate de FServidor escribimos:

DdeServerItem1.CopyToClipboard;

Esta línea de código será la que informará a la aplicación cliente de quien es el servidor, para ello hemos de ejecutar una vez este proyecto antes de diseñar el project cliente. Ahora en el Evento/OnChange de Memo1 escribiremeos:

DdeServerItem1.Text := Memo1.Text;

Esta línea de código indica que cuando cambie Memo1 (por ej: cuando escribamos algo en él), el texto de Memo1 pase a ser recogido por DdeServerItem1.
El servidor está acabado, compilamos, guardamos y ejecutamos; visto lo hecho (que no hace absolutamente nada) cerramos la aplicación y ya en diseño, cerramos el project (File/CloseAll) para abrir uno nuevo (File/New Application).
A esta nueva ficha le damos el mismo alto y ancho que la anterior, la ubicamos a la izquierda del escritorio, tapando al Inspector y guardamos el project, de nombre a la Unit le ponemos Clente y de nombre al project le ponemos Cliente1, el nombre de la ficha será Fcliente y su Caption "Programa Cliente" (sin comillas).
Depositaremos un Memo con las mismas medidas que el anterior y borrándole la Propiedad/Lines, también colocaremos un BitBtn con las mismas características que el anterior y de la Pestaña/System depositamos un DdeClientConv y un DdeClientItem, la diferencia visual entre estos componentes no visibles en tiempo de ejecución es, las flechas del primero. En el Evento/OnCreate de Fcliente escribiremos:

DdeClientItem1.DdeItem := 'DdeServerItem1';

Ya hemos conectado entre sí a los dos componentes Item. En el Event/OnChange (el único evento que posee) de DdeClientItem1 escribiremos:

Memo1.Text := DdeClientItem1.Text;

Cuando se produzca un cambio en DdeClientItem1, este pasará al Memo1. Estas son las únicas cuatro líneas de código a escribir por nuestra parte para le creación de estas dos aplicaciones y si las leemos con una pizca de traducción veremos en las tres últimas que el Memo del servidor le pasa el texto al DdeServerItem, el texto de este es "capturado" por el DdeClientItem y lo pasa al Memo del cliente. Ahora nos queda solo modificar algunas propiedades.
En el DdeClientConv1 tenemos por defecto a la Propiedad/ConnectMode en Automatic, así la dejaremos; su segunda opción que es Manual la usaríamos asociada a un evento para cambiar la conexión a otro servidor en tiempo de ejecución. Las dos propiedades siguientes se modifican en conjunto, tanto nos daría clicar el botón de tres puntos de DdeService como de DdeTopic; pero antes de hacerlo, un mínimo de teoría.

Topic Esta propiedad identifica una unidad de datos como el nombre de un archivo o el Caption de una ficha servidor o el name de un DdeServerItem de la ficha servidor.

Service Esta propiedad siempre debe contener el nombre del archivo ejecutable sin la extensión exe.

Item Identifica un elemento de datos de texto enviado por una aplicación servidor a una cliente, los Items siempre se representan como listas de cadena TStrings.

Ahora clicamos el botón de los tres puntos de una de estas propiedades (DdeService o DdeTopic) y se nos abre una ventana llamda DDE Info, los edits correspondientes a DdeService y DdeTopic aparecen vacíos, con solo clicar el botón Paste Link ya deberían completarse con la información del programa servidor, esto ocurre porque nosotros ya hemos ejecutado con anterioridad la aplicación servidor y aquella línea de código que escribimos en el OnActivate de FServidor (DdeServerItem1.CopyToClipboard;) ya se cumplió. Clicamos Ok y se cierra la ventana. Puede que se ejecute servidor por sí solo.
Nota: no te extrañes si al abrir el project cliente en Delphi, se te ejecute el programa servidor, lo mismo que una vez acabados los dos projects y ejecutes a cliente, también se te ejecutará servidor minimizado en la barra de tareas. En algunos casos puede ocurrir que alguna de estas dos aplicaciones no se ejecute correctamente si aún mantienes abierto a Delphi, estos son algunos líos que nos provoca el debug, pero con cerrar Delphi, problema solucionado.
Ahora seleccionamos en la ficha a DdeClientItem1 y modificamos su Propiedad/DdeConv, desplegando la ventana y seleccionando a DdeClientConv1 y ya está acabado nuestro project, compilamos, guardamos y cerramos la fase de diseño para ir a nuestra carpeta ClieServ y clicar sobre el exe de Cliente. Todo lo que escribas en el Memo de servidor pasará al Memo de cliente. Realmente no hemos diseñado un proyecto de intercambio de datos ida y vuelta tipo chat, porque estos fluyen en una sola dirección, pero con agregar unos componentes DDE ya lo tendríamos. Para los objetivos que nos hemos planteado en este curso, el proyecto actual ya cumple los mismos, pero como dijimos en nuestra primera lección, estamos abiertos a todo tipo de sugerencias y si a vosotros os interesa avanzar un par de pasos más en transferencias DDE, nos lo hacen saber a través de los mensajes en esta misma lección y ya volveremos a abordar el tema.
A continuación los dos bloques de código de este apartado


 unit Servidor;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   Buttons, StdCtrls, DdeMan;

 type
   TFServidor = class(TForm)
     DdeServerItem1: TDdeServerItem;
     BitBtn1: TBitBtn;
     Memo1: TMemo;
     procedure FormActivate(Sender: TObject);
     procedure Memo1Change(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;

 var
   FServidor: TFServidor;

 implementation

 {$R *.DFM}

 procedure TFServidor.FormActivate(Sender: TObject);
 begin
 DdeServerItem1.CopyToClipboard;
 end;

 procedure TFServidor.Memo1Change(Sender: TObject);
 begin
 DdeServerItem1.Text := Memo1.Text;
 end;

 end.





 unit Cliente;

 interface

 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   DdeMan, StdCtrls, Buttons;

 type
   TFCliente = class(TForm)
     BitBtn1: TBitBtn;
     DdeClientConv1: TDdeClientConv;
     DdeClientItem1: TDdeClientItem;
     Memo1: TMemo;
     procedure FormCreate(Sender: TObject);
     procedure DdeClientItem1Change(Sender: TObject);

   private
     { Private declarations }
   public
     { Public declarations }
   end;

 var
   FCliente: TFCliente;

 implementation

 {$R *.DFM}



 procedure TFCliente.FormCreate(Sender: TObject);
 begin
    DdeClientItem1.DdeItem := 'DdeServerItem1';
    end;



 procedure TFCliente.DdeClientItem1Change(Sender: TObject);
 begin
 Memo1.Text := DdeClientItem1.Text;
 end;

 end.