Filesize function for Delphi

Erroneous filesize function: (Files bigger than 2GB are shown 2GB)

function FileSize(const aFilename: String): Int64;
var
 info: TWin32FileAttributeData;
begin
 result := -1;

if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then
 EXIT;

result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;

Better filesize function: (sr.FindData is Platform specific warning)

function FileSize(const aFilename: String): Int64;
var
 sr : TSearchRec;
begin
 if FindFirst(aFilename, faAnyFile, sr ) = 0 then
 begin
 result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow);
 end else
 begin
 result := -1;
 end;
 FindClose(sr);
end;

Best way:

function FileSize(const aFilename: String): Int64;
var
 sr : TSearchRec;
begin
 if FindFirst(aFilename, faAnyFile, sr ) = 0 then
 begin
 Result:=Sr.Size;
 end else
 begin
 result := -1;
 end;
 FindClose(sr);
end;
Advertisements

Localization of MessageDlg in Delphi

Built-in MessageDlg function shows texts such as Yes, No, Confirmation only in English.

function MyMessageDlg(CONST Msg: string; DlgTypt: TmsgDlgType; button: TMsgDlgButtons;
 Caption: ARRAY OF string; dlgcaption: string): Integer;
var
 aMsgdlg: TForm;
 i: Integer;
 Dlgbutton: Tbutton;
 Captionindex: Integer;
begin
 aMsgdlg := createMessageDialog(Msg, DlgTypt, button);
 aMsgdlg.Caption := dlgcaption;
//aMsgdlg.BiDiMode := bdRightToLeft;
 Captionindex := 0;
 for i := 0 to aMsgdlg.componentcount - 1 Do
 begin
 if (aMsgdlg.components[i] is Tbutton) then
 Begin
 Dlgbutton := Tbutton(aMsgdlg.components[i]);
 if Captionindex <= High(Caption) then
 Dlgbutton.Caption := Caption[Captionindex];
 inc(Captionindex);
 end;
 end;
 Result := aMsgdlg.Showmodal;
end;

Get ShellExecute Error in Delphi

ExecuteResult:=ShellExecute(Handle, 'open', PChar(filename), nil, nil, SW_HIDE);

case ExecuteResult of
 0 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The operating system is out of memory or resources.');
 2 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The specified file was not found.');
 3 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The specified path was not found.');
 5 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 only: The operating system denied access to the specified file.');
 8 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 only: There was not enough memory to complete the operation.');
 10 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Wrong Windows version.');
 11 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).');
 12 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Application was designed for a different operating system.');
 13 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Application was designed for MS-DOS 4.0.');
 15 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to load a real-mode program.');
 16 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to load a second instance of an application with non-readonly data segments.');
 19 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Attempt to load a compressed application file.');
 20 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Dynamic-link library (DLL) file failure.');
 26 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': A sharing violation occurred.');
 27 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The filename association is incomplete or invalid.');
 28 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE transaction could not be completed because the request timed out.');
 29 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE transaction failed.');
 30 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': The DDE transaction could not be completed because other DDE transactions were being processed.');
 31 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': There is no application associated with the given filename extension.');
 32 : ShowMessage('Error ' + IntToStr(ExecuteResult) + ': Windows 95 only: The specified dynamic-link library was not found.');
 end;

Get Windows Language in English

function GetLocaleInformation(Flag: Integer): string;
var
 pcLCA: array [0..20] of Char;
begin
 if GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, Flag, pcLCA, 19) <= 0 then
 pcLCA[0] := #0;
 Result := pcLCA;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
 ShowMessage(GetLocaleInformation(LOCALE_SENGLANGUAGE));
end;

Result are like:

French

German

Japanese

TPath.DirectorySeparatorChar

(Delphi uses System.IOUtils)

Different versions of Windows seem to behave differently (e.g. \ and / both work on the English versions)

¥ : Japanese version

₩ : Korean version

While the ₩ and ¥ characters are shown as directory separator symbols in the respective Korean and Japanese windows versions, they are only how those versions of Windows represent the same Unicode code point U+005c as a glyph. The underlying code point for backslash is still the same across English Windows and the Japanese and Korean windows versions.

Also, I don’t know of any Windows API function that gets you the system’s path separator, but you can rely on it being \ in all circumstances.

Note File I/O functions in the Windows API convert “/” to “\” as part of converting the name to an NT-style name, except when using the “\?\” prefix as detailed in the following sections.

IO handler is not valid error in Delphi

Indy Tidhttp component complains “IO handler is not valid” when the original URL redirects to a HTTPS url.

Solution: Use a TIdSSLIOHandlerSocketOpenSSL

uses IdSSLOpenSSL

Also copy SSL DLL (libeay32.dll, ssleay32.dll)

var
  Http: TIdHTTP;
  MS: TMemoryStream;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  Http := TIdHTTP.Create(nil);
  Http.HandleRedirects:=True;
  try
    MS := TMemoryStream.Create;
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      Http.IOHandler:=LHandler;
      Http.OnWork:= HttpWork;
      Http.OnRedirect:= HttpRedirect;
//    Http.RedirectMaximum:=9;
      Http.Get(urlfile, MS);
      MS.SaveToFile(filename);
    finally
      MS.Free;
      LHandler.Free;
    end;
  finally
    Http.Free;
  end;
end;