Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CopyFileProgress: negativer Wert beim Kopieren (https://www.delphipraxis.net/110618-copyfileprogress-negativer-wert-beim-kopieren.html)

Helmi 20. Mär 2008 20:28


CopyFileProgress: negativer Wert beim Kopieren
 
Hallo,

ich hab Luckies CopyFileEx mal ausprobiert
um Dateien größer 2 GB zu kopieren und den Kopiervorgang in einer Progressbar anzeigen zu lassen.

Ich hab mir testweise dann einfach mal die maximale Dateigröße und die bisher kopierte Dateigröße in je einem Label anzeigen lassen und musste feststellen, dass der bisher kopierte Wert auf einmal ins negative umschlägt.

Nur wieso?


Hier mal ein Auszug aus meinem Code zum Anzeigen der Dateigröße und der bisher kopierten Dateigröße:

Delphi-Quellcode:
    CEXM_MAXBYTES:
      begin
//        ProgressBar1.Max := (Int64(Msg.LParam) shl 32) + Msg.WParam;
        Label1.Caption := IntToStr((Int64(Msg.LParam) shl 32) + Msg.WParam);
      end;
    CEXM_CONTINUE:
      begin
//        Progressbar1.Position := (Int64(Msg.LParam) shl 32) + Msg.WParam;
        Caption := IntToStr(Msg.WParam + Msg.LParam);

        Label2.Caption := Caption;
      end;

Fussball-Robby 20. Mär 2008 21:02

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Die Werte werden einfach zu hoch für Integer. Ich weiß es nicht genau, aber müsste es nicht so gehen?
Delphi-Quellcode:
Caption := IntToStr(Int64(Msg.WParam) + Msg.LParam);
Mfg

Helmi 20. Mär 2008 21:12

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Zitat:

Zitat von Fussball-Robby
Die Werte werden einfach zu hoch für Integer. Ich weiß es nicht genau, aber müsste es nicht so gehen?
Delphi-Quellcode:
Caption := IntToStr(Int64(Msg.WParam) + Msg.LParam);

Das hatte ich auch schon ausprobiert - aber es war das selbe

zu groß kanns aber ned sein, denn beim Label1 wird ja ein großer positiver wert angezeigt

Fussball-Robby 20. Mär 2008 21:13

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Zitat:

Zitat von Helmi
zu groß kanns aber ned sein, denn beim Label1 wird ja ein großer positiver wert angezeigt

Weil bei Label1 in Int64 umgerechnet wird.
Delphi-Quellcode:
Caption := IntToStr(Int64(Msg.WParam) + Int64(Msg.LParam));
So?

Helmi 20. Mär 2008 21:21

Re: CopyFileProgress: negativer Wert beim Kopieren
 
hat sich nichts verändert

Fussball-Robby 20. Mär 2008 21:22

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Dann keine Ahnung :?

sx2008 21. Mär 2008 05:21

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Versuchs mal mit Zwischenvariable:
Delphi-Quellcode:
var sz:LARGE_INTEGER; // unit Windows
begin
  sz.LowPart := Msg.WParam;
  sz.HighPart := Msg.LParam;
  Label1.Caption := IntToStr(sz.QuadPart);

wido 27. Mär 2008 11:22

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Zitat:

Zitat von Helmi
Caption := IntToStr(Msg.WParam + Msg.LParam);

Du kannst die Werte aber nicht so einfach addieren - das geht schief. Wird dort wahrscheinlich zu einem Integerüberlauf kommen und die von Dir beobachteten "negativen" Zahlen treten auf. Das lustige ist, Du hast die richtige Lösung auskommentiert:

Delphi-Quellcode:
Progressbar1.Position := (Int64(Msg.LParam) shl 32) + Msg.WParam;
Entsprechend sollte folgendes das gewünschte Ergebnis liefern:

Delphi-Quellcode:
Caption := IntToStr((Int64(Msg.LParam) shl 32) + Msg.WParam);
Du scheinst auch nicht wirklich verstanden zu haben, was der Code genau macht. Von daher versuch ich es Dir mal zu erklären. Vereinfacht gesagt besteht ein INT64 aus 2 normalen Integern. Ein Integer ist 4 Byte groß, ein INT64 entsprechend 8 Byte. Wie stellst Du jetzt auf einem 32 Bit System einen 64 Bit Wert da. Naja, mit Hilfe von 2 32 Bit Werten. Der erste Integer (in unserem Falle LParam) nimmt die ersten 32 Bit des 64 Bit Wertes auf und der zweite Integer die letzten 32 Bit des 64 Bit Integer Wertes. Angenommen wir haben jetzt folgenden Int64 Wert:

Code:
0x1111111122222222
Dieser würde dargestellt werden durch:

Code:
LPARAM = 0x11111111
WPARAM = 0x22222222
Quizfrage:
Was passiert jetzt, wenn ich LPARAM mit WPARAM addiere?

Code:
0x11111111
0x22222222
----------
0x33333333
Das ist aber nicht, was wir eigentlich wollten. Was wir eigentlich wollten ist folgende Addition:
Code:
0x1111111100000000
0x0000000022222222
------------------
0x1111111122222222
Wir müssen also die Bytes von LPARAM nach Links verschieben. Dazu gibt es den Befehl shl (shift left = "Verschiebe nach Links"). Der Befehl "shl 32" bewirkt also, daß der Wert um 32 Bits (oder 4 Bytes) nach links verschoben wird. Nur wenn Du den Wert shiftest, macht die Addition auch das, was Du wirklich erreichen willst.

Ich hoffe mal es ist Dir jetzt klar geworden wo der Fehler war und wieso Du den Wert shiften musst ;).

sx2008 28. Mär 2008 04:24

Re: CopyFileProgress: negativer Wert beim Kopieren
 
Zitat:

Zitat von wido
Wir müssen also die Bytes von LPARAM nach Links verschieben. Dazu gibt es den Befehl shl (shift left = "Verschiebe nach Links"). Der Befehl "shl 32" bewirkt also, daß der Wert um 32 Bits (oder 4 Bytes) nach links verschoben wird. Nur wenn Du den Wert shiftest, macht die Addition auch das, was Du wirklich erreichen willst.

Es ist zwar nicht falsch, was du schreibt, aber mein Vorschlag aus dem Posting davor ist besser.
Man nimmt einfach die beiden 32 Bit Werte und kopiert sie in einen varianten Record (unter C würde man das als Union bezeichen).
Dann kann man die Daten als 64 Bit Wert auslesen.
Das funktioniert 100%ig während man bei Shiften in int64 immer aufpassen muss, dass die oberen 32 Bit nicht abhanden kommen.
Der Compiler ist bei int64 Operationen manchmal etwas zickig und tut nicht immer das, was man erwarten würde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz