Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi KeyPress unter Form2 funktioniert nicht. (https://www.delphipraxis.net/180314-keypress-unter-form2-funktioniert-nicht.html)

Sir Rufo 12. Mai 2014 10:36

AW: KeyPress unter Form2 funktioniert nicht.
 
Aus dem Grund sollte man sich überall wo man
Delphi-Quellcode:
Application.ProcessMessages
verwendet auch noch ein
Delphi-Quellcode:
{ TODO : Should be done better }
hinschreiben.

Als Workaround gesehen ist das erst mal ok, sollte aber beizeiten anders gelöst werden (Thread oder Event-gesteuert).

Mavarik 12. Mai 2014 11:29

AW: KeyPress unter Form2 funktioniert nicht.
 
Zitat:

Zitat von himitsu (Beitrag 1258589)
Nein, bei ProgressMessages muß man dennoch aufpassen,...

Zitat:

Zitat von Mavarik (Beitrag 1258586)
fast ohne Ausnahme
Mavarik

:stupid:

Mavarik 12. Mai 2014 11:30

AW: KeyPress unter Form2 funktioniert nicht.
 
Zitat:

Zitat von Sir Rufo (Beitrag 1258592)
(Thread oder Event-gesteuert).

Logisch...

Es sei den, die Aktion/das Fenster soll/muss Modal sein.

akurka 12. Mai 2014 11:34

AW: KeyPress unter Form2 funktioniert nicht.
 
Hallo Mavarik und Himitsu
Ja Ihr habt recht, vermutlich habe ich zu früh gejubelt.
Es hat praktisch überall Warteschleifen, darum das zum Teil komische
verhalten.(anklicken mit der Maus löscht das Menü usw.)

Etwas verstehe ich nicht :
Wieso empfange ich auch in der Warteschleifen Meldungen von der
RSCOM ? Die RSCOM benützt WinAPI, sind das bereits ein Threads ?

Aber die RSCOM unit ist kein Thread ???
Muss ich die in dem Fall als ein Thread ausführen ?
Ich habe mich noch nie einen Thread versucht, ja nu, es gibt immer das
erstemal.

Es wird in allen diesen Warteschleifen auf irgendeine Message vom
rs232 gewartet oder auf eine TastaturEingabe.
(Maus Events werden keine benötigt)

Das bedeutet, ich müsste in jeder Schleife das Application.ProcessMessage aufrufen,
wäre das so richtig ?

Vielen Dank.
Gruss Anton

Mavarik 12. Mai 2014 11:38

AW: KeyPress unter Form2 funktioniert nicht.
 
Ich kenne die RSCom jetzt nicht, aber

Ich würde auf jeden Fall eine RS232 Routine verwenden, die einen Event auslösen kann, wenn Informationen an liegen...
Das kann ggf. natürlich auch ein eigener Thread sein, der in einer Endlosschleife darauf wartet...

Immer wenn der Event dann feuert: OnRSDataReady.. wird die Information dann verarbeitet.

Bedeutet: Dein Programm funktioniert Event gesteuert und ist im Prinzip die ganze Zeit im Idle-Mode...

Mavarik

himitsu 12. Mai 2014 11:41

AW: KeyPress unter Form2 funktioniert nicht.
 
Das Schönste Problem, was mir öfters passiert ist, in Verbindung mit den Messages:
Beim Schließen einer Form soll eventuell eine Meldung angezeigt werden.

Also wurde nach/beim Schließen ein ShowMessage eingeblendet.
ShowMessage hängt sich aber an die ActiveForm und wenn die "Active" noch die gerade Schließende ist, dann beendet diese Form den Dialog,
sobald sie entgültig weg ist, womit der Dialog garnicht, bzw. nur für wenige Millisekunden sichtbar ist.

Oder im ProgressMessage werden Dinge schon gemacht, die eigentlich erst nach Ende der Funktion passieren sollen ... so kann man sich tolle Mehrfachufrufe erzeugen, oder etwas löscht sich selber unterm Arsch weg.

Sir Rufo 12. Mai 2014 11:42

AW: KeyPress unter Form2 funktioniert nicht.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Nachdem ich mir den Quellcode einmal angesehen habe, beschleicht mich der Verdacht, dass hier ein altes Konsolen-Programm 1:1 in eine GUI-Anwendung umgewandelt werden soll.

Dieser Screenshot bestärkt mich weiter in meinem Verdacht
Anhang 41161

Mit ein paar simplen
Delphi-Quellcode:
Application.ProcessMessages
ist es da aber leider nicht getan.

Auch ist die RSCOM-Unit nicht wirklich dafür ausgelegt und sollte nur mit Vorsicht genossen werden oder entsprechend umgebaut werden.

Wenn wir mal den hierfür in Frage kommenden grundlegenden konzeptionellen Ansatz betrachten, so haben wir:
  1. die Kommunikation mit der CNC-Maschine (Daten-Sammler)
  2. die Anzeige der gesammelten Daten
Hierbei sollte A in einem eigenständigen Thread laufen und B einfach nur die Daten anzeigen und bei einer Änderung refreshen.

Sir Rufo 12. Mai 2014 12:46

AW: KeyPress unter Form2 funktioniert nicht.
 
Liste der Anhänge anzeigen (Anzahl: 1)
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)

akurka 12. Mai 2014 13:05

AW: KeyPress unter Form2 funktioniert nicht.
 
Hallo Sir Rufo
Ja ich habs ja nicht behauptet das es anders ist.
Tatsächlich ist es eine 20 Jahre alte DOS applikation, ursprünglich
in MS-Pascal geschrieben, ich war damals u.a. auch beteiligt.
Nun ich betrachte dies als mein persönliches Hobby, das alte Programm umzuschreiben (ohne Rücksicht auf Stunden Aufwand)

Leider ist es so, dass ich mich die letzte 15 Jahre hauptsächlich mit
FPGA (VHDL) Entwicklungen beschäftigt habe und damit den Anschluss an
OOP programmieren völlig verpasst habe.

Nun will ich aufs Alter meine Sünden aus der Vergangenheit wieder
gutmachen.Wie es halt so ist, man probiert immer der Weg des geringsten Widerstandes.
Das es leider mit der hergeholten COMPORT
Funktionen nicht so funktioniert ist mir jetzt langsam auch klar.
Das ist jetzt auch mein Ziel die RSCOM Unit neu zu gestalten.
Oder weisst Du eine geeignete Komponente die ich da für die
rs232 einsetzen kann ?
Gruss Anton

Sir Rufo 12. Mai 2014 13:21

AW: KeyPress unter Form2 funktioniert nicht.
 
Eine Empfehlung habe ich da nicht, es sollten sich aber so einige über Tante google finden lassen.

Für die Umstellung von Konsole auf GUI ist das aber auch erstmal nebensächlich wie die Daten konkret geholt werden. Du musst das GUI-Konzept mit den Events erst mal verinnerlichen (siehe mein Beispiel-Projekt).
Das sehe ich hier gerade als größere Baustelle.

Dann kannst du im Anschluss auch die konkrete Kommunikation anbauen.

Beim Arbeiten mit OOP ist eine Grundlage auch die Abstraktion, somit passt das als Übung auch, die konkrete Kommunikation mit RS232 zunächst aussen vor zu lassen ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 Uhr.
Seite 3 von 4     123 4      

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