Delphi 5 TDateTimePicker Format

During add Delphi 5 compatibility to the Purchase Order calculation sample of HotXLS Delphi Excel Spreadsheet component, an error occurred while compiling under Delphi 5.

The line which set the date format of the TDateTimePicker control does not compile:

DateTimePicker.Format := 'MM/dd/yyyy';

TDateTimePicker control of Delphi is a wrapper around a Microsoft control. It allows you to show the date in one of two formats (long and short), but in Delphi 5 and lower, it did not allow you to change the DateTime format. That’s because it uses the Windows date and time settings, not Delphi’s internal format variables like “ShortDateFormat”.

In Delphi 6 and later, you can use the Format property to change the display of date or time.

In Delphi 5 and earlier, you should use the DateTime_SetFormat function to set the format, this function in the “CommCtrl” unit, you should add CommCtrl to the “USES” column, otherwise, the DateTime_SetFormat won’t be recognized.

The fix for our sample project looks like this:

{$IFDEF D5}
  DateTime_SetFormat(DateTimePicker.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
  DateTimePicker.Format := 'MM/dd/yyyy';
{$ENDIF}

ftol and the 64bit Delphi inline asm changes

function _ftol( f: double) : Integer; cdecl;
begin
  asm
    lea    eax, f
    fstp  qword ptr [eax]
  end;
  result := Trunc(f);
end;

Above is a Delphi inline asm version of the ftol (Floating Point to Integer Conversion) function used by our HotPDF Delphi PDF component.

When compiling above Delphi codes in the 64-bit target platform, Delphi will raise below error:
[dcc64 Error] E1025 Unsupported language feature: ‘ASM’

The reason is: The 64-bit Delphi compiler DCC64 does not support mixed Pascal/assembly code.
DCC64.EXE supports 64-bit assembly code, but the routines must be written completely in assembler.

In addition, the 64-bit asm codes have many different than the 32-bit ones, you can not copy the 32-bit asm codes to the 64-bit assembler routines directly, you must re-write them from scratch, I found below codes from the internet:

function _ftol: Integer; cdecl;
// Assumes double value is in FPU stack on entry
// Make a truncation to integer and put it into function result
var
  TmpVal: Int64;
  SaveCW, ScratchCW: word;

asm
  .NOFRAME
  fnstcw word ptr [SaveCW]
  fnstcw word ptr [ScratchCW]
  or word ptr [ScratchCW], 0F00h  ;// trunc toward zero, full precision
  fldcw word ptr [ScratchCW]
  fistp qword ptr [TmpVal]
  fldcw word ptr [SaveCW]
  mov rax, TmpVal
end;

But maybe we do not really need assembly this routine,

function _ftol(f: double): integer; cdecl;
begin
  Result := Trunc(f);
end;

The trunc function of Delphi just returns the integer part of a floating point number, that’s the conversion from floating point to integer. The speed of this version should be not bad.

Delphi Incompatible type tagLOGBRUSH tagLOGBRUSH32

When using Delphi XE2 or above editions to compile coeds likes below:

procedure VEMRCREATEBRUSHINDIRECT(Data: PEMRCreateBrushIndirect);
begin
  GDIObjects[Data^.ihBrush] := CreateBrushIndirect(Data^.lb);
//GDIObjects and CreateBrushIndirect are defined in the winapi.windows unit.
end;

The compiler says: E2010 Incompatible types: ‘tagLOGBRUSH’ and ‘tagLOGBRUSH32’.

The solution to fix this compiling error is:

procedure VEMRCREATEBRUSHINDIRECT(Data: PEMRCreateBrushIndirect);
var
  LogBrush: TLogBrush;
begin
  LogBrush.lbStyle := Data^.lb.lbStyle;
  LogBrush.lbColor := Data^.lb.lbColor;
  LogBrush.lbHatch := Data^.lb.lbHatch;
  GDIObjects[Data^.ihBrush] := CreateBrushIndirect(LogBrush);
end;

C++Builder dynamic create & delete HotPDF component instance

This example shows you how to programmatically New and Free a HotPDF object instance with C++Builder.

#include 
#pragma hdrstop

#include "Unit1.h"
#pragma package(smart_init)
#pragma link "HPDFDoc"
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{

    THotPDF* HotPDF1 = new THotPDF(this);
    HotPDF1->FileName = "HelloWorld.pdf";
    HotPDF1->AutoLaunch = true;      
    HotPDF1->BeginDoc(false);
    HotPDF1->CurrentPage->PrintText( 10, 10, 0, "Hello World!" );
    HotPDF1->EndDoc();
    HotPDF1->Free(); 	
}

You need to set the include & library path of the project to the directory where HotPDF library files exist.

HotPDF Canvas Draw

This HotPDF Component Sample draw plots with Delphi TCanvas.

program CanvasDraw;
{$APPTYPE CONSOLE}
uses
{$IFDEF VER230} System.SysUtils, System.Classes, Vcl.Graphics, {$ELSE} SysUtils, Classes, Graphics, {$ENDIF} HPDFDoc;

var
   I, Y: Integer;
   HotPDF: THotPDF;

begin
    HotPDF:= THotPDF.Create(nil);
    try
        Randomize;
        HotPDF.AutoLaunch := true;
        HotPDF.FileName := 'CanvasDraw.pdf';
        HotPDF.BeginDoc;                                          // Create PDF file
        HotPDF.Canvas.Font.Size := 14;                            // Set canvas font size
        I :=20;
        Y := 60;
        HotPDF.Canvas.TextOut(10, 30, 'Canvas Rectangles');      //  Print text
        while I <= 700 do
        begin                                                   //  Draw colour
            HotPDF.Canvas.Brush.Color := random($FFFFFF);         //  rectangles
            HotPDF.Canvas.Rectangle(I, Y, I+90, Y + 160);
            Inc(I, 30);
            Inc( Y, 3 );
        end;

        I :=20;
        Y := 350;
        HotPDF.Canvas.TextOut(10, 320, 'Canvas Ellipses');         // Print text
        while I <= 700 do                                       //  Draw colour
        begin                                                   //  ellipses
            HotPDF.Canvas.Brush.Color := random($FFFFFF);
            HotPDF.Canvas.Ellipse(I, Y, I+90, Y + 160);
            Inc(I, 30);
            Inc( Y, 3 );
        end;

        I :=20;
        Y := 680;
        HotPDF.Canvas.TextOut(10, 650, 'Canvas RoundRects');      // Print text
        while I <= 700 do
        begin
            HotPDF.Canvas.Brush.Color := random($FFFFFF);         //  Draw colour
            HotPDF.Canvas.RoundRect(I, Y, I+90, Y + 160, 20, 20); //  roundrects
            Inc(I, 30);                                         
            Inc( Y, 3 );
        end;
        HotPDF.EndDoc;                                            // Close PDF file
    finally
        HotPDF.Free;
    end;
end.

HotPDF Table To PDF

HotPDF Component Database Table To PDF sample

program TableDemo;
{$APPTYPE CONSOLE}
{ Reduce EXE size by disabling as much of RTTI as possible }
{$IFDEF VER210}
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
{$ENDIF}

uses
  {$IFDEF VER230}System.Classes, System.SysUtils, Vcl.Graphics, DB, DBTables,
  {$ELSE} Classes, SysUtils, Graphics, DB, DBTables,
  {$ENDIF} HPDFDoc;

var
  HotPDF: THotPDF;
  PageNum, VertPos: Integer;
  CustomerTable: TTable;
  Back: boolean;

procedure PrintRow(Position: Integer; No, Company, Addr, City: AnsiString; ShowBackground: boolean);
begin
  if ShowBackground then
  begin
    HotPDF.CurrentPage.SetRGBColor($FFF3DD);
    HotPDF.CurrentPage.Rectangle(50, Position, 520, 20);
    HotPDF.CurrentPage.Fill;
    HotPDF.CurrentPage.SetRGBColor(clBlack);
  end;
  HotPDF.CurrentPage.TextOut(70, Position, 0, No);
  HotPDF.CurrentPage.TextOut(110, Position, 0, Company);
  HotPDF.CurrentPage.TextOut(300, Position, 0, Addr);
  HotPDF.CurrentPage.TextOut(480, Position, 0, City);
end;

procedure PreparePage;
begin
  HotPDF.CurrentPage.SetFont('Arial', [fsItalic], 10);
  HotPDF.CurrentPage.TextOut(50, VertPos, 0, 'customer.db' + '  Page' + AnsiString(IntToStr(PageNum)));
  HotPDF.CurrentPage.TextOut(480, VertPos, 0, AnsiString(DateTimeToStr(Now)));
  HotPDF.CurrentPage.MoveTo(50, VertPos + 15);
  HotPDF.CurrentPage.LineTo(570, VertPos + 15);
  HotPDF.CurrentPage.MoveTo(50, VertPos + 45);
  HotPDF.CurrentPage.LineTo(570, VertPos + 45);
  HotPDF.CurrentPage.Stroke;
  HotPDF.CurrentPage.SetFont('Times New Roman', [fsItalic, fsBold], 12);
  HotPDF.CurrentPage.SetRGBFillColor(clNavy);
  PrintRow(VertPos + 25, 'No', 'Company', 'Addr', 'City', false);
  HotPDF.CurrentPage.SetRGBFillColor(clBlack);
  Inc(VertPos, 20);
end;

begin
  CustomerTable := TTable.Create(nil);
  try
    CustomerTable.DatabaseName := 'DBDEMOS';
    CustomerTable.TableName := GetCurrentDir + '\customer.db';
    CustomerTable.Active := true;
    CustomerTable.First;
    HotPDF := THotPDF.Create(nil);
    try
      HotPDF.AutoLaunch := true;
      HotPDF.FileName := 'TableDemo.pdf';
      HotPDF.PageLayout := plOneColumn;
      HotPDF.BeginDoc;
      HotPDF.CurrentPage.SetFont('Arial', [fsBold], 24);
      HotPDF.CurrentPage.TextOut(200, 20, 0, 'Customer report'); // Print PDF header
      PageNum := 1;
      VertPos := 60;
      PreparePage; // Table header
      Back := true;
      while (not(CustomerTable.Eof)) do
      begin
        Back := not(Back);
        if (VertPos > 700) then // If end of page then
        begin
          HotPDF.AddPage; // Add page, draw and print
          Inc(PageNum);   // table header and set
          VertPos := 60;  // new print position
          PreparePage;
        end;
        PrintRow(VertPos + 25, // print row from the current position
          AnsiString(CustomerTable.FieldValues['CustNo']), AnsiString(CustomerTable.FieldValues['Company']),
          AnsiString(CustomerTable.FieldValues['Addr1']), AnsiString(CustomerTable.FieldValues['City']), Back);
        Inc(VertPos, 20);
        CustomerTable.Next;
      end;
      HotPDF.EndDoc;
    finally
      HotPDF.Free;
    end;
  finally
    CustomerTable.Free;
  end;

end.

HotPDF Chart Sample

This HotPDF Component example show charts in PDF document using TeeChart.

unit ChartUnit;

interface

uses
  {$IF CompilerVersion >= 16} Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, VclTee.TeeGDIPlus, VclTee.TeEngine, VclTee.Series, VclTee.TeeProcs, VclTee.Chart,
  {$ELSE}Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart,
  {$ENDIF} HPDFDoc;

type
  TForm1 = class(TForm)
    RadioGroup1: TRadioGroup;
    DemoChart: TChart;
    BarSeries1: TBarSeries;
    BarSeries2: TBarSeries;
    BarSeries3: TBarSeries;
    Panel1: TPanel;
    Label1: TLabel;
    RadioGroup2: TRadioGroup;
    ComboBox1: TComboBox;
    Button1: TButton;
    procedure RadioGroup1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure RadioGroup2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  Case RadioGroup1.ItemIndex of
    0: BarSeries1.MultiBar:=mbNone;
    1: BarSeries1.MultiBar:=mbSide;
    2: BarSeries1.MultiBar:=mbStacked;
    3: BarSeries1.MultiBar:=mbStacked100;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  H: Integer;
begin
  DemoChart.View3D:=False;
  Randomize;
  {$IFDEF VER220}
  with BarSeries1 do
  	for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  with BarSeries2 do
  	for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  with BarSeries3 do
  for H:=1 to 12 do Add( Random(100),FormatSettings.ShortMonthNames[H],clTeeColor);
  {$ELSE}
  with BarSeries1 do
  	for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  with BarSeries2 do
  	for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  with BarSeries3 do
  for H:=1 to 12 do Add( Random(100),ShortMonthNames[H],clTeeColor);
  {$ENDIF}
  ComboBox1.Items.Clear;
  for H:=0 to DemoChart.SeriesCount-1 do
    ComboBox1.Items.Add(DemoChart.Series[H].Name);
  ComboBox1.ItemIndex:=0;
end;

procedure TForm1.RadioGroup2Click(Sender: TObject);
begin
  With DemoChart.Series[ComboBox1.ItemIndex] as TBarSeries do
    BarStyle:=TBarStyle(RadioGroup2.Itemindex);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  HotPDF: THotPDF;
  ChartRect: TRect;
begin
  HotPDF := THotPDF.Create(nil);
  try
    case RadioGroup1.ItemIndex of
      0: HotPDF.FileName := 'PDFChart-Behind.pdf';
      1: HotPDF.FileName := 'PDFChart-SideToSide.pdf';
      2: HotPDF.FileName := 'PDFChart-Stacked.pdf';
      3: HotPDF.FileName := 'PDFChart-Stacked100.pdf';
    end;
    HotPDF.BeginDoc;
    ChartRect.Left := 0;
    ChartRect.Right := 800;
    ChartRect.Top := 0;
    ChartRect.Bottom := 600;
    DemoChart.PrintPartialCanvas( HotPDF.CurrentPage.Canvas, ChartRect );
    HotPDF.EndDoc;
  finally
    HotPDF.Free;
  end;
end;

end.

HotPDF Barcode Sample

This HotPDF Component example generates barcode within PDF for 22 popular types.

program Barcodes;
{$APPTYPE CONSOLE}

uses
{$IFDEF VER230} System.Classes, System.SysUtils, Vcl.Graphics,
{$ELSE} Classes, SysUtils, Graphics, {$ENDIF} HPDFDoc;

var
   I, H: Integer;
   HotPDF: THotPDF;

const
  Names: array[0..21] of string =
  (
    'Code 25 Interleaved',
    'Code 25 Industrial',
    'Code 25 Matrix',
    'Code39',
    'Code39 Extended',
    'Code128A',
    'Code128B',
    'Code128C',
    'Code93',
    'Code93 Extended',
    'MSI',
    'PostNet',
    'Codebar',
    'EAN8',
    'EAN13',
    'UPC_A',
    'UPC_E0',
    'UPC_E1',
    'UPC Supp2',
    'UPC Supp5',
    'EAN128A',
    'EAN128B'
    );

begin
  HotPDF:= THotPDF.Create(nil);
  try
    HotPDF.AutoLaunch := true;
    HotPDF.FileName := 'Barcodes.pdf';
    HotPDF.BeginDoc;
    for I := 0 to 7 do
    begin
      for H := 0 to 2 do
      begin
        if ((I * 3) + H) > 21 then Break;
        HotPDF.CurrentPage.DrawBarcode( THPDFBarcodeType((I * 3) + H),    // Draw Black barcode
          H * 266 + 67, I * 133 + 69,       // on the white background
          50, 1, 0, '12345', true, 0, clWhite );  // Draw 12345
        HotPDF.CurrentPage.TextOut( H * 200 + 50, I * 100 + 35, 0, Names[(I * 3) + H] );   // Print barcode name
      end;
    end;
    HotPDF.EndDoc;
  finally
    HotPDF.Free;
  end;
end.

HotPDF Hyperlink Sample

This HotPDF Component Sample adds clickable hyperlinks into PDF document.

unit Main;

interface

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

type
  TForm1 = class(TForm)
    HotPDF: THotPDF;
    HelloWorldButton: TButton;
    edtWeb: TEdit;
    edtProduct: TEdit;
    edtOrder: TEdit;
    edtContact: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure HelloWorldButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.HelloWorldButtonClick(Sender: TObject);
begin
    HotPDF.BeginDoc;
    HotPDF.CurrentPage.SetFont( 'Microsoft Sans Serif', [], 13 );

    HotPDF.CurrentPage.TextOut(20,30,0,'Clickable links:');
    HotPDF.CurrentPage.PrintHyperlink(20, 60, 'Company site: ' + edtWeb.Text, edtWeb.Text);
    HotPDF.CurrentPage.PrintHyperlink(20, 80, 'Product page: ' + edtProduct.Text, edtProduct.Text);
    HotPDF.CurrentPage.SetRGBHyperlinkColor(clRed);
    HotPDF.CurrentPage.PrintHyperlink(20, 100, 'Purchase link: ' + edtOrder.Text, edtOrder.Text);
    HotPDF.CurrentPage.SetRGBHyperlinkColor(clBlue);
    HotPDF.CurrentPage.PrintHyperlink(20, 120, 'Contact form: ' + edtContact.Text, edtContact.Text);

    HotPDF.EndDoc;
end;

end.

HotPDF Text Annotation

This HotPDF Component sample adds a text annotation at the specified location of the PDF document.

program Annotation;
{$APPTYPE CONSOLE}

uses
{$IFDEF VER230} System.Classes, System.SysUtils, Vcl.Graphics,
{$ELSE} Classes, SysUtils, Graphics, {$ENDIF} HPDFDoc;

var
  HotPDF: THotPDF;
begin
  HotPDF := THotPDF.Create(nil);
  try
    HotPDF.FileName := 'Annotation.pdf';
    HotPDF.BeginDoc;
    HotPDF.CurrentPage.TextOut(120,65,0,'Click the icon:');
    HotPDF.CurrentPage.AddTextAnnotation( 'This is a text annotation.' + #13#10  
      + 'Dies ist eine Textanmerkung.' + #13#10
      + 'Ceci est une annotation textuelle.' + #13#10, 
      Rect(120, 80, 140, 100), true, taComment, clBlue );
    HotPDF.EndDoc;
  finally
    HotPDF.Free;
  end;
end.