AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CopyFileEx

Ein Thema von Luckie · begonnen am 7. Aug 2004 · letzter Beitrag vom 10. Mär 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

CopyFileEx

  Alt 7. Aug 2004, 14:19
So, ich habe gerade ein Beispiel für das Kopieren einer Datei mit Fortschrittsanzeige mit Hilfe von MSDN-Library durchsuchenCopyFileEx geschrieben:
Delphi-Quellcode:
var
  Form1: TForm1;
  CancelCopy: Boolean;

implementation

{$R *.dfm}

function CopyFileProgress(TotalFileSize, TotalBytesTransferred, StreamSize,
  StreamBytesTransferred: LARGE_INTEGER; dwStreamNumber, dwCallbackReason,
  hSourceFile, hDestinationFile, lpData: DWORD): DWORD; stdcall;
begin
  Application.ProcessMessages;
  if CancelCopy = True then
  begin
    ShowMessage('Abbruch');
    result := PROGRESS_CANCEL;
  end;
  case dwCallbackReason of
    CALLBACK_CHUNK_FINISHED:
      begin
        Form1.ProgressBar1.Position := TotalBytesTransferred.QuadPart;
        result := PROGRESS_CONTINUE;
      end;
    CALLBACK_STREAM_SWITCH:
      begin
        Form1.ProgressBar1.Max := TotalFileSize.QuadPart;
        result := PROGRESS_CONTINUE;
      end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Cancel: PBOOL;
begin
  CancelCopy := False;
  Cancel := nil;
  CopyFileEx('g:\Brennen\Madonna - Erotica.mpg', 'g:\Madonna - Erotica.mpg',
    @CopyFileProgress, nil, Cancel, 0);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  CancelCopy := True;;
end;
Nur ein Problem habe ich: Das Abbrechen funktioniert nicht. Er geht zwar in den if-Zweig rein, aber er ruft die Callback Routine immer wieder auf, obwohl ich PROGRESS_CANCEL zurückgebe.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
NicoDE
(Gast)

n/a Beiträge
 
#2

Re: CopyFileEx

  Alt 7. Aug 2004, 14:46
Versuchs mit
Delphi-Quellcode:
  if CancelCopy = True then
  begin
    ShowMessage('Abbruch');
    Result := PROGRESS_CANCEL;
    Exit;
  end
  else
    Application.ProcessMessages;
BTW, Application.ProcessMessages führt eine Ansychronität ein, die Du vermutlich nicht haben willst. Und Du solltest bei Abbruch die Funktion verlassen, sonst wird Dein Result wieder überschrieben. Zudem ist auf den ersten Blick der Rückgabewert nicht immer definiert (noch nicht ganz wach?).

Gruss Nico
  Mit Zitat antworten Zitat
wolke

Registriert seit: 10. Mai 2005
Ort: Dresden
12 Beiträge
 
#3

Re: CopyFileEx

  Alt 3. Sep 2005, 02:22
^hochhol.

danke für den code. wenn Application.ProcessMessages nicht empfehlenswert ist, was gibt es als alternative? ich will ja nicht daß mein programm nicht mehr reagiert.

kann ich die priorität des kopierprozesses durch die priorität meines programmes beeinflussen?

ich habe den code so abgeändert, daß statt PROGRESS_CANCEL ein PROGRESS_STOP zurückgegeben wird, zusätzlich setze ich als flag COPY_FILE_RESTARTABLE. wenn ich nun die aktion stoppe und nochmal starte sollte er doch fortsetzen, tut es aber nicht. wieso?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: CopyFileEx

  Alt 3. Sep 2005, 02:36
Threads wären besser:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ProgressBar1: TProgressBar;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WndProc(var Msg: TMessage); override;
  end;

var
  Form1 : TForm1;

implementation

{$R *.dfm}

type
  TCopyEx = packed record
    Source: String[255];
    Dest: String[255];
    Handle: THandle;
  end;
  PCopyEx = ^TCopyEx;

const
  CEXM_CANCEL = WM_USER + 1;
  CEXM_CONTINUE = WM_USER + 2; // wParam: lopart, lParam: hipart
  CEXM_MAXBYTES = WM_USER + 3; // wParam: lopart; lParam: hipart

var
  CancelCopy : Boolean = False;

function CopyFileProgress(TotalFileSize, TotalBytesTransferred, StreamSize,
  StreamBytesTransferred: LARGE_INTEGER; dwStreamNumber, dwCallbackReason,
  hSourceFile, hDestinationFile: DWORD; lpData: Pointer): DWORD; stdcall;
begin
  if CancelCopy = True then
  begin
    SendMessage(THandle(lpData), CEXM_CANCEL, 0, 0);
    result := PROGRESS_CANCEL;
    exit;
  end;
  case dwCallbackReason of
    CALLBACK_CHUNK_FINISHED:
      begin
        SendMessage(THandle(lpData), CEXM_CONTINUE, TotalBytesTransferred.LowPart, TotalBytesTransferred.HighPart);
        result := PROGRESS_CONTINUE;
      end;
    CALLBACK_STREAM_SWITCH:
      begin
        SendMessage(THandle(lpData), CEXM_MAXBYTES, TotalFileSize.LowPart, TotalFileSize.HighPart);
        result := PROGRESS_CONTINUE;
      end;
  else
    result := PROGRESS_CONTINUE;
  end;
