diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..565c1d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/backup/ +*.log +*.o +*.or +*.ppu +*.compiled + +Copier +Copini \ No newline at end of file diff --git a/Copier.lpi b/Copier.lpi new file mode 100644 index 0000000..36d3455 --- /dev/null +++ b/Copier.lpi @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <i18n> + <EnableI18N LFM="False"/> + </i18n> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="LCL"/> + </Item1> + </RequiredPackages> + <Units Count="2"> + <Unit0> + <Filename Value="Copier.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="Main.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="frmMain"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit1> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="delphi"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/Copier.lpr b/Copier.lpr new file mode 100644 index 0000000..f2f8f02 --- /dev/null +++ b/Copier.lpr @@ -0,0 +1,14 @@ +program Copier; + +uses + Forms, Interfaces, + Main in 'Main.pas' {frmMain}; + +{.$R *.RES} + +begin + Application.Initialize; + Application.Title := 'Copier'; + Application.CreateForm(TfrmMain, frmMain); + Application.Run; +end. diff --git a/Copier.lps b/Copier.lps new file mode 100644 index 0000000..921cc26 --- /dev/null +++ b/Copier.lps @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <Version Value="10"/> + <BuildModes Active="Default"/> + <Units Count="4"> + <Unit0> + <Filename Value="Copier.lpr"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="-1"/> + <CursorPos Y="3"/> + <UsageCount Value="22"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit0> + <Unit1> + <Filename Value="Main.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="frmMain"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <IsVisibleTab Value="True"/> + <EditorIndex Value="-1"/> + <TopLine Value="404"/> + <CursorPos X="15" Y="429"/> + <UsageCount Value="22"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit1> + <Unit2> + <Filename Value="/usr/share/fpcsrc/3.0.4/rtl/inc/systemh.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="1196"/> + <CursorPos X="11" Y="1214"/> + <UsageCount Value="11"/> + </Unit2> + <Unit3> + <Filename Value="Main.lfm"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + <DefaultSyntaxHighlighter Value="LFM"/> + </Unit3> + </Units> + <General> + <ActiveWindowIndexAtStart Value="-1"/> + </General> + <JumpHistory HistoryIndex="-1"/> + </ProjectSession> +</CONFIG> diff --git a/Main.lfm b/Main.lfm new file mode 100644 index 0000000..e2fdeb8 --- /dev/null +++ b/Main.lfm @@ -0,0 +1,138 @@ +object frmMain: TfrmMain + Left = 140 + Height = 294 + Top = 201 + Width = 397 + Caption = 'Midnight Copier' + ClientHeight = 294 + ClientWidth = 397 + Color = clBtnFace + Constraints.MinHeight = 190 + Constraints.MinWidth = 250 + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'MS Sans Serif' + KeyPreview = True + OnClose = FormClose + OnCreate = FormCreate + OnDestroy = FormDestroy + OnKeyDown = FormKeyDown + OnResize = FormResize + Position = poScreenCenter + LCLVersion = '1.8.4.0' + object Label5: TLabel + Left = 135 + Height = 13 + Top = 277 + Width = 249 + Anchors = [akRight, akBottom] + Caption = '©2004 Copyright by Midnight Entertainment' + ParentColor = False + end + object iProgress: TImage + Left = 8 + Height = 25 + Top = 80 + Width = 380 + Anchors = [akTop, akLeft, akRight] + OnPaint = iProgressPaint + end + object Label1: TLabel + Left = 8 + Height = 13 + Top = 16 + Width = 32 + Caption = 'From:' + ParentColor = False + end + object Label2: TLabel + Left = 8 + Height = 13 + Top = 48 + Width = 16 + Caption = 'To:' + ParentColor = False + end + object eSrcFile: TEdit + Left = 40 + Height = 30 + Top = 8 + Width = 237 + Anchors = [akTop, akLeft, akRight] + TabOrder = 0 + end + object eDestFile: TEdit + Left = 40 + Height = 30 + Top = 40 + Width = 237 + Anchors = [akTop, akLeft, akRight] + TabOrder = 1 + end + object bCopy: TButton + Left = 315 + Height = 30 + Top = 8 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Copy' + Default = True + OnClick = bCopyClick + TabOrder = 2 + end + object bSrc: TButton + Left = 283 + Height = 30 + Top = 8 + Width = 29 + Anchors = [akTop, akRight] + Caption = '...' + OnClick = bSrcClick + TabOrder = 3 + end + object bDest: TButton + Left = 283 + Height = 30 + Top = 40 + Width = 29 + Anchors = [akTop, akRight] + Caption = '...' + OnClick = bDestClick + TabOrder = 4 + end + object bCancel: TButton + Left = 315 + Height = 30 + Top = 40 + Width = 75 + Anchors = [akTop, akRight] + Caption = 'Cancel' + OnClick = bCancelClick + TabOrder = 5 + end + object mReport: TMemo + Left = 8 + Height = 164 + Top = 112 + Width = 380 + Anchors = [akTop, akLeft, akRight, akBottom] + Color = clBtnFace + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Courier New' + ParentFont = False + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 6 + end + object odSrc: TOpenDialog + Options = [ofNoChangeDir, ofExtensionDifferent, ofEnableSizing, ofForceShowHidden] + left = 232 + top = 72 + end + object sdDest: TSaveDialog + Options = [ofNoChangeDir, ofExtensionDifferent, ofNoReadOnlyReturn, ofEnableSizing, ofForceShowHidden] + left = 264 + top = 72 + end +end diff --git a/Main.pas b/Main.pas new file mode 100644 index 0000000..e596e28 --- /dev/null +++ b/Main.pas @@ -0,0 +1,582 @@ +unit Main; + +interface + +uses + SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + StdCtrls, ExtCtrls, LCLType; + +type + + { TfrmMain } + + TfrmMain = class(TForm) + eSrcFile: TEdit; + eDestFile: TEdit; + bCopy: TButton; + iProgress: TImage; + Label1: TLabel; + Label2: TLabel; + bSrc: TButton; + bDest: TButton; + Label5: TLabel; + odSrc: TOpenDialog; + sdDest: TSaveDialog; + bCancel: TButton; + mReport: TMemo; + procedure bCopyClick(Sender: TObject); + procedure bSrcClick(Sender: TObject); + procedure bDestClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure bCancelClick(Sender: TObject); + procedure FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); + procedure FormResize(Sender: TObject); + procedure FormClose(Sender: TObject; var Action: TCloseAction); + procedure iProgressPaint(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + + PZone = ^TZone; + TZone = record + sStart : integer; + sEnd : integer; + BlkSize : integer; + Error : boolean; + Prev : PZone; + Next : PZone; + Current : boolean; + ErrZone : boolean; + end; + +const + MaxBlkSize = 4096; + MinBlkSize = 4096; + +var + frmMain: TfrmMain; + + Cancel: boolean; + CurZone: PZone; + ErrZones: PZone; + fSize: integer; + InfoFile: string; + IniFile: string; + OldTime: double; + LockCopy: boolean; + CancelErrors: boolean; + +implementation + +{$R *.lfm} + +function IntToStrEx(Value: integer): string; +var + str : string; + n : integer; +begin + str:=IntToStr(Value); + Result:=''; n:=0; + while length(str)>0 do begin + Result := str[length(str)]+Result; + str := copy(str, 1, length(str)-1); + Inc(n); + if (length(str)>0) and (n=3) then begin + n:=0; + Result := Chr(39)+Result; + end; + end; +end; + +function UpInt(Value: Extended): integer; +begin + Result := trunc(Value); + if Result<Value then Inc(Result); +end; + +procedure SaveIni; +var + f : textfile; +begin + AssignFile(f, IniFile); ReWrite(f); + WriteLn(f, frmMain.eSrcFile.Text); + WriteLn(f, frmMain.eDestFile.Text); + Write(f, frmMain.mReport.Lines.Text); + CloseFile(f); +end; + +procedure LoadIni; +var + f : textfile; + str : string; +begin + if FileExists(IniFile) then begin + AssignFile(f, IniFile); Reset(f); + ReadLn(f, str); + frmMain.eSrcFile.Text := str; + ReadLn(f, str); + frmMain.eDestFile.Text := str; + while not eof(f) do begin + ReadLn(f, str); + frmMain.mReport.Lines.Add(str); + end; + CloseFile(f); + end; +end; + +procedure AddZoneBefore(Zone, ZoneListItem: PZone); +begin + Zone.Next := ZoneListItem; + if Zone.Next<>nil then begin + Zone.Prev := Zone.Next.Prev; + Zone.Next.Prev := Zone; + if Zone.Prev<>nil then Zone.Prev.Next:=Zone; + end else Zone.Prev := nil; +end; + +procedure AddZoneAfter(Zone, ZoneListItem: PZone); +begin + Zone.Prev := ZoneListItem; + if Zone.Prev<>nil then begin + Zone.Next := Zone.Prev.Next; + Zone.Prev.Next := Zone; + if Zone.Next<>nil then Zone.Next.Prev:=Zone; + end else Zone.Next := nil; +end; + +procedure RemoveZone(Zone: PZone); +begin + if Zone.Prev<>nil then Zone.Prev.Next:=Zone.Next; + if Zone.Next<>nil then Zone.Next.Prev:=Zone.Prev; +end; + +function FindFirstZone(Zone: PZone): PZone; +begin + Result := Zone; + if Result<>nil then while Result.Prev<>nil do Result:=Result.Prev; +end; + +procedure DisposeZoneList(var Zone: PZone); +var + z: PZone; +begin + Zone := FindFirstZone(Zone); + while Zone<>nil do begin + z := Zone.Next; + Dispose(Zone); + Zone := z; + end; +end; + +function FindMaxZone(Zone: PZone): PZone; +begin + Result := FindFirstZone(Zone); + Zone := Result; + while Zone<>nil do begin + if ((not Zone.Error) and Result.Error) + or ((Zone.Error=Result.Error) and ((Zone.sEnd-Zone.sStart)>(Result.sEnd-Result.sStart))) then + Result := Zone; + Zone := Zone.Next; + end; +end; + + +procedure MoveToError(Zone: PZone); +var + z : PZone; +begin + RemoveZone(Zone); + + z:=ErrZones; + while (z<>nil) and (z.next<>nil) and (z.sEnd<Zone.sStart) do z:=z.Next; + if (z<>nil) and (z.sEnd<=Zone.sStart) then AddZoneAfter(Zone, z) else AddZoneBefore(Zone, z); + + if (Zone.Prev<>nil) and (Zone.Prev.sEnd=Zone.sStart) then begin + Zone.sStart:=Zone.Prev.sStart; + z := Zone.Prev; + RemoveZone(z); + Dispose(z); + end; + if (Zone.Next<>nil) and (Zone.Next.sStart=Zone.sEnd) then begin + Zone.sEnd:=Zone.Next.sEnd; + z := Zone.Next; + RemoveZone(z); + Dispose(z); + end; + + ErrZones := FindFirstZone(Zone); +end; + +procedure GenerateReport; +var + z : PZone; + str : string; + Text, ns : string; + ncp, dmg : integer; +begin + if fSize=0 then exit; + z := FindFirstZone(CurZone); + ncp := 0; + ns := Chr(13); + Text := 'Remained Blocks:'+ns; + while z<>nil do begin + str := IntToHex(z.sStart, 8)+':'+IntToHex(z.sEnd, 8)+' - '; + if z.Error then str:=str+'Read Error' else str:=str+'Copying'; + Text := Text+str+ns; + ncp := ncp+z.sEnd-z.sStart; + z:=z.Next; + end; + + z := ErrZones; + dmg := 0; + Text := Text+'Damaged Blocks:'+ns; + while z<>nil do begin + str := IntToHex(z.sStart, 8)+':'+IntToHex(z.sEnd, 8); + Text := Text+str+ns; + dmg := dmg+z.sEnd-z.sStart; + z:=z.Next; + end; + + str := 'Damaged: '+IntToStrEx(dmg)+' ('+FloatToStr(round((dmg)/fSize*10000)*0.01)+'%)'; + Text := str+ns+Text; + str := 'Remained: '+IntToStrEx(ncp)+' ('+FloatToStr(round((ncp)/fSize*10000)*0.01)+'%)'; + Text := str+ns+Text; + str := 'Copied: '+IntToStrEx(fSize-ncp-dmg)+' ('+FloatToStr(round((fSize-ncp-dmg)/fSize*10000)*0.01)+'%)'; + Text := str+ns+Text; + str := 'File Size: '+IntToStrEx(fSize); + Text := str+ns+Text; + + frmMain.mReport.Lines.Text := Text; +end; + +procedure SaveCopyInfo; +var + f : file of TZone; + z : PZone; +begin + if InfoFile='' then exit; + if (CurZone<>nil) or (ErrZones<>nil) then begin + AssignFile(f, InfoFile); + ReWrite(f); + z := FindFirstZone(CurZone); + while z<>nil do begin + z.Current := (z=CurZone); + z.ErrZone := (z=ErrZones); + write(f, z^); + z:=z.Next; + end; + z := ErrZones; + while z<>nil do begin + z.Current := (z=CurZone); + z.ErrZone := (z=ErrZones); + write(f, z^); + z:=z.Next; + end; + CloseFile(f); + end else DeleteFile(InfoFile); +end; + +procedure LoadCopyInfo; +var + f : file of TZone; + z, z2 : PZone; + asked : boolean; +begin + DisposeZoneList(CurZone); + DisposeZoneList(ErrZones); + asked:=false; + if FileExists(InfoFile) then begin + AssignFile(f, InfoFile); + Reset(f); + z2 := nil; + while not eof(f) do begin + New(z); + read(f, z^); + if (not asked) and (z.Error or z.ErrZone or (z.BlkSize<>MaxBlkSize)) then begin + CancelErrors := mrYes=MessageDlg('Reread error blocks?', mtConfirmation, [mbYes, mbNo], 0); + asked := true; + end; + if CancelErrors then begin + z.Error := False; + z.BlkSize := MaxBlkSize; + z.ErrZone := False; + end; + if z.Current then CurZone:=z; + if z.ErrZone then begin + ErrZones:=z; + z2:=nil; + end; + AddZoneAfter(z, z2); + z2:=z; + end; + if CancelErrors then CurZone:=FindMaxZone(z2); + CloseFile(f); + end else begin + New(CurZone); + CurZone.sStart := 0; + CurZone.sEnd := fSize; + CurZone.BlkSize := MaxBlkSize; + CurZone.Error := False; + CurZone.Prev := nil; + CurZone.Next := nil; + end; +end; + +procedure DrawZones; +var + z : PZone; + s : integer; + r, r2 : TRect; + str : string; + bmp : TBitmap; +begin + with frmMain.iProgress do begin + r.Top:=1; r.Left:=1; r.Right:=Width-1; r.Bottom:=Height-1; + Canvas.Brush.Color := clBlue; + if fSize=0 then Canvas.Brush.Color := clWhite; + Canvas.FillRect(r); + Canvas.Brush.Color := clWhite; + z := FindFirstZone(CurZone); + s := 0; + while z<>nil do begin + r.Left := 1+trunc(z.sStart/fSize*(Width-2)); + r.Right := 1+trunc(z.sEnd/fSize*(Width-2)); + s := s+z.sEnd-z.sStart; + Canvas.FillRect(r); + z:=z.Next; + end; + Canvas.Brush.Color := clRed; + z := ErrZones; + while z<>nil do begin + r.Left := 1+trunc(z.sStart/fSize*(Width-2)); + r.Right := r.Left+UpInt((z.sEnd-z.sStart)/fSize*(Width-2)); + Canvas.FillRect(r); + z:=z.Next; + end; + Canvas.Brush.Color := clRed; + z := FindFirstZone(CurZone); + while z<>nil do begin + if z.Error then begin + r.Left := 1+trunc(z.sStart/fSize*(Width-2)); + r.Right := r.Left+1; + Canvas.FillRect(r); + end; + z:=z.Next; + end; + if fSize<>0 then begin + bmp := TBitmap.Create; + str:=FloatToStr(round((1-s/fSize)*1000)*0.1)+'%'; + bmp.Width := bmp.Canvas.TextWidth(str); + bmp.Height := bmp.Canvas.TextHeight(str); + bmp.Canvas.Brush.Color := clBlack; + bmp.Canvas.Font.Color := clWhite; + bmp.Canvas.TextOut(0, 0, str); + r.Left:=trunc((Width-bmp.Width)/2); + r.Top:=trunc((Height-bmp.Height)/2); + r.Right:=r.Left+bmp.Width; + r.Bottom:=r.Top+bmp.Height; + r2.Left:=0; r2.Top:=0; r2.Right:=bmp.Width; r2.Bottom:=bmp.Height; + Canvas.CopyMode := cmSrcInvert; + Canvas.CopyRect(r, bmp.Canvas, r2); + bmp.Free; + end; + Canvas.Brush.Style := bsClear; + Canvas.Pen.Color := clBlack; + r.Top:=0; r.Left:=0; r.Right:=Width; r.Bottom:=Height; + Canvas.Rectangle(r); + Canvas.Brush.Style := bsSolid; + end; + SaveCopyInfo; + GenerateReport; + LockCopy:=True; + Application.ProcessMessages; + LockCopy:=False; + OldTime:=Time*24*3600; +end; + +procedure CopyFile(Src, Dest: string); +var + SrcFile : file; + DestFile : file; + e : integer; + Res, IORes : integer; + z : PZone; + Buffer : array[0..MaxBlkSize] of byte; + DlgRes : Word; + rewr : boolean; +begin + InfoFile := Dest+'.copyinfo'; + if not FileExists(Src) then begin + ShowMessage('Source file not found'); + exit; + end; + rewr:=true; + if FileExists(Dest) then begin + if FileExists(InfoFile) then begin + DlgRes := MessageDlg('Do you want to continue last copying of this file?', mtConfirmation, mbYesNoCancel, 0); + if DlgRes=mrNo then DeleteFile(InfoFile) else + if DlgRes=mrYes then rewr:=false else exit; + end else begin + DlgRes := MessageDlg('Destination file already exists. Do you want to overwrite it?', mtConfirmation, mbOkCancel, 0); + if DlgRes<>mrOk then exit; + end; + end; + AssignFile(SrcFile, Src); + AssignFile(DestFile, Dest); + FileMode := fmOpenRead; + Reset(SrcFile, 1); + fSize:=FileSize(SrcFile); + FileMode := fmOpenReadWrite; + if rewr then ReWrite(DestFile, 1) else Reset(DestFile, 1); + LoadCopyInfo; + + {$IOCHECKS OFF} + while CurZone<>nil do begin + if Cancel then break; + if CurZone.Error then CurZone:=FindMaxZone(CurZone); + if CurZone.Error then begin + e := (trunc((CurZone.sStart+CurZone.sEnd)/2) div MinBlkSize)*MinBlkSize; + if e<=CurZone.sStart then e:=e+MinBlkSize; + if e>=CurZone.sEnd then begin + if CurZone.Prev<>nil then z:=CurZone.Prev else z:=CurZone.Next; + MoveToError(CurZone); + CurZone:=FindMaxZone(z); + end else begin + New(z); + z.BlkSize := MaxBlkSize; + z.sStart := e; + z.sEnd := CurZone.sEnd; + z.Error := False; + CurZone.sEnd := e; + AddZoneAfter(z, CurZone); + if CurZone.sEnd-CurZone.sStart<=MinBlkSize then MoveToError(CurZone); + CurZone := FindMaxZone(z); + end; + DrawZones; + end else begin + if CurZone.sEnd-CurZone.sStart>0 then begin + Seek(SrcFile, CurZone.sStart); + if CurZone.sEnd-CurZone.sStart<CurZone.BlkSize then CurZone.BlkSize:=CurZone.sEnd-CurZone.sStart; + BlockRead(SrcFile, Buffer, CurZone.BlkSize, Res); + IORes := IOResult; + if IORes<>0 then Res:=0; + if Res=0 then begin + if CurZone.BlkSize<=MinBlkSize then CurZone.Error:=True else CurZone.BlkSize:=MinBlkSize; + end else begin + Seek(DestFile, CurZone.sStart); + BlockWrite(DestFile, Buffer, Res); + end; + CurZone.sStart:=CurZone.sStart+Res; + if Time*24*3600-OldTime>=0.05 then DrawZones; + end; + if CurZone.sEnd-CurZone.sStart<=0 then begin + if CurZone.Prev<>nil then z:=CurZone.Prev else z:=CurZone.Next; + RemoveZone(CurZone); + Dispose(CurZone); + CurZone := FindMaxZone(z); + DrawZones; + end; + end; + end; + {$IOCHECKS ON} + CloseFile(SrcFile); + CloseFile(DestFile); + DrawZones; + DisposeZoneList(CurZone); + DisposeZoneList(ErrZones); + if not Cancel then beep; +end; + +procedure ClearVars; +begin + Cancel:=False; + CurZone:=nil; + ErrZones:=nil; + LockCopy:=False; + CancelErrors:=False; + InfoFile:=''; + fSize:=0; +end; + +procedure TfrmMain.bCopyClick(Sender: TObject); +begin + if not LockCopy then begin + ClearVars; + SaveIni; + CopyFile(eSrcFile.Text, eDestFile.Text); + ClearVars; + DrawZones; + SaveIni; + end; +end; + +procedure TfrmMain.bSrcClick(Sender: TObject); +begin + odSrc.FileName:=eSrcFile.Text; + if odSrc.Execute then eSrcFile.Text:=odSrc.FileName; +end; + +procedure TfrmMain.bDestClick(Sender: TObject); +var + n: integer; + path, fname: string; +begin + n:=Length(eSrcFile.Text); + while n>0 do + if eSrcFile.Text[n]='\' then break else Dec(n); + fname:=copy(eSrcFile.Text, n+1, Length(eSrcFile.Text)-n); + n:=Length(eDestFile.Text); + while n>0 do + if eDestFile.Text[n]='\' then break else Dec(n); + path:=copy(eDestFile.Text, 1, n); + sdDest.FileName:=path+fname; + if sdDest.Execute then eDestFile.Text:=sdDest.FileName; +end; + +procedure TfrmMain.FormCreate(Sender: TObject); +begin + ClearVars; + DrawZones; + IniFile := copy(Application.ExeName, 1, length(Application.ExeName)-3)+'ini'; + LoadIni; +end; + +procedure TfrmMain.FormDestroy(Sender: TObject); +begin + SaveIni; +end; + +procedure TfrmMain.bCancelClick(Sender: TObject); +begin + Cancel:=true; +end; + +procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word; + Shift: TShiftState); +begin +// if (Key=VK_F2) and (CurZone<>nil) then CurZone.Error:=true; + if Key=VK_ESCAPE then Cancel:=true; +end; + +procedure TfrmMain.FormResize(Sender: TObject); +begin + DrawZones; +end; + +procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); +begin + Cancel := true; +end; + +procedure TfrmMain.iProgressPaint(Sender: TObject); +begin + DrawZones; +end; + +end. + + diff --git a/copier.res b/copier.res new file mode 100644 index 0000000..067a453 Binary files /dev/null and b/copier.res differ