martes, 5 de septiembre de 2017

Muy breve tutorial para empezar con Lazarus

Es este un sencillo ejemplo de primer programa para los recién llegados a Lazarus y a la programación con objetos.


Iniciamos Lazarus, Archivo–> Nuevo–>Aplicación. Nos mostrará un formulario con su correspondiente unit. Antes de hacer nada seleccionamos Guardar todo, el 5to. icono, seleccionamos la carpeta donde se guardará la aplicación, y guardamos, son 2 la ventanas de diálogo de guardar que aparecerán, dejamos los nombres por defecto ya que es una práctica y guardamos.


Cuando compilemos con éxito el programa, tendremos los siguientes archivos:
  • project1: es el ejecutable
  • project1.lpi: contiene información del proyecto, se recomienda no editar nunca este fichero,
  • project1.ico: como su extensión lo sugiere, es el icono.
  • project1.lps: guarda la configuración del proyecto y tampoco debería editarse nunca.
  • project1.lpr: Es el programa principal, se inicializa, se crea el formulario principal y se lanza el programa. Este archivo sí se puede editar (modificar), de hecho en la práctica se modifica habitualmente, aunque no mucho. Para comenzar, de momento, con algún ejercicio sencillo, no habrá que tocarlo.
  • project1.res: es una archivo binario de los recursos del programa.
  • unit1.pas: es el código fuente de la aplicación que estamos escribiendo.
  • unit1.lfm: sería como el código del formulario, o más bien sus propiedades. Salvo contadas excepciones, no hay que modificar nunca este archivo.
En los casos donde cito “no hay que modificar nunca este archivo” es porque lo hace Lazarus “para Lazarus”, se crear y actualizan automáticamente.
Todos los objetos tienen una propiedad “name” y la mayoría tiene una propiedad “caption”, como el caso del formulario TForm que Lazarus crea por defecto cuando creamos una unidad o aplicación. Estas propiedades, además de poder ser editadas mediante código, muchas veces se accede a ellas desde el inspector de objetos. Vamos a cambiar esas propiedades de nuestro formulario, lo llamaremos frmA y el caption es el texto que mostrará el formulario, le podremos simplemente Formulario A.



Ahora a iremos incorporando objetos a nuestro Form, desde la paleta Standar seleccionamos un TLabel (es el 5to. botón) y lo colocamos en el formulario. Un TLabel es una etiqueta, que básicamente muestra un texto.


Al TLabel le cambiaremos la propiedad (también se le llama atributo) caption. Nótese que la etiqueta se llama Label1, si colocásemos otra etiqueta, Lazarus la llamaría Label2. En caption pondremos: Este texto cambiará cuando presione el botón. Esto lo haremos desde el inspector de objetos, seleccionando Label1.




Para mayor comodidad para escribir el texto es aconsejable presionar sobre los 3 puntos (…) en la propiedad caption, esto nos abrirá una ventana para ingresar es texto que mostrará la etiqueta.



De paso podemos alinear la etiqueta horizontalmente al centro de la ventana, haciendo click derecho sobre la misma y seleccionando la opción “Alinear”.



 Bien, ahora lo ideal sería incluir un botón, desde la paleta Standar el 4to. icono que dice “OK” es un TButton, incorporamos uno al formulario y le damos las dimensiones que queramos valiéndonos del mouse.



Por default, Lazarus le asigna el nombre al componente Button1 y también al caption. Cambiaremos solo el caption y le pondremos “Haga click aquí.” o “Pinche aquí” o lo que más les guste.

Cabe destacar dos cosas, en Free Pascal, los objetos por convención (según tengo entendido) llevan una T al comienzo, por eso verán que todo es TForm, TLabel, TButton, TEdit, etc… Lo otro es que Lazarus define la instanciación de del objeto (variable) quitando la T y agregando un número, Form1, Label1, Button1, etc.

Hasta ahora no hemos escrito una sola línea de código, pero llego la hora de hacerlo, debemos hacer que cuando el usuario haga click en el botón cambie el texto de Label1. Para esto, hay que definir el evento OnClick de Button1. Evento: es un procedimiento asociado a un objeto y para una acción determinada. Esto es una definición breve muy básica, siempre hay que leer (y mucho) la wiki de Lazarus y la de Free Pascal.

