Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#28

AW: KeyPress unter Form2 funktioniert nicht.

  Alt 12. Mai 2014, 12:46
Ich habe mal ein ganz simples Beispiel-Programm geschrieben was hierzu passt.

Zentrales Element ist diese Unit hier
Delphi-Quellcode:
unit Container_Data;

interface

uses
  Classes,
  SyncObjs;

type
  TData = record
    Value1 : Integer;
    Value2 : Integer;
    Value3 : Integer;
  end;
  
  TDataContainer = class
  private
    FCS : TCriticalSection;
    FData : TData;
    function GetData : TData;
    procedure SetData( const Value : TData );
  public
    constructor Create;
    destructor Destroy; override;

    property Data : TData read GetData write SetData;
  end;

  // Daten-Sammler
  TDataThread = class( TThread )
  private
    FContainer : TDataContainer;
  protected
    procedure Execute; override;
  public
    constructor Create( AContainer : TDataContainer );
  end;

implementation

{ TDataContainer }

constructor TDataContainer.Create;
begin
  FCS := TCriticalSection.Create;
  inherited Create;
end;

destructor TDataContainer.Destroy;
begin

  inherited;
  FCS.Free;
end;

function TDataContainer.GetData : TData;
begin
  FCS.Enter;
  try
    Result := FData;
  finally
    FCS.Leave;
  end;
end;

procedure TDataContainer.SetData( const Value : TData );
begin
  FCS.Enter;
  try
    FData := Value;
  finally
    FCS.Leave;
  end;
end;

{ TDataThread }

constructor TDataThread.Create( AContainer : TDataContainer );
begin
  inherited Create( False );
  FContainer := AContainer;
end;

procedure TDataThread.Execute;
var
  LData : TData;
begin
  inherited;
  LData := FContainer.Data;
  while not Terminated do
    begin
      case Random( 3 ) of
        0 :
          LData.Value1 := Random( 101 );
        1 :
          LData.Value2 := Random( 101 );
        2 :
          LData.Value3 := Random( 101 );
      end;
      FContainer.Data := LData;
      Sleep( Random( 30 ) );
    end;
end;

end.
Der Thread nimmt irgendwelche Zufallsdaten, trägt diese in den Record ein und übergibt diesen Record dem Container.
Der Container regelt den Zugriff auf diese Daten von unterschiedlichen Threads mit einer CriticalSection.

Die Form zum Anzeigen nimmt sich jetzt per Timer (50ms) die Daten aus dem Container und stellt diese dar.
Delphi-Quellcode:
unit UI_Form_Data;

interface

uses
  Windows, Messages,
  SysUtils, Variants, Classes,
  Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
  UI_Form_Base, Container_Data, Vcl.ComCtrls;

type
  TUIData_Form = class( TUIBase_Form )
    RefreshData_Timer : TTimer;
    Value1_Label : TLabel;
    Value2_Label : TLabel;
    Value3_Label : TLabel;
    Value1_ProgressBar : TProgressBar;
    Value2_ProgressBar : TProgressBar;
    Value3_ProgressBar : TProgressBar;
    procedure RefreshData_TimerTimer( Sender : TObject );
    procedure FormClose( Sender : TObject; var Action : TCloseAction );
  private
    FContainer : TDataContainer;
    procedure SetContainer( const Value : TDataContainer );
    procedure PresentData( AData : TData );
  public
    property Container : TDataContainer read FContainer write SetContainer;
  end;

var
  UIData_Form : TUIData_Form;

implementation

{$R *.dfm}
{ TUIData_Form }

procedure TUIData_Form.FormClose( Sender : TObject; var Action : TCloseAction );
begin
  inherited;
  Action := caFree;
end;

procedure TUIData_Form.PresentData( AData : TData );
begin
  Value1_Label.Caption := IntToStr( AData.Value1 );
  Value1_ProgressBar.Position := AData.Value1;
  Value2_Label.Caption := IntToStr( AData.Value2 );
  Value2_ProgressBar.Position := AData.Value2;
  Value3_Label.Caption := IntToStr( AData.Value3 );
  Value3_ProgressBar.Position := AData.Value3;
end;

procedure TUIData_Form.RefreshData_TimerTimer( Sender : TObject );
begin
  inherited;
  PresentData( FContainer.Data );
end;

procedure TUIData_Form.SetContainer( const Value : TDataContainer );
begin
  if Value = FContainer
  then
    Exit;

  FContainer := Value;
  RefreshData_Timer.Enabled := Assigned( FContainer );
end;

end.
Natürlich kann man hier jetzt auch eine Benachrichtigung einbauen, wenn sich die Daten ändern und nur dann zeichnen lassen. Grundsätzlich geht es aber erstmal darum, das generelle Konzept der Events mit möglichst einfachsten Mitteln zu zeigen.

Im Anhang das gesamte Projekt (ich hoffe das läuft so unter Delphi 7 - hab leider keins da um das zu testen, alle Namespaces habe ich aber eigentlich entfernt)
Angehängte Dateien
Dateityp: zip dp_180314.zip (3,9 KB, 4x aufgerufen)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat