Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=26)
-   -   Abrir archivos con nombres de archivos de otra codificación. (https://www.clubdelphi.com/foros/showthread.php?t=55851)

matabyte 29-04-2008 05:46:56

Abrir archivos con nombres de archivos de otra codificación.
 
Bueno, lo pongo aquí porque creo que afecta a Windows.

Uso Windows XP y Delphi 2007.

El caso es que cuando intento abrir un archivo usando un TStream o un TOpenDialog, y el nombre del archivo está en otra codificación de la de Windows (Por ejemplo, un nombre de archivo en Japonés con Windows en Español o a la inversa), Delphi me tira el programa diciendo que el archivo no es válido.

Se que aún Dephi no es Unicode completamente (aunque se pueden usar las WideStrings). No se si es problema del propio delphi o de los componentes.

He intentado usar el OpenDialog del "TNT Unicode Controls" y funciona correctamente, pero el TFileStream de Delphi tiene la propiedad "FileName" igual a string, con lo que no puede usar el archivo unicode.

¿Sabéis algún sistema para manejar esos archivos con Delphi, a poder ser con un TStream? ¿o hay que esperar a la versión 2008?

Gracias ^_^

cHackAll 30-04-2008 17:27:45

Analizando una unidad de los propios componentes que citaste, podemos formarnos algúnas ideas a implementar;

1. Ataquemos a la clase TFileStream, la cual sobrecargada tiene un método útil de la clase padre (THandleStream), de creación que permite inicializar por manejador "FHandle"
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
 var FindData: TWin32FindDataW; Stream: TFileStream;
 begin
  Windows.FindClose(FindFirstFileW('*.jpg', FindData)); // solo para obtener el nombre del primer archivo JPEG, esperando tenga su nombre en UNICODE
 Stream := TFileStream.Create(CreateFileW(@FindData.cFileName, GENERIC_READ, FILE_SHARE_READ + FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0));
 
 ...
Donde la API CreateFileW es la encargada de archivo en modo UNICODE dado el nombre brindado en este caso por FindFirstFileW.

2. Podríamos hasta realizar nuestra propia clase sobrecargando el método;
Código Delphi [-]
uses RTLConsts;
  
 type
  TFileStreamW = class(TFileStream)
   constructor Create(const lpFileName: PWideChar); overload;
  end;
 
 constructor TFileStreamW.Create(const lpFileName: PWideChar);
 begin
  inherited Create(CreateFileW(lpFileName, GENERIC_READ, FILE_SHARE_READ + FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0));
  if FHandle < 0 then
   raise EFCreateError.CreateResFmt(@SFCreateErrorEx, [ExpandFileName(lpFileName), SysErrorMessage(GetLastError)]);
 end;
Utilizándola de igual forma;
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
 var FindData: TWin32FindDataW; Stream: TFileStreamW;
 begin
  Windows.FindClose(FindFirstFileW('*.jpg', FindData));
  Stream := TFileStreamW.Create(@FindData.cFileName);
 
 ...
Hasta podemos idearnos una 3ra forma más sencilla sin conocimientos de POO;
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
 var
  FindData: TWin32FindDataW; 
  FileName: array [0..MAX_PATH-1] of WideChar;
  Stream: TFileStream;
 begin
  Windows.FindClose(FindFirstFileW('*.jpg', FindData)); 
  GetShortPathNameW(@FindData.cFileName, @FileName, SizeOf(FileName));
  Stream := TFileStream.Create(string(WideString(@FileName)), fmOpenRead);
 
...
Donde la API GetShortPathNameW está obteniendo el antigüo nombre 8.3 accesible por la VCL.

Nota; Para obtener el nombre del archivo con la intervencion del usuario, en lugar de usar la API FindFirstFileW, debemos utilizar la API GetOpenFileNameW abstraída de TOpenDialog con su apropiada estructura TOpenFilenameW.

Como verás depende netamente de la habilidad del programador, no así de la version del IDE

Saludos

matabyte 01-05-2008 01:40:13

Muchas gracias por la explicación:D. Como era Delphi el que tenía el objeto del TFileStream no había pensado en crear una subclase para eso! Muy buena idea, me has solucionado mucho ^_^


La franja horaria es GMT +2. Ahora son las 13:58:54.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi