Month: April 2019

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.