![]() |
Vermeiden von Application.Processmessages
Zitat:
Create nur 1x! Doch nochmal zum Thread Thema Beispiel alt:
Delphi-Quellcode:
Beispiel neu:
procedure TMainForm.FormCreate(Sender: TObject);
begin LeftPanel.Width := 100; RightPanel.Width := 100; // Center Panel is align Client... Aber wie groß jetzt Application.Processmessages; Width_für_neue_Berechnung := CenterPanel.Width; Berechne_Element_auf_CenterPanel(Width_für_neue_Berechnung); ... end;
Delphi-Quellcode:
Mavarik
procedure TMainForm.FormCreate(Sender: TObject);
begin LeftPanel.Width := 100; RightPanel.Width := 100; TThread.Queue(NIL,Procedure () begin Width_für_neue_Berechnung := CenterPanel.Width; Berechne_Element_auf_CenterPanel(Width_für_neue_Berechnung); end); // In der Hoffnung hier den Wert nicht auch zu brauchen... end; |
AW: Vernichten von Application.Processmessages
Zitat:
Delphi-Quellcode:
Das sind zwar zwei Zeilen mehr als es im OnCreate zu machen, aber eine Boolean-Variable ist im Vergleich zu einem
type
TBaseForm = class(TForm) procedure FormActivate(Sender: TObject); private var firstActivateHappened: Boolean; public procedure initGUI(); virtual; end; procedure TBaseForm.initGUI(); begin // Empty end; procedure TBaseForm.FormActivate(Sender: TObject); begin if (not firstActivateHappened) then begin initGUI(); firstActivateHappened := True; end; inherited; end;
Delphi-Quellcode:
oder
TThread.Queue(..)
Delphi-Quellcode:
so herrlich unspektakulär ;-)
Application.ProcessMessages()
Du hättest nun einfach
Delphi-Quellcode:
Genau für Dinge wie "Wie groß ist das Element nun?" nehme ich immer "meine"
procedure TMainForm.initGUI();
begin inherited; Berechne_Element_auf_CenterPanel(CenterPanel.Width); end;
Delphi-Quellcode:
-Lösung und war damit eigentlich immer glücklich.
OnActivate
|
AW: Vernichten von Application.Processmessages
Ich hab sowas in OnShow ebenfalls mit einer Variable FirstShow.
|
AW: Vernichten von Application.Processmessages
Ja, das wäre ja genau das gleiche. :-) Ich meine, ich hatte irgendeinen Grund,
Delphi-Quellcode:
statt
OnActivate
Delphi-Quellcode:
zu nehmen. Wenn ich nicht falsch liege, kommt erst
OnShow
Delphi-Quellcode:
, dann
OnShow
Delphi-Quellcode:
.
OnActivate
|
AW: Vernichten von Application.Processmessages
Hier mal ein Best Practice und DontDo Beispiel
Delphi-Quellcode:
unit Form.Main;
interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FMX.Controls.Presentation, FMX.StdCtrls; type TForm1 = class( TForm ) ToolBar1: TToolBar; Text1: TText; Label1: TLabel; procedure FormCreate( Sender: TObject ); private procedure MeasureTextControl( AText: TText ); procedure QueueMeasureTextControl( AText: TText ); procedure DontDoMeasureTextControl( AText: TText ); public end; var Form1: TForm1; implementation {$R *.fmx} { TForm1 } procedure TForm1.FormCreate( Sender: TObject ); begin Text1.Align := TAlignLayout.Client; // funktioniert // MeasureTextControl( Text1 ); // funktioniert - Best Practice QueueMeasureTextControl( Text1 ); // Fehlerhafte Darstellung // DontDoMeasureTextControl( Text1 ); end; procedure TForm1.DontDoMeasureTextControl( AText: TText ); begin Application.ProcessMessages; MeasureTextControl( AText ); end; procedure TForm1.MeasureTextControl( AText: TText ); begin Label1.Text := AText.Width.ToString; end; procedure TForm1.QueueMeasureTextControl( AText: TText ); begin TThread.Queue( nil, procedure begin MeasureTextControl( AText ); end ); end; end. |
AW: Vernichten von Application.Processmessages
TThread.Queue kannst du dir an der Stelle sparen, da es sofort ausgeführt wird.
(zumindestens in Windows, aber vermutlich auch im NextGen usw.) ![]() |
AW: Vernichten von Application.Processmessages
Zitat:
Hatte ich inzwischen schon geändert... in einen OnIdle Handler... |
AW: Vernichten von Application.Processmessages
Ja, ja ... :stupid:
Dann ebend so ... menno :mrgreen:
Delphi-Quellcode:
Gut, dafür braucht man einen ThreadHelper
procedure TForm1.QueueMeasureTextControl( AText: TText );
begin TThread.ExecLater<TText>( MeasureTextControl, AText ); end;
Delphi-Quellcode:
unit ThreadHelper;
interface uses System.Classes, System.SysUtils; type TThreadHelper = class helper for TThread class procedure ExecLater( AProc: TProc ); overload; class procedure ExecLater<T>( AProc: TProc<T>; AArg: T ); overload; class procedure ExecLater<T1, T2>( AProc: TProc<T1, T2>; AArg1: T1; AArg2: T2 ); overload; class procedure ExecLater<T1, T2, T3>( AProc: TProc<T1, T2, T3>; AArg1: T1; AArg2: T2; AArg3: T3 ); overload; class procedure ExecLater<T1, T2, T3, T4>( AProc: TProc<T1, T2, T3, T4>; AArg1: T1; AArg2: T2; AArg3: T3; AArg4: T4 ); overload; end; implementation { TThreadHelper } class procedure TThreadHelper.ExecLater( AProc: TProc ); begin TThread.CreateAnonymousThread( procedure begin TThread.Current.Synchronize( procedure begin AProc( ); end ); end ).Start( ); end; class procedure TThreadHelper.ExecLater<T1, T2, T3, T4>( AProc: TProc<T1, T2, T3, T4>; AArg1: T1; AArg2: T2; AArg3: T3; AArg4: T4 ); begin TThread.CreateAnonymousThread( procedure begin TThread.Current.Synchronize( procedure begin AProc( AArg1, AArg2, AArg3, AArg4 ); end ); end ).Start( ); end; class procedure TThreadHelper.ExecLater<T1, T2, T3>( AProc: TProc<T1, T2, T3>; AArg1: T1; AArg2: T2; AArg3: T3 ); begin TThread.CreateAnonymousThread( procedure begin TThread.Current.Synchronize( procedure begin AProc( AArg1, AArg2, AArg3 ); end ); end ).Start( ); end; class procedure TThreadHelper.ExecLater<T1, T2>( AProc: TProc<T1, T2>; AArg1: T1; AArg2: T2 ); begin TThread.CreateAnonymousThread( procedure begin TThread.Current.Synchronize( procedure begin AProc( AArg1, AArg2 ); end ); end ).Start( ); end; class procedure TThreadHelper.ExecLater<T>( AProc: TProc<T>; AArg: T ); begin TThread.CreateAnonymousThread( procedure begin TThread.Current.Synchronize( procedure begin AProc( AArg ); end ); end ).Start( ); end; end. |
AW: Vermeiden von Application.Processmessages
Ich habe mir erlaubt, den Themen-Titel anzupassen.
Vermutlich geht es eher um "vermeiden" als "vernichten". |
AW: Vernichten von Application.Processmessages
Zitat:
Delphi-Quellcode:
Die selbe Funktionalität wie oben, nur mit weniger Code.
type
TBaseForm = class(TForm) procedure FormActivate(Sender: TObject); public procedure initGUI(); virtual; end; procedure TBaseForm.initGUI(); begin // Empty end; procedure TBaseForm.FormActivate(Sender: TObject); begin OnActivate = nil; initGUI(); firstActivateHappened := True; inherited; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:55 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