![]() |
AW: KeyPress unter Form2 funktioniert nicht.
Aus dem Grund sollte man sich überall wo man
Delphi-Quellcode:
verwendet auch noch ein
Application.ProcessMessages
Delphi-Quellcode:
hinschreiben.
{ TODO : Should be done better }
Als Workaround gesehen ist das erst mal ok, sollte aber beizeiten anders gelöst werden (Thread oder Event-gesteuert). |
AW: KeyPress unter Form2 funktioniert nicht.
Zitat:
Zitat:
|
AW: KeyPress unter Form2 funktioniert nicht.
Zitat:
Es sei den, die Aktion/das Fenster soll/muss Modal sein. |
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 |
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 |
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. |
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:
ist es da aber leider nicht getan.
Application.ProcessMessages
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:
|
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:
Der Thread nimmt irgendwelche Zufallsdaten, trägt diese in den Record ein und übergibt diesen Record dem Container.
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 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:
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.
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. 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) |
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 |
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 12:49 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