[Lazarus-es] problema con Unicode y CreateFileW

islanis en infomed.sld.cu islanis en infomed.sld.cu
Mar Oct 14 21:35:16 CEST 2014


uff y veo que se me quedaron algunas cosillas importantes,bueno acá se  
los dejo mejor y mas reducido de donde sale sourcefile

SourceFile:=FileItem.SrcFullName;

y FileItem sale de la clase TCopier es de tipo TFileItem


o sea que sal de acá

CurrentCopy:record
			FileItem:TFileItem;
			DirItem:TDirItem;
			CopiedSize,SkippedSize:Int64;
			NextAction:TCopyAction;
		end;


y acá les dejo la clase TFileItem

Saludos Ale y gracias de antemano

//-----------------SCFileList.pas---------------------------------
{
     This file is part of SuperCopier.

     SuperCopier is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

     SuperCopier is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
}

unit SCFileList;

{$MODE Delphi}

interface
uses SCCommon,SCDirList,Classes,SCObjectThreadList, FileUtil, Windows;

const
   FILELIST_DATA_VERSION=001;

type
	TFileList=class;

	TFileItem=class
	private
     Owner:TFileList;
	public
     BaseListId:Integer;

     CopyTryCount:Integer;

		SrcName,
		DestName:WideString;
		SrcSize:Int64;
		Directory:TDirItem;

     procedure SaveToStream(TheStream:TStream);
     procedure  
LoadFromStream(TheStream:TStream;Version:integer;BaseDirListIndex:Integer);
		function SrcFullName:WideString;
		function DestFullName:WideString;
		function DestSize:Int64;
		function SrcAge:Integer;
		function DestAge:Integer;
		function SrcExists:Boolean;
		function DestExists:Boolean;
		function DestIsSameFile:Boolean;
     function SrcDelete:Boolean;
     function DestDelete:Boolean;
     function DestCopyAttributes:boolean;
     function DestCopySecurity:boolean;
     function DestClearAttributes:boolean;
	end;

	TFileList = class (TObjectThreadList)
   private
     FDirList:TDirList;
     FSortMode:TFileListSortMode;
     FSortReverse:Boolean;
	protected
		function Get(Index: Integer): TFileItem;
		procedure Put(Index: Integer; Item: TFileItem);
	public
		TotalCount:cardinal;
		TotalSize,Size:Int64;

		constructor Create(PDirList:TDirList);
		destructor Destroy; override;

     procedure SaveToStream(TheStream:TStream);
     procedure LoadFromStream(TheStream:TStream);
		function Add(Item: TFileItem): Integer;
		procedure Delete(Index: Integer;UpdateTotalCount:Boolean=False);
     procedure Sort;

		property Items[Index: Integer]: TFileItem read Get write Put; default;
     property SortMode:TFileListSortMode read FSortMode write FSortMode;
     property SortReverse:Boolean read FSortReverse write FSortReverse;
	end;

implementation

uses SCWin32,SysUtils,LCLIntf, LCLType, LMessages, Contnrs, Math;

function FLSortCompare(Item1,Item2:Pointer):Integer;forward;

//******************************************************************************
//******************************************************************************
//******************************************************************************
// TFileItem: fichier а copier
//******************************************************************************
//******************************************************************************
//******************************************************************************

procedure TFileItem.SaveToStream(TheStream:TStream);
var Len,Idx:Integer;
begin
   // version 1
     // On ne peut pas sauvegarder un pointeur, on sauvegarde l'index  
a la place
     // L'index commence de la fin de la liste pour pouvoir retrouver  
le DirItem
     // au chargement alors que la DirList est dйjа chargйe
   Idx:=Owner.FDirList.Count-1-Owner.FDirList.IndexOf(Directory);
   TheStream.Write(Idx,SizeOf(Integer));

   Len:=Length(SrcName);
   TheStream.Write(Len,SizeOf(Integer));
   TheStream.Write(SrcName[1],Len*SizeOf(WideChar));

   Len:=Length(DestName);
   TheStream.Write(Len,SizeOf(Integer));
   TheStream.Write(DestName[1],Len*SizeOf(WideChar));

   TheStream.Write(SrcSize,SizeOf(Int64));
end;

procedure  
TFileItem.LoadFromStream(TheStream:TStream;Version:integer;BaseDirListIndex:Integer);
var Len,Idx:Integer;
begin
   if Version>=001 then
   begin
     TheStream.Read(Idx,SizeOf(Integer));
       // on rйcupиre le DirItem en retranchant а  
l'index du dernier item de DirList
       // l'index sauvegardй
     Directory:=Owner.FDirList[BaseDirListIndex-Idx];



     TheStream.Read(Len,SizeOf(Integer));
     SetLength(SrcName,Len);
     TheStream.Read(SrcName[1],Len*SizeOf(WideChar));

     TheStream.Read(Len,SizeOf(Integer));
     SetLength(DestName,Len);
     TheStream.Read(DestName[1],Len*SizeOf(WideChar));

     TheStream.Read(SrcSize,SizeOf(Int64));
   end;
end;

function TFileItem.SrcFullName:WideString;
begin
   Result:=Concat(Directory.SrcPath,SrcName);
end;

function TFileItem.DestFullName:WideString;
begin
   Result:=Concat(Directory.DestPath,DestName);
end;

function TFileItem.DestSize:Int64;
begin
   Result:=SCCommon.GetFileSizeByName(DestFullName);
end;

function TFileItem.SrcAge:Integer;
begin
	Result:=FileAge(SrcFullName);
end;

function TFileItem.DestAge:Integer;
begin
	Result:=FileAge(DestFullName);
end;

function TFileItem.DestExists:Boolean;
begin
	Result:=FileAge(DestFullName)<>-1;
end;

function TFileItem.SrcExists: Boolean;
begin
	Result:=FileAge(SrcFullName)<>-1;
end;

function TFileItem.DestIsSameFile:Boolean;
begin
	// Deux fichiers sont considйrйs identiques lorsque ils  
ont la mкme taille et la mкme date de derniиre modif
	Result:=(SrcSize=DestSize) and (SrcAge=DestAge);
end;

function TFileItem.SrcDelete:Boolean;
var ErrCode:Integer;

   //HACK: la gestion interne de l'unicode de delphi pourrit le code  
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure SrcDelete_;
   begin
     Result:=SCWin32.DeleteFile(PWideChar(SrcFullName)); { *Converted  
from DeleteFile*  }
     ErrCode:=GetLastOSError;
   end;

begin
   SrcDelete_;
   Windows.SetLastError(ErrCode);
end;

function TFileItem.DestDelete:Boolean;
var ErrCode:Integer;

   //HACK: la gestion interne de l'unicode de delphi pourrit le code  
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestDelete_;
   begin
     Result:=SCWin32.DeleteFile(PWideChar(DestFullName)); { *Converted  
from DeleteFile*  }
     ErrCode:=GetLastError;
   end;

begin
   DestDelete_;
   SetLastError(ErrCode);
end;

function TFileItem.DestCopyAttributes:Boolean;
var Attr:Cardinal;
     ErrCode:Integer;

   //HACK: la gestion interne de l'unicode de delphi pourrit le code  
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestCopyAttributes_;
   begin
     Attr:=SCWin32.GetFileAttributes(PWideChar(SrcFullName));
     Result:=Attr<>$ffffffff;
     if Result then  
Result:=SCWin32.SetFileAttributes(PWideChar(DestFullName),Attr);
     ErrCode:=GetLastError;
   end;

begin
   DestCopyAttributes_;
   SetLastError(ErrCode);
end;

function TFileItem.DestCopySecurity:boolean;
var ErrCode:Integer;

   //HACK: la gestion interne de l'unicode de delphi pourrit le code  
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestCopySecurity_;
   begin
     Result:=CopySecurity(SrcFullName,DestFullName);
     ErrCode:=GetLastError;
   end;

begin
   DestCopySecurity_;
   SetLastError(ErrCode);
end;

function TFileItem.DestClearAttributes:boolean;
var ErrCode:Integer;

   //HACK: la gestion interne de l'unicode de delphi pourrit le code  
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestClearAttributes_;
   begin
      
Result:=SCWin32.SetFileAttributes(PWideChar(DestFullName),FILE_ATTRIBUTE_NORMAL);
     ErrCode:=GetLastError;
   end;

begin
   DestClearAttributes_;
   SetLastError(ErrCode);
end;

//******************************************************************************
//******************************************************************************
//******************************************************************************
// TFileList: liste de fichiers а copier
//******************************************************************************
//******************************************************************************
//******************************************************************************

procedure TFileList.SaveToStream(TheStream:TStream);
var i,Num,Version:integer;
begin
   Version:=FILELIST_DATA_VERSION;
   TheStream.Write(Version,SizeOf(Integer));

   Num:=Count;
   TheStream.Write(Num,SizeOf(Integer));

   for i:=0 to Num-1 do
   begin
     Items[i].SaveToStream(TheStream);
   end;
end;

procedure TFileList.LoadFromStream(TheStream:TStream);
var i,Num,Version:integer;
     FileItem:TFileItem;
     BaseDirListIndex:Integer;
begin
   Version:=000;
   Num:=0;

   TheStream.Read(Version,SizeOf(Integer));
   if Version>FILELIST_DATA_VERSION then raise  
Exception.Create('FileItems: data file is for a newer SuperCopier  
version');

   TheStream.Read(num,SizeOf(Integer));

   BaseDirListIndex:=FDirList.Count-1;
   for i:=0 to Num-1 do
   begin
     FileItem:=TFileItem.Create;
     FileItem.Owner:=Self;
     FileItem.LoadFromStream(TheStream,Version,BaseDirListIndex);
     Add(FileItem);
   end;
end;

function TFileList.Add(Item: TFileItem): Integer;
begin
	// maj des compteurs
	Inc(Size,Item.SrcSize);
   Inc(TotalSize,Item.SrcSize);
   Inc(TotalCount,1);

   Item.Owner:=Self;

	Result:=inherited Add(Item);
end;

procedure TFileList.Delete(Index: Integer;UpdateTotalCount:Boolean=False);
begin
	// maj des compteurs
   if Items[Index]<>nil then
   begin
     Dec(Size,Items[Index].SrcSize);

     if UpdateTotalCount then
     begin
       Dec(TotalSize,Items[Index].SrcSize);
       Dec(TotalCount,1);
     end;
   end;

	inherited Delete(Index);
end;

function TFileList.Get(Index: Integer): TFileItem;
begin
	Result:=TFileItem(inherited Get(Index));
end;

procedure TFileList.Put(Index: Integer; Item: TFileItem);
begin
	inherited Put(Index,Item);
end;

constructor TFileList.Create(PDirList:TDirList);
begin
	inherited Create;

   // init des variables
	TotalCount:=0;
	TotalSize:=0;
   Size:=0;

   FDirList:=PDirList;
   FSortMode:=fsmNone;
   FSortReverse:=False;
end;

destructor TFileList.Destroy;
begin
	inherited Destroy;
end;

procedure TFileList.Sort;
begin
   if Count>1 then inherited Sort(FLSortCompare);
end;

//******************************************************************************
// FLSortCompare: fonction de tri pour la filelist
//******************************************************************************

function FLSortCompare(Item1,Item2:Pointer):Integer;
var FileItem1,FileItem2:TFileItem;
begin
   FileItem1:=TFileItem(Item1);
   FileItem2:=TFileItem(Item2);

   // le premier element de la liste dois rester le premier element de la liste
   // ca il est en train d'кtre copiй
   if FileItem1=FileItem1.Owner.First then
   begin
     Result:=-1;
     Exit;
   end;

   if FileItem2=FileItem2.Owner.First then
   begin
     Result:=1;
     Exit;
   end;

   Result:=0;
   case FileItem1.Owner.SortMode of
     fsmBySrcName:
       Result:=WideCompareText(FileItem1.SrcName,FileItem2.SrcName);
     fsmBySrcFullName:
       Result:=WideCompareText(FileItem1.SrcFullName,FileItem2.SrcFullName);
     fsmByDestName:
       Result:=WideCompareText(FileItem1.DestName,FileItem2.DestName);
     fsmByDestFullName:
       Result:=WideCompareText(FileItem1.DestFullName,FileItem2.DestFullName);
     fsmBySrcSize:
       Result:=CompareValue(FileItem1.SrcSize,FileItem2.SrcSize);
     fsmBySrcExt:
        
Result:=WideCompareText(ExtractFileExt(FileItem1.SrcName),ExtractFileExt(FileItem2.SrcName));
   end;

   if FileItem1.Owner.SortReverse then Result:=-Result;
end;

end.
//---------------------------------------------------------------

José Mejuto <joshyfun en gmail.com> escribió:

> El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribió:
>> Hola estoy tratando de reparar una versión de supercopier que es un
>> programa para copiar archivos y carpetas pero justo en la seccion que
>> les pongo abajo cada vez que el sitema se encuentra una carpeta con
>> tildes el sistema me da una excepción notificandome que no tiene acceso,
>> y justo en el fragmento que les muestro es donde el sistema se engancha
>
> Hola,
>
> Deberías de mostrar también de donde sacas SourceFile, si es un  
> ansistring, un utf8string o qué.
>
> -- 
>
>
> _______________________________________________
> Lazarus-es mailing list
> Lazarus-es en lists.lazarus.freepascal.org
> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
>



----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.



--
Nunca digas nunca, di mejor: gracias, permiso, disculpe.

Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas

Infomed: http://www.sld.cu/





More information about the Lazarus-es mailing list