end;

procedure TForm1.WndProc(var Msg: TMessage);
begin
  inherited;
  case Msg.Msg of
    CEXM_MAXBYTES:
      begin
        ProgressBar1.Max := Msg.WParam + Msg.LParam;
      end;
    CEXM_CONTINUE:
      begin
        Progressbar1.Position := Msg.WParam + Msg.LParam;
        Caption := IntToStr(Msg.WParam + Msg.LParam);
      end;
    CEXM_CANCEL:
    begin
      Progressbar1.Position := 0;
      Caption := '0';
    end;
  end;
end;

function CopyExThread(p: PCopyEx): Integer;
var
  Source: String;
  Dest: String;
  Handle: THandle;
  Cancel : PBool;
begin
  Source := p.Source;
  Dest := p.Dest;
  Handle := p.Handle;
  Cancel := PBOOL(False);

  CopyFileEx(PChar(Source), PChar(Dest), @CopyFileProgress, Pointer(Handle), Cancel, 0);

  Dispose(p);
  result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Params: PCopyEx;
  ThreadID: Cardinal;
begin
  cancelCopy := False;
  New(Params);
  Params.Source := 'H:\Videos ungebrannt\Gwen Stefani - rich girl.mpeg';
  Params.Dest := 'H:\test.mpeg';
  Params.Handle := Handle;
  CloseHandle(BeginThread(nil, 0, @CopyExThread, Params, 0, ThreadID));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  CancelCopy := True;
end;
Ungefähr so.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
wolke

Registriert seit: 10. Mai 2005
Ort: Dresden
12 Beiträge
 
#5

Re: CopyFileEx

  Alt 3. Sep 2005, 02:46
auch noch so spät unterwegs?

wie, threads? also einen thread erstellen, der die kopieraktion dann macht?
habe mich noch nicht wirklich mit threadprogrammierung beschäftigt, kannst du mir ein grobes gerüst zusammenschustern?

ich möchte sehr "performant" viele dateien kopieren/verschieben und kann auf 9x verzichten, habe mir deshalb CopyFileEx/MoveFileEx herausgesucht. vielleicht mache ichs aber doch mit blockread/write, weil ich dann bei netzwerkkopieraktionen den durchsatz limitieren kann.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: CopyFileEx

  Alt 3. Sep 2005, 03:43
Zitat von wolke:
auch noch so spät unterwegs?
Ich musste den zweiten Teil von Richter Alexander Holt noch sehen. Man muss ja wissen, wer der Mörder ist.

Zitat:
wie, threads? also einen thread erstellen, der die kopieraktion dann macht?
habe mich noch nicht wirklich mit threadprogrammierung beschäftigt, kannst du mir ein grobes gerüst zusammenschustern?
Jupp, genau wie ich es oben gezeigt habe. Das mit Application.Processmessage war nur eine Quick and Dirty Lösung.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
wolke

Registriert seit: 10. Mai 2005
Ort: Dresden
12 Beiträge
 
#7

Re: CopyFileEx

  Alt 3. Sep 2005, 11:24
danke!

nachdem du deinen beitrag editiert hast schaut es jetzt so aus als hätte ich um 4 uhr morgens nur nicht gesehen daß du ja schon ein beispiel gepostet hast!

kann ich die priorität des kopierprozesses durch die priorität meines threads beeinflussen?
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: CopyFileEx

  Alt 3. Sep 2005, 11:29
Sollte möglich sein. Probier es aus. Aber generell würde ich an den Prioritäten nichts ändern, ins besondere, wenn es um das Anheben der Priorität geht. In der Zuteilung von Rechenzeit findet Windows meist schon selber das richtige Maß. Man kann durch Anheben fast mehr kaputt machen, als verbessern.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
wolke

Registriert seit: 10. Mai 2005
Ort: Dresden
12 Beiträge
 
#9

Re: CopyFileEx

  Alt 3. Sep 2005, 12:01
ich möchte die priorität nicht anheben, sondern senken. ich probiers mal, danke.
  Mit Zitat antworten Zitat
masadafish

Registriert seit: 21. Apr 2005
8 Beiträge
 
#10

Re: CopyFileEx

  Alt 8. Apr 2006, 16:23
hi
ich wollt mich zunächst für das tolle beispiel bedanken
aber ich habe ein problem denn sobald ich datein die größer als ca 2gb sind kopieren will stimmt die progressbar nicht mehr da der progrssbar.max wert ja ein integer
ist und msg.lparam und msg.wparam ja auch "nur" integer sind ... steh ich jetz nur auf der leitung oder ist was wirklich schwierig?
also hat wer ne ahnung wie man das abändern kann das es auch mit größeren datein funzt?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz