Usando TWin32FindData para determinar el nombre corto (o nombre DOS) de un archivo

Determinando el nombre corto (nombre DOS) de un archivo

Copyright © 2000 Ernesto De Spirito

Storage Library - Guarde la configuración de su aplicación

TWin32FindData

El campo FindData del registro TSearchRec usado por las funciones FindFirst y FindNext y el procedimiento FindClose, es a su vez otro registro:

type
TWin32FindData = record
  dwFileAttributes: DWORD;
  ftCreationTime: TFileTime;
  ftLastAccessTime: TFileTime;
  ftLastWriteTime: TFileTime;
  nFileSizeHigh: DWORD;
  nFileSizeLow: DWORD;
  dwReserved0: DWORD;
  dwReserved1: DWORD;
  cFileName: array[0..MAX_PATH - 1] of AnsiChar;
  cAlternateFileName: array[0..13] of AnsiChar;
end;

Contiene información adicional, como las fechas de creación, última escritura y último acceso(que se pueden convertir a TDateTime usando FileTime2DateTime), y el nombre corto (nombre DOS o nombre 8.3) de un archivo en el campo cAlternateFileName. Este campo es una cadena terminada en nulo (cero), y estará vacía (el primer caracter es #0) si el nombre largo coincide con el nombre corto.

Por ejemplo, esta función regresaría el nombre corto de un archivo dado:

uses SysUtils;

function ShortName(const FileName: TFileName): TFileName;
var
  SearchRec: TSearchRec;
begin
  if FindFirst(FileName, faAnyFile, SearchRec) = 0 then begin
    if SearchRec.FindData.cAlternateFileName[0] = #0 then
      Result := SearchRec.Name
    else
      Result := SearchRec.FindData.cAlternateFileName;
    FindClose(SearchRec);
  end else
    Result := '';
end;

Para convertir de TFileTime a TDateTime puede usar la siguiente función:

uses Windows;

function FileTime2DateTime(FileTime: TFileTime): TDateTime;
var
  FileDate: record
    DosTime, DosDate: Word;
  end;
begin
  FileTimeToDosDateTime(FileTime, FileDate.DosDate,
    FileDate.DosTime);
  Result := FileDateToDateTime(PInteger(@FileDate)^);
end;

GetShortPathName

Windows provee una API para obtener el nombre corto de un archivo (incluyendo la versión corta del camino si se incluye un camino). Aquí escribimos una función para encapsular la llamada a esta API:

uses SysUtils, Windows;

function GetShortFilename(const FileName: TFileName): TFileName;
var
  buffer: array[0..MAX_PATH-1] of char;
begin
  SetString(Result, buffer, GetShortPathName(
    pchar(FileName), buffer, MAX_PATH-1));
end;
JfControls Library - para Delphi y C++ Builder