Einzelnen Beitrag anzeigen

Benutzerbild von Sko
Sko

Registriert seit: 11. Sep 2005
327 Beiträge
 
Turbo Delphi für Win32
 
#16

Re: Probleme mit Frames und deren Aktualisierung in Formular

  Alt 29. Jun 2006, 23:33
Ich habs jetzt so gebaut wie in omata´s Beispiel, das ist genau das was ich wollte, vielen Dank nochmal dafür . Aber ich glaub ich hab da irgendwas bei der Anpassung falsch gemacht: wenn das Fenster, in das die Frames kommen, schon vor der Erstellung des Frames angezeigt wird, friert das Programm ab dem Zeitpunkt der Erstellung des Frames für die Dauer der Datenübertragung ein und beim Beenden des Programms kommt "Ungültiges Fensterhandle", außerdem wird der Frame sofort nach der Übertragung vom Formular entfernt, das hab ich - jedenfalls bewusst - garnicht eingebaut. Wenn das Fenster geschlossen ist, und ich es nach dem Zeitpunkt der Erstellung des Frames erst öffne, geht alles, nichts ist eingefroren, alles läuft wie´s soll und der Frame bleibt auch nach dem Ende der Übertragung da . Hier mal die entsprechenden Code-Schnipsel, ich hoffe ihr könnt mir helfen:

Hier wird das erstellen ausgelöst:
Delphi-Quellcode:
procedure TMainForm.TCPReceiverExecute(AContext: TIdContext);
var
  SizeOfIncomingStream: Integer;
  IDS: TidStreamVCL;
  DateiFrame: TFDatei;
  Target, DGroesse: string;
  DStream: TFileStream;
begin
  if DateiGroesse < 1048576 then DGroesse := RealToStr(DateiGroesse/1024) + ' KB'; //Dateigröße ist eine globale int64 Variable
  if DateiGroesse > 1048576 then DGroesse := RealToStr(DateiGroesse/1024/1024) + ' MB';
  if DateiGroesse > 1073741824 then DGroesse := RealToStr(DateiGroesse/1024/1024/1024) + ' GB';
  DateiFrame := FDownLoad.add(Target, DGroesse); //<-hier wird der Frame erstellt
  DStream := DateiFrame.FStream;
  Application.ProcessMessages;
  try
    IDS := TidStreamVCL.Create(DStream);
    try
      with AContext.connection do
      begin
        try
          SizeOfIncomingStream := Socket.ReadInteger;
          Socket.ReadStream(IDS, SizeOfIncomingStream);
        finally
          Disconnect;
        end;
      end;
      IDS.VCLStream.Position := 0;
    finally
      FreeAndNil(IDS);
    end;
  finally
    with DateiFrame do
    begin
      Bar.Position := 100;
      Fertig := true;
      FStream.Free;
    end;
  end;
end;
So sieht das der Code für´s Downloadfenster aus:
Delphi-Quellcode:
unit DownLoadForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Math, EmpfDatei, StdCtrls;

type
  TLoadForm = class(TForm)
    SBDateien: TScrollBox;
    BAuf: TButton;
    procedure BAufClick(Sender: TObject);
  private
    { Private-Deklarationen }
    DownloadListe: TList;
    LTimer: TTimer;
  public
    { Public-Deklarationen }
    constructor create(AOwner:TComponent); reintroduce;
    destructor destroy; override;
    procedure TimerUpdate(Sender:TObject);
    function add(Dateiname, Dateigroesse: string): TFDatei;
    procedure del(Index:integer);
    function count:integer;
  end;

var
  LoadForm: TLoadForm;

implementation

{$R *.dfm}

function TLoadForm.count: integer;
begin
  Result := DownloadListe.Count;
end;

constructor TLoadForm.create(AOwner: TComponent);
begin
  inherited create(AOwner);
  DownloadListe:=TList.Create;
  LTimer := TTimer.Create(Self);
  LTimer.Interval := 500;
  LTimer.Enabled := false;
  LTimer.OnTimer := TimerUpdate;
end;

destructor TLoadForm.destroy;
var
  i: integer;
begin
  for i := 1 to DownloadListe.Count do
    TFDatei(DownloadListe[i-1]).free;
  DownloadListe.free;
  LTimer.free;
  inherited;
end;

procedure TLoadForm.TimerUpdate(Sender: TObject);
var i:integer;
begin
  for i:=1 to DownloadListe.Count do
    TFDatei(DownloadListe[i-1]).Refresh;
  Application.ProcessMessages;
end;

function TLoadForm.add(Dateiname, Dateigroesse: string): TFDatei;
var
  FrameDownload: TFDatei;
  ID, i: integer;
begin
  i := 0;
  ID := 0;
  while (i < DownloadListe.Count) do
  begin
    ID := Max(ID, TFDatei(DownloadListe[i]).ID);
    inc(i);
  end;
  inc(ID);
  FrameDownload:=TFDatei.create(Self, ID, Dateiname, Dateigroesse);
  FrameDownload.Parent:=SBDateien;
  FrameDownload.Align:=alTop;
  LTimer.Enabled := true;
  DownloadListe.Add(FrameDownload);
  for i := 1 to DownloadListe.Count do
    TFDatei(DownloadListe[i-1]).Align:=alBottom;
  for i := 1 to DownloadListe.Count do
    TFDatei(DownloadListe[i-1]).Align:=alTop;
  result := FrameDownload;
  BAuf.Enabled:=(DownloadListe.Count > 0);
end;

procedure TLoadForm.del(Index: integer);
begin
  if (Index >= 0) and (Index < DownloadListe.Count) then begin
    TFDatei(DownloadListe[Index]).free;
    DownloadListe.Delete(Index);
    LTimer.Enabled := (DownloadListe.Count > 0);
    BAuf.Enabled := (DownloadListe.Count > 0);
  end;
end;

procedure TLoadForm.BAufClick(Sender: TObject);
var
  i: integer;
begin
  i := 0;
  while (i < DownloadListe.Count) do
  begin
    if TFDatei(DownloadListe[i]).Fertig then
    begin
      del(i);
    end
    else
      inc(i);
  end;
end;

end.
und so der Code vom Frame:
Delphi-Quellcode:
unit EmpfDatei;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ComCtrls, StdCtrls, ShellAPI;

type
  TFDatei = class(TFrame)
    Label1: TLabel;
    Label2: TLabel;
    LName: TLabel;
    LGroesse: TLabel;
    Bar: TProgressBar;
    Label3: TLabel;
    IIcon: TImage;
    LTyp: TLabel;
    Bevel1: TBevel;
  private
    { Private-Deklarationen }
    DID: integer;
  public
    FileName: String;
    DateiGroesse: Int64;
    FStream: TFileStream;
    DFertig: boolean;
    constructor create(AOwner:TComponent;
                       ID:integer;
                       Dateiname, Dateigroesse: string); reintroduce;
    destructor destroy; override;
    procedure Refresh;
    property Fertig: boolean read DFertig write DFertig;
    property ID: integer read DID;
  end;

implementation

uses ErwEinstellungen, Main;

{$R *.dfm}

function FileIcon(FileName: String): TIcon;
var
  FileInfo: TSHFileInfo;
  AIcon: TIcon;
begin
  FillChar(FileInfo,SizeOf(FileInfo),#0);
  SHGetFileInfo(PChar(FileName),0,FileInfo,SizeOf(FileInfo),SHGFI_ICON or SHGFI_LARGEICON);
  AIcon:=TIcon.Create;
  Try
    AIcon.Handle:=FileInfo.HIcon;
    AIcon.Transparent:=True;
  Except end;
  Result:=AIcon;
end;

function FileType(FileName: String): string;
var
  FileInfo: TSHFileInfo;
begin
  FillChar(FileInfo,SizeOf(FileInfo),#0);
  SHGetFileInfo(PChar(FileName),0,FileInfo,SizeOf(FileInfo),SHGFI_TYPENAME);
  Result := FileInfo.szTypeName;
end;

constructor TFDatei.create(AOwner: TComponent;
                                  ID:integer;
                                  Dateiname, Dateigroesse:string);
begin
  inherited create(AOwner);
  Self.Name := 'FrameDownload' + IntToStr(ID);
  LName.Caption := ExtractFileName(Dateiname);
  LTyp.Caption := FileType(Dateiname);
  LGroesse.Caption := Dateigroesse;
  IIcon.Picture.Icon := FileIcon(DateiName);
  FStream := TFileStream.Create(Dateiname, fmCreate);
  DFertig:=false;
  DID := ID;
end;

destructor TFDatei.destroy;
begin
  inherited;
end;

procedure TFDatei.Refresh;
begin
  if not DFertig then
  begin
    if (FStream <> nil) and (FStream.Position <> 0) then
      Bar.Position := round((FStream.Position * 100) / FStream.Size);
  end;
  Bar.Update;
end;

end.
MfG Sko
Zitat von Phoenix:
[OT]Phoenix guckt in die Glaskugel, zuckt mit den Flügelspitzen, krächzt etwas von wegen 'Boden' und 'Scherben' und schubbst die Kugel in Richtung Tischkante.[/OT]
Rockbox
  Mit Zitat antworten Zitat