Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Timer bei fsSTAYONTOP kommt nicht durch (https://www.delphipraxis.net/72307-timer-bei-fsstayontop-kommt-nicht-durch.html)

easywk 28. Jun 2006 13:12


Timer bei fsSTAYONTOP kommt nicht durch
 
Hallo zusammen,

aus meinem Hauptform heraus erzeuge ich ein weiteres Form, dass als FormStyle fsSTAYONTOP hat und mit einem einfachen Show angezeigt wird. In diesem Zusatzform gibt es einen Timer, der enabled ist und ein Interval von 500 hat. Direkt nachdem ich das Zusatzform angezeigt habe läuft im Hauptform ein sehr zeitintensiver Rechenprozess ...

Nun mein Problem: der Timer im Zusatzform kommt nicht durch, es sieht so aus, als ob das Fenster einfach keine Rechenzeit zugeteilt bekommt. Wenn ich im Hauptform in die Rechenroutine ab und an ein Application.Processmessages einfüge, dann kommt der Timer im Zusatzform durch - aber das ist in meinen Augen keine Lösung.

Kann ich es irgendwie erreichen, dass das Zusatzform auch Rechenzeit zugeteilt bekommt? Threads sind keine Lösung, da ich auf dem Form zeichnen muss ...

Thanks for help
Bjoern

SirThornberry 28. Jun 2006 13:18

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
egal wieviel Formulare du hast, sie laufen alle im gleichen Thread ab. Und während in dem Thread etwas gemacht wird können die Nachrichten nicht zeitgliche abgearbeitet werden (somit auch keine Paint-Messages, Timer-Messages etc.). Außer Application.ProcessMessages bleiben dir dann wohl nur noch Threads.

Luckie 28. Jun 2006 13:22

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
Zitat:

Zitat von easywk
Threads sind keine Lösung, da ich auf dem Form zeichnen muss ...

Ja und? Genau deshalb gibt es die Synchronize Methode.

easywk 28. Jun 2006 13:38

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
Zitat:

Zitat von Luckie
Ja und? Genau deshalb gibt es die Synchronize Methode.

Habe ich dann aber nicht wieder das gleiche Problem mit der Botschaftsschleife? Laut OH wartet Synchronize darauf, dass der Hauptthread in die Botschaftsschleife eintritt - und genau das tut der Hauptthread ja nicht

Luckie 28. Jun 2006 13:42

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
Du sollst die Berechnung in einem Thread durchführen und nicht das Formular anzeigen.

easywk 28. Jun 2006 13:56

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
Ok, das wäre eine denkbare Lösung. Da es aber diverse Rechenroutinen gibt wäre es gut, wenn ich dem Thread irgendwie die Routine übergeben könnte, die er ausführen soll ... wo war gleich noch dein Thread-Tutorial? :P

easywk 28. Jun 2006 14:43

Re: Timer bei fsSTAYONTOP kommt nicht durch
 
So, in dieser Lösung übergebe ich dem Zusatzformular die Rechenroutine. Das Formular erzeugt einen Thread, führt in diesem Thread die Rechenroutine aus und zeigt ein "Lebenszeichen" an
Delphi-Quellcode:
type
  TMsgProcedure = procedure of object;

  TMsgThread = class(TThread)
    private
    protected
      Working : Boolean;
      procedure Execute; override;
    public
      ExecProc : TMsgProcedure;
    end;

  TFormWorkMessage = class(TForm)
    LabelMsgText: TLabel;
    Label1: TLabel;
    Image1: TImage;
    ImageList1: TImageList;
    Timer1: TTimer;
  private
    { Private-Deklarationen }
    ImgIndex : Integer;
    MyThread : TMsgThread;
  public
    { Public-Deklarationen }
    procedure ShowMessageAndExec(MsgText:String;ExecProc:TMsgProcedure);
  end;

var
  FormWorkMessage: TFormWorkMessage;

implementation

{$R *.dfm}

{ TFormWorkMessage }

procedure TMsgThread.Execute;
begin
  Working:=TRUE;
  Self.ExecProc;
  Working:=FALSE;
end;

procedure TFormWorkMessage.ShowMessageAndExec(MsgText: String;
  ExecProc:TMsgProcedure);
begin
  ImgIndex:=1;
  LabelMsgText.Caption:=MsgText;
  // Thread für die Rechenoperation initialisieren
  MyThread:=TMsgThread.Create(TRUE);
  MyThread.ExecProc:=ExecProc;
  MyThread.Resume;
  Self.Show;
  // "lebenszeichen" Anzeigen und warten bis der Thread fertig ist
  repeat
    ImageList1.GetBitmap(ImgIndex,Image1.Picture.Bitmap);
    if ImgIndex<ImageList1.Count-1 then
      Inc(ImgIndex)
    else ImgIndex:=0;
    Self.Repaint;
    Sleep(250);
  until not MyThread.Working;
  // ordnungsgemäß beenden
  MyThread.Terminate;
  MyThread.WaitFor;
  MyThread.Free;
  Self.Close;
end;
Meinungen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:22 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 by Thomas Breitkreuz