Para ello, haremos click en Button1 y en el inspector de objetos y luego click en la pestaña “Eventos”, allí buscaremos el evento OnClick y haremos click en la segunda columna para que nos aparezcan los 3 puntos y haremos click sobre los mismos.



Lazarus nos habrá mandado al editor de código fuente donde ya ha definido el evento.


Lo que sigue ahora sí, habrá que escribirlo, con la ayuda de autocompletar que es fundamental para evitar errores, comenzamos a escribir “lab” y presionamos [CTRL] + Sapce para autocompletar.


Cuando vemos la “var” (variable) Label1 del tipo TLabel le damos Enter, escribimos un punto “.” y nuevamente Control + Espacio y buscamos la propiedad Caption, podemos escribir “ca” para hallarla más rápido. Ahora nos resta asignarle el valor que tomará la propiedad caption, por ejemplo:

procedure TfrmA.Button1Click(Sender: TObject);
begin
  Label1.Caption:='Gracias por presionar el botón.';
end;

Para ir viendo como funciona, vamos a compilar, presionando F9 o haciendo click en el icono play.


Y nos tendría que aparecer algo así:


Lo probamos, hacemos click y el texto debe cambiar. Luego pulsar el botón de Stop o [Crtl] +F2 para finalizar.


A esta altura ya creamos un ejecutable escribiendo solo una linea de código. Si bien el RAD Lazarus reduce mucho la cantidad de código a escribir, es erróneo pensar que todo será soltar componentes y escribir poco, mientras se va avanzando, cada vez se escribe más y, a su vez, iremos viendo que en algunos casos es mejor y a veces indispensable, algunos objetos definirlos “a mano” lo que se llama “en tiempo de diseño”, porque todo lo que arrastramos al formulario, puede escribirse e insisto, a veces solo queda esa opción, por ejemplo si queremos que cuando el usuario presione un botón se cree otro botón, el primer botón lo podemos crear soltando un TButton en el TForm, pero el segundo TButton deberemos crearlo, definirlo, mostrarlo y posiblemente eliminarlo mediante código.

Por último, dotaremos al formulario con un botón que muestre una imagen y una leyenda de “Cerrar” y cuya acción será finalizar la aplicación, es decir, cerrarla. El componente para esto se llama TBitBtn y está disponible en la paleta “Additional”, es un icono muy parecido a TButton.


Un BitBtn es un botón al que se le puede añadir una imagen, también posee imágenes prediseñadas, se encuentran en la propiedad “Kind” que por defecto es “bkCustom” y de momento lo dejamos así para añadir nuestra propia imagen, una apropiada para simbolizar la acción de cerrar. Para esto debemos tener una imagen, preferentemente guardada en nuestro disco, con realizar una búsqueda en Internet de “free icons” encontraremos unas cuantas.


Para cargar la imagen, vamos al inspector de objetos y en la propiedad “Glyph” hacemos click en “…”:


(También en Caption escribimos Cerrar).


Se abrirá una nueva ventana de diálogo donde haremos click en Cargar y seleccionamos la imagen.


Y click en Aceptar. En este caso la imagen la obtuve de aquí (icons8.com).

Y con esto terminamos el diseño de nuestro formulario que debería ser algo similar a esto:


Quizas te estés preguntando “entonces para que existe TButton si TBitBtn es mejor?” y la respuesta es simple: hubo una vez en la que no existía TBitBtn y muchos programas se hicieron con TButton y se debe preservar la compatibilidad; y es correcto, desde ya. De mi parte no veo otro motivo y utilizo siempre TBitBtn que se puede utilizar sin ninguna imagen también, con el beneficio de que si el día de mañana le queremos agregar una imagen no tengo más que agregarla si la necesidad de cambiar el componente.

Solo nos falta hacer que el BitBtn1 cierre la aplicación y para ello recurriremos nuevamente al evento OnClick, tal como hicimos con Button1, buscamos en el inspector de objetos el evento OnClick del BitBtn1 y presionamos sobre los 3 puntos.

Escribimos:

Close;

Y nuestro código fuente tendría que verse así:


Compilamos (F9) y probamos.



Y hasta acá llegamos con este muy breve tutorial o guía de inicio. Para finalizar, algunas anotaciones que nunca están de más:

Este código es el mismo para cualquiera de los sistemas operativos de escritorio soportados por Free Pascal, es decir, tanto en GNU/Linux, Windows o Mac OS se compilar este proyecto y funciona. Para proyectos “en serio” el 99% del código es el mismo y en muchos casos el 100%, es una de las principales ventajas de Free Pascal, además de ser de código abierto y la gran documentación online constantemente actualizada.

En este caso he utilizado la versión 3.0.0 de Free Pascal y 1.6.0 de Lazarus sobre Linux Mint 17.2 x86_64 MATE.

Lamentablemente y a pesar de ser el segundo o tercer lenguaje más utilizado en el planeta, no es mucha la documentación en español. Y si vamos al tema libros, al día de hoy solo he conseguido uno solo de Lazarus: “Iniciar con Lazarus y Free Pascal” el cual me ha servido mucho, el problema que tiene es la pésima traducción al español, por lo tanto, lo recomiendo pero en inglés. De hecho, el autor (Menkaura) me ha respondido muy amablemente un par de consultas que le hice por e-mail. Ojo que hay otro libro que en el título menciona a Lazarus pero solo le dedica un capítulo.

Es ideal antes de empezar con Lazarus, practicar Pascal puro desde la consola, luego practicar la programación orientada a objetos también desde consola, antes de comenzar con la IDE Lazarus.

Hay un libro on line Pascal con Free Pascal con muy buena documentación en español, desde ya. También sus 8 videos donde muestra como hacer un editor de textos con Lazarus, los cuales recomiendo ya que enseña como manejar varios componentes: https://youtu.be/el5sD0_2cZo

Y desde ya los foros, no solamente planteando dudas, sino también leyendo todos los debates se aprende mucho.

La mayoría de lo que encuentres sobre Delphi es aplicable a Lazarus con Free Pascal, siempre teniendo en cuenta que Delphi es solamente Windows.

Foros en español de Lazarus:

El oficial: forum.lazarus.freepascal.org
 
Delphi Access: delphiaccess.com 100% es español con varios subforos, entre ellos, Lazarus.

Club Delphi: clubdelphi.com primo hermano de Delphi Access, también 100% en español.

Información oficial de la wiki de Free Pascal sobre los componentes vistos en este tutorial:
// Fin

SQLite crear una base de datos con código

A diferencia de otras bases de dato SQL, SQLite carece del famoso CREATE DATABASE porque si la base de datos no existe, la crea automáticamente.

En tiempo de diseño solo debemos completar la propiedad Database de un componente Zconnection y activar la propiedad Connected, con eso ya se creo la base de datos.


Con código sería así:
   
ZConnection1.Database:='prueba.db';
ZConnection1.Connect;

Aclaración: Zconnection es un componente de ZeosLib, un conjunto de componentes para manejar bases de datos.

Tutorial Lazarus en español (PDF)

Este es el mejor curso para Lazarus que he encontrado, actualizado en 2015, del Lic. Ricardo De Castro Aquino, una joyita para quienes se inician en Lazarus con Free Pascal y como material de consulta permanente. Son 78 páginas imperdibles, muy bien explicado todo, mucho material para practicar.


Descargar "Manual de Lazarus" en PDF

Editor de Lazarus: Atajos de teclado

Perfectamente explicado en http://wiki.lazarus.freepascal.org/Lazarus_IDE_Tools/es#Tabla_resumen_de_los_atajos

Muy completo tutorial tanto de los shortcuts como del autocompletado.
Siempre es mejor leerlo en la wiki, pues puede haber alguna actualización. Pero nunca está demás una copia en PDF por las dudas.

Descargar Atajos de teclado en PDF

Instalar Lazarus y Free Pascal en Linux Mint

Hay varios métodos para instalar Lazarus, muy bien explicados en la wiki de Lazarus, en este caso explicaré un método muy simple que consiste en descargar los 3 paquetes necesarios e instalarlos.

Breve pero necesaria aclaración: se descarga el compilador, las fuentes y la IDE Lazarus. Para poder instalar Lazarus es necesario que previamente estén instalados el compilador y las fuentes, por ende primero deben instalarse primero esos dos paquetes, luego el RAD (IDE) Lazarus.

En este caso vamos a descargar e instalar FPC3.0.0 (Free Pascal Compiler), el código fuente del mismo compilador y por último Lazarus 1.6.2 para GNU/Linux 32 y 64 bits desde donde corresponde, es decir, desde SourceForge.net. <–click


Descargar todos esos archivos con excepción de README.txt.


Para instalar, solo basta con hacer doble click, en este caso sobre el paquete fpc-scr…. el cual se abrirá con el instalador de paquetes, hay que hacer click en el botón Instalar paquete. En la imagen aparece reinstalar porque ya lo tengo instalado, un detalle.


Nos pedirá la contraseña de super usuario y los instalará, puede demorar un poco.


Una vez finalizado el proceso tendrá que mostrar el paquete ya instalado. Cerramos y vamos por el siguiente, el compilador de Free Pascal.


Hacemos doble click en fpc_3.0.0…. y presionamos instalar, también nos pedirá la contraseña.


Esta advertencia hay que ignorarla con el botón cerrar y seguir. La misma se debe a que por algún motivo que desconozco, las versiones de Lazarus y Free Pascal en los repositorios de Ubuntu (que utiliza Linux Mint) son muy antiguas, demasiado, casi obsoletas.


Una vez cerrada la advertencia, se continúa con la instalación del compilador.


Al aparecer esto, significa la instalación a finalizado y cerramos el instalador de paquetes. Abrimos con doble click lazarus-project_1.6.2-1…. para ahora sí instalar Lazarus.


En esta captura en lugar de 3 archivos hay 6 porque tengo dos versiones de cada paquete, uno para 64 bits y otro para 32 bits.


Al tratarse de paquetes .deb las instalaciones son similares, se abre el paquete, click en instalar, contraseña y cerrar.


Para este pequeño tutorial instalé la versión i386 (32 bits) en una VM pero el procedimiento es igual para la versión de 64 bits que salvo para equipos muy antiguos, es la que más comúnmente se instala.


Ahora sí, en la carpeta que se creo “Lazarus” buscamos el ejecutable del mismo nombre y lo lanzamos.


Si aparece una ventana así significa que todo fue bien y solo hay que “Arrancar IDE”.


Aclaración: como la instalación fue a través del instalador de paquetes deb, en caso de necesitar desinstalar, se debe hacer lo mismo, ejecutar cada uno de los 3 paquetes y hacer click en el botón desinstalar. Es una forma de desinstalar, de seguro hay otras parecidas, pero esta es simple y rápida.

lunes, 4 de septiembre de 2017

Conectar SQLite y editar una tabla

En este video vemos como hacer un ABM de una tabla en 2 minutos sin escribir código. Desde ya un ABM es mucho más que lo que se muestra, pero que sirva como punto de partida. Ver en pantalla completa.



La conexión se realiza mediante Zconnection, componente del paquete Zeos Lib, ZQuery y un DataSource.

Soltamos los 3 componentes en el Form, indicamos la base de datos en ZConnection1 y el protocolo sqlite-3, conectamos. No es necesario nada más como se puede ver.

ZQuery1: indicamos que se conecta via ZConnection1, escribimos la consulta en SQL. Antes de activar, vamos a DataSource1 y le indicamos que el DataSet vendrá de ZQuery1. Activamos ZQuery1.

Agreamos un DBGrid y le indicamos que el DataSource será DataSource1.

Agregamos un DBNavigator y de igual forma que con el DBGrid le establecemos el DataSource1.

Por ningún motivo usar ZTable nunca, no tiene sentido y creo que no eliminan el componente por razones de compatibilidad con versiones anteriores.

Todo esto se puede hacer en tiempo de ejecución, escribiendo el código, que no es mucho por cierto y es lo más normal cuando se está desarrollando un programa y no un ejemplo. También se utilizan Data Modules para soltar ahí todos los componentes no visuales y trabajar más cómodo.

TDBLookUpComboBox 1

Cómo configurar, tanto en modo diseño como en ejecución, un DBLookUpComboBox.

Para este ejemplo se da por hecho que ya hay una conexión con una base de datos, una Query y DataSource. Para este caso utilizo para ellos los componentes de Zeos Lib.

En tiempo de diseño:

Con la base de datos conectada, el query activo y un DBLookUpComboBox1 en el Form, desde el inspector de objetos vamos configurar el combo en este orden:

  1. DataSource:=DataSource1
  2. ListSource:=DataSource1
  3. DataField:='tabla_ID';
  4. KeyField:='tabla_ID';
  5. ListField:='tabla_Descrip';
El ListField es el que se muestra en el combo, puede ser cualquier campo o columna de la tabla.



En modo diseño nuestro combo ya muestra los datos. No hemos escrito ni una sola línea de código, solo una consulta SQL.



En tiempo de ejecución:

Me ha pasado y todavía leo en los foros, que el combo se ve bien pero a la hora de ejecutar el programa, no se carga; o cómo hacer todo en tiempo de ejecución. Pues veamos el mismo caso:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, db, FileUtil, Forms, Controls, Graphics, Dialogs,
        DbCtrls, ZConnection, ZDataset;

type

        { TForm1 }

    TForm1 = class(TForm)
                DataSource1: TDataSource;
                DBLookupComboBox1: TDBLookupComboBox;
                ZConnection1: TZConnection;
                ZQuery1: TZQuery;
                procedure FormCreate(Sender: TObject);
    private
        { private declarations }
    public
        { public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  ZConnection1.Database:='datos.db';
  ZConnection1.Connect;
  ZQuery1.SQL.Text:='SELECT * FROM turnos;';
  ZQuery1.Open;
  DBLookupComboBox1.DataSource:=DataSource1;
  DBLookupComboBox1.ListSource:=DataSource1;
  DBLookupComboBox1.DataField:='turid';
  DBLookupComboBox1.KeyField:='turid';
  DBLookupComboBox1.ListField:='turdesc';
end;

end.  

Primero que nada, desde el inspector de objetos asegurarse de tener desconectada la base de datos y el SQL del query en blanco.

Es importante seguir un orden, primero establecer la conexión con la base de datos, luego definir la consulta SQL y paso siguiente abrirla, si es mediante Open mejor, el código es más claro, además active:=True lo único que hace es invocar a Open y en False, a Close.

Lo que sigue es lo mismo que hicimos desde el inspector de objetos y en el mismo orden.


domingo, 3 de septiembre de 2017

Diferencia horaria entre dos fechas

El tipo TDateTime es un número del tipo Double cuya parte entera se utiliza para la parte de la fecha y la parte fraccionaria para la hora.

Free Pascal dispone de una gran cantidad de funciones para el tratamiento de fechas y horas en la unidad dateutils.

En este ejemplo solo veremos como calcular la diferencia horaria, la parte time, de dos TDateTime y también la cantidad de horas entre dos fechas también del tipo TDateTime.


Lo primero que notamos es que el cálculo del tiempo transcurrido entre las 19:00 y 02:27 es correcto, 7 horas y 27 minutos.
Lo segundo, es que si se tomarán en cuenta los días de las fechas, las horas transcurridas serían 55 y 27 minutos.
Lo tercero, la cantidad de horas es correcta, 55, pero se ignoran los minutos.

Pero según lo que se necesite, esto puede servir o resultar insuficiente, en tal caso, hay que buscar la combinación de funciones que nos resuelvan el tema y de última siempre están las funciones Decode* y Encode* mediante las cuales, podemos hacer lo que queramos, aunque deberemos escribir más código.

El código del ejemplo:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, dateutils;

type

        { TForm1 }

    TForm1 = class(TForm)
                btnDiferencia: TButton;
                btnCantidad: TButton;
                Label1: TLabel;
                Label2: TLabel;
                Label3: TLabel;
                Label4: TLabel;
                procedure btnCantidadClick(Sender: TObject);
    procedure btnDiferenciaClick(Sender: TObject);
    private
        fechainicio, fechafin:TDateTime;
        { private declarations }
    public
        { public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.btnDiferenciaClick(Sender: TObject);
var
  Diferencia:TDateTime;
begin
  fechainicio:=StrToDateTime('05-07-2017 19:00');
  fechafin:=StrToDateTime('08-07-2017 02:27');
  Diferencia:=fechafin-fechainicio;
  Label3.Caption:=TimeToStr(TimeOf(Diferencia));
end;

procedure TForm1.btnCantidadClick(Sender: TObject);
var
  canthoras:Int64;
begin
  fechainicio:=StrToDateTime('05-07-2017 19:00');
  fechafin:=StrToDateTime('08-07-2017 02:27');
  canthoras:=HoursBetween(fechafin,fechainicio);
  Label4.Caption:=IntToStr(canthoras);
end;

end.

La función TimeOf recibe como parámetro un valor del tipo TDateTime y retorna la parte horaria, es decir, le pasamos un TDateTime y nos devuelve un TTime, por tal motivo utilizamos TimeToStr en lugar DateTimeToStr.

La función HoursBetween recibe como parámetros dos valores del tipo TDateTime y retorna un valor del tipo Int64 que serán la cantidad de horas entre las fechas.

Código fuente: Diferencia horaria entre fechas.7z

o en GitLab

sábado, 2 de septiembre de 2017

Cargar un archivo CSV en un StringGrid

Una vez puesto en el Form un componentes TStringGrid y un TButton y haber ajustado un par de propiedades desde el inspector de objetos, solo es necesario escribir una línea de código.

StringGrid1.LoadFromCSVFile('archivo.csv',' ',False,0,True);


Para este caso quité tanto la columna como la fila fija, la cantidad de columnas viene por default en 5 y el tamaño de las celdas lo fijé en 80, nada más. El archivo que carga contiene 50.000 filas y pesa 1,5 MB. Lo carga en aproximadamente 5 segundos.

El procedimiento LoadFromCSVFile:

procedure LoadFromCSVFile (

AFilename: string; 

ADelimiter: Char=',';

UseTitles: boolean=true;


FromLine: Integer=0;

SkipEmptyLines: Boolean=true);  

Como podemos observar, varios parámetros, al ya tener un valor asignado, son opcionales.

AFilename: el nombre del archivo, si no está en el mismo directorio que el programa, debe especificarse la ruta completa.

ADelimiter: el delimitador o separador de campos, al ser del tipo Char admite un solo caracter.

UseTitles: Si es True entonces respetará la primera fila como títulos de los campos comenzando la carga de datos en la siguiente, o sea, no la importa, caso contrario comenzará por la fila 0 (cero). Esto se refiere al archivo, es decir, si la primera fila del archivo son los títulos de las columnas.

FromLine: desde qué línea comienza la importación del archivo CSV.

SkipEmptyLines: si  es True, entonces si encuentra una línea vacia, la ignora, de lo contrario, la cargará en blanco.

Código completo del ejemplo:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids,
        StdCtrls;

type

        { TForm1 }

    TForm1 = class(TForm)
                Button1: TButton;
                StringGrid1: TStringGrid;
                procedure Button1Click(Sender: TObject);
    private
        { private declarations }
    public
        { public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  StringGrid1.LoadFromCSVFile('archivo.csv',' ',False,0,True);
end;

end.     

Código fuente para descargar: CSV a StringGrid.7z




Comparar horas

CompareTime es un función que nos permite comparar tiempo entre dos valores del tipo TDateTime o TTime. Si el valor es del tipo TDateTime, la parte del valor correspondiente a la fecha, es ignorada.

Esta función se encuentra en DateUtils por lo tanto debe agregarse en uses.

La función recibe como parámetros dos constantes del tipo TDateTime y devuelve un TValueRelationship cuyos valores están en el rango -1..1

function CompareTime ( const A: TDateTime; const B: TDateTime ) : TValueRelationship;

Definición según la wiki de Free Pascal.

Los parámetros aceptados son tanto del tipo TDateTime como TTime.

Si los valores son iguales, entonces devuelve 0 (cero).

Si el primer valor es anterior o más temprano que el segundo, entonces devuelve un valor menor a 0 (cero), es decir, negativo.

Si el primer valor es posterior o más tarde que el segundo, entonces devuelve un valor mayor a 0 (cero), es decir, positivo.

El valor retornado por la función puede almacenarse en una variable del tipo Integer y si bien la documentación habla de valores mayores, iguales o menores a 0 (cero), siendo del tipo entero entonces solo debería retornar 1, 0 o -1.

Ejemplo:


Código:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, FileUtil, DateTimePicker, Forms, Controls, Graphics, dateutils,
        Dialogs, StdCtrls;

type

        { TForm1 }

    TForm1 = class(TForm)
                btnComparar: TButton;
                DateTimePicker1: TDateTimePicker;
                DateTimePicker2: TDateTimePicker;
                Label1: TLabel;
                Label2: TLabel;
                Memo1: TMemo;
                procedure btnCompararClick(Sender: TObject);
    private
        { private declarations }
    public
        { public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.btnCompararClick(Sender: TObject);
begin
   CASE CompareTime(DateTimePicker1.Time,DateTimePicker2.Time) of
     1 : Memo1.Append('Llegó temprano');
     0 : Memo1.Append('Llego en horario.');
    -1 : Memo1.Append('Llegó tarde.');
     end;
end;

end.     

Descargar el código (.pas y .lfm): CompareTime.7z