![]() |
OnChangeValue ?
Hallo
Ich suche eine Komponente die bei ànderung einer Variable (Externe Eingangswert) einen Event auslöst. Etwa in der Art : OnChangeValue. Ich habe überall danach gesucht aber niergens gefunden. Muss ich dann eine eigene Komponente schreiben ? |
AW: OnChangeValue ?
Mach das doch mit einer Property dessen Setter-Methode ein "OnChange"-Event auslöst:
Delphi-Quellcode:
TMeineKlasse = class
private var FMeinWert: Integer; procedure setMeinWert(const value: Integer); public var OnValueChange: TNotifyEvent; property MeinWert: Integer read FMeinWert write setMeinWert; end; procedure TMeineKlasse.setMeinWert(const value: Integer); begin if (FMeinWert = value) then Exit; FMeinWert := value; if Assigned(OnValueChange) then OnValueChange(self); end; |
AW: OnChangeValue ?
Zur Ergänzung: Man schreibt sich dann eine Ereignisbehandlung, z.B.:
Delphi-Quellcode:
und weist z.B. im OnCreate oder im OnShow der Form dem Ereignis diese Methode zu:
procedure TFormMain.ExternValueChanged;
begin DoSomething; end;
Delphi-Quellcode:
Wird das Ereignis in einer anderen Unit bzw. Form ausgelöst, muß man darauf achten, daß diese andere Form bereits instaziiert wurde. Wird sie erst nach der Unit/Form, in der die Ereignisbehandlung steht, erzeugt, wählt man für die Zuweisung der Ereignisbehandlung zum Ereignis z.B. OnShow oder OnActivate statt OnCreate.
procedure TFormMain.FormCreate(Sender: TObject);
begin OnValueChange := ExternValueChanged; end; |
AW: OnChangeValue ?
Hallo, danke für die beiden Beiträge.
Was den Setter anbelangt verstehe ich es nicht ganz, der Wert den ich überwachen will kommt von aussen, d.h es wird in meinem Programm gar nicht verändert resp. gesetzt. Im meinem Programm wird das Wert nur gelesen. Ich meinte Setter bedeutet setzen eines bestehenden Wertes und wenn es ungültig ist dann eine Exception auslösen. Verstehe ich es falsch ?? Beim zweitem Vorschlag was meinst Du mit DoSomething ? Sollte da ein Vergleich zwischen AltWert und NeuWert statfinden ? Aber wie soll daraus ein Event erzeugt werden ? |
AW: OnChangeValue ?
Zitat:
Delphi-Quellcode:
procedure TFormMain.DoSomething;
Var i : integer begin for i := 0 to 999999 do begin beep; Sleep(1000); end; end; |
AW: OnChangeValue ?
Zitat:
Delphi-Quellcode:
Das ist die Art & Weise, wie man Properties erstellt. Drückst du nun in der Zeile, in der das Property deklariert wird, die Tastenkombination Shift-Control-C, werden automatisch die beiden Methoden Getter und Setter erstellt. Nun kannst du "von außen" die Variable fMeinWert nur noch auf dem Weg über das Property ändern:
Private
fMeinWert : Integer; Public Property MeinWert : Integer read GetfMeinWert write SetfMeinWert;
Delphi-Quellcode:
Beim Setzen und Auslesen von MeinWert werden jetzt immer Setter und Getter des Properties aufgerufen. Hier kannst du dann z.B. das reinschreiben, was passieren soll, wenn sich die Variable ändert, also im Setter nach der Zuweisung DoSomeThing.
// Wert setzen
MeinWert := 65; //oder MeinWert := AusgelesenerWert; // Wert auslesen MeineVariable := MeinWert; Zitat:
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
Ausgelöst wird das Ereignis dann durch diesen Befehl:
TYPE
TUpdateStatusbarEvent = Procedure of Object; // Statusbar in Mainform TYPE TDatMod = CLASS(TDataModule) ... PRIVATE { Private-Deklarationen } Var fUpdateStatusbar : TUpdateStatusbarEvent; ... PUBLIC { Public-Deklarationen } ... Property OnUpdateStatusbar : TUpdateStatusbarEvent read fUpdateStatusbar write fUpdateStatusbar; ... END;
Delphi-Quellcode:
Verbindest du nun in deiner Unit, in der die Reaktions-Methode steht, das Ereignis mit der Methode, wird diese Methode jedesmal aufgerufen, wenn das Ereignis stattfindet – oder wie man hier gewöhnlich sagt: wenn das Event feuert:
If Assigned(fUpdateStatusbar) Then fUpdateStatusbar;
Delphi-Quellcode:
Ich setze dieses Event z.B. ein, um in der Mainform die Statusbar zu aktualisieren, wenn sich der Datensatzzeiger einer Tabelle geändert hat:
Procedure TFormMain.FormActivate(Sender: TObject);
begin ... DatMod.OnUpdateStatusbar := StatusBarAktuell; ... end;
Delphi-Quellcode:
Damit wird nun jedesmal beim Scrollen einer Datenmenge, die z.B. in FormMain durch das Scrollen in einem DBGrid ausgelöst wurde, die Anzeige in der Methode StatusBarAktuell aktualisiert:
Procedure TDatMod.View_LogAccessAfterScroll(DataSet: TDataSet);
begin If Assigned(fUpdateStatusbar) Then fUpdateStatusbar; end;
Delphi-Quellcode:
Solltest du entgegen meiner Erwartung nur Bahnhof verstehen, empfiehlt sich die Lektüre des einen oder anderen Tutorials, z.B. das beim
Procedure TFormMain.StatusBarAktuell;
begin StatBar.Panels[0].Text := GLD.IntToStrPunkte(DatMod.View_LogAccess.RecNo); StatBar.Panels[1].Text := GLD.IntToStrPunkte(DatMod.View_LogAccess.FieldByName('ID').AsInteger); StatBar.Panels[2].Text := DatMod.View_LogAccess.FieldByName('DATEI').AsString; Application.ProcessMessages; end; ![]() |
AW: OnChangeValue ?
Hallo
Vielen vielen Dank für die ausführliche Erklärung. Es ist sehr gut erklärt, soweit habe ich es verstanden. Ich hatte die überwachte Werte bisher über mehrere Timer überwacht was im prinzip einem Polling gleichkommt, und natürlich auch dem Windows Prinzip wiederspricht. Jetzt werde ich mein Programm entsprechend umstellen, ich schreibe Dir dann ob es klappt. Besten Dank und ein Gruss aus dem Wolkenverhangenem Engadin Anton |
AW: OnChangeValue ?
Hallo Perlsau
Leider klappt es bereits bei der Deklaration nicht :
Delphi-Quellcode:
Bei der Compilation gibt es diese Meldung:
unit menueREF;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,ExtCtrls, NC__09,NC__08,NCAS09,NCKU00,NCKU09; type TForm2 = class(TForm) Image1: TImage; procedure MenueCreate(Sender: TObject); procedure StatusBild; procedure Man; procedure MenueDestroy(Sender: TObject); procedure OnKeyPress(Sender: TObject; var Key: Char); private fBWStellung: Integer; { Private-Deklarationen } public Property BWStellung :Integer read GetfBWStellung write SetfBWStellung; { Public-Deklarationen } end; var Form2: TForm2; ActiveImage :TImage; BWStellung := int(Status.CNC.ZBETR); //Status.CNC.ZBETR ist Byte F_KeyA :boolean; procedure OptionFehlt; implementation {$R *.dfm} uses NCUP01,NCUP10,NCUP11,NCUP12,NCUP13; //===================================================== procedure TForm2.MenueCreate(Sender: TObject); begin keypreview:=true; usw..... [Fehler] menueREF.pas(22): Feld- oder Methodenbezeichner erwartet Eigentlich ist der zu überwachende Wert ein Byte (STATUS.CNC.ZBETR). Ich habe es zuerst mit Byte probiert danach auch mit integer. Es wird ein Feld verlangt also z.Bsp ein String Muss ich meine Variable als String deklarieren d.h. Feld? oder liegt sm am DELPHI7 dass es nicht schluckt ? Gruss Anton |
AW: OnChangeValue ?
Ich sehe in deinem Code keine Getter- und Setter-Methoden. Die erzeugst du, wie ich oben bereits ausgeführt habe, indem du den Cursor auf die Zeile mit der Property-Deklaration setzt und die Tastenkombi Ctrl-Shift-C drückst. In den Setter schreibst du dann rein, was passieren soll, wenn der Wert gesetzt wird.
Hinweis: Eine Anleitung sollte man schon komplett ausführen, weil sonst Fehlermeldungen auftreten. |
AW: OnChangeValue ?
Hallo Perlsau
Tut mir leid dass ich Dich nochmal beanspruche aber es haut nicht. Muss man für die Setter Deklaration immer eigene Klasse deklarieren oder kann ich auch bestehende nehmen ? Ich habe beides probiert aber ohne Erfolg. Was mache ich falsch ?
Delphi-Quellcode:
die Fehler Meldung ist die gleiche :
unit menueREF;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,ExtCtrls, NC__09,NC__08,NCAS09,NCKU00,NCKU09; type TForm2 = class(TForm) Image1: TImage; procedure MenueCreate(Sender: TObject); procedure OnValueChange; procedure StatusBild; procedure Man; procedure MenueDestroy(Sender: TObject); procedure OnKeyPress(Sender: TObject; var Key: Char); private //fBWStellung: Integer; //procedure setBWStellung(const value: Integer); { Private-Deklarationen } public //OnValueChange :TNotifyEvent; //Property BWStellung :Integer read GetfBWStellung write SetfBWStellung; { Public-Deklarationen } end; TMeineKlasse = class private fBWStellung: Integer; procedure setBWStellung(const value: Integer); public OnValueChange :TNotifyEvent; Property BWStellung :Integer read getfBWStellung write SetfBWStellung; end; var Form2: TForm2; ActiveImage :TImage; F_KeyA :boolean; procedure OptionFehlt; implementation {$R *.dfm} uses NCUP01,NCUP10,NCUP11,NCUP12,NCUP13; //===================================================== //procedure TForm2.setBWStellung(const value: Integer); procedure TMeineKlasse.setBWStellung(const value: Integer); begin if (fBWStellung = value) then Exit; fBWStellung := value; if Assigned(OnValueChange) then OnValueChange(Self); end; //------------------------------------------------- procedure TForm2.OnValueChange; begin StatusBild; end; //==================================================== procedure TForm2.MenueCreate(Sender: TObject); begin keypreview:=true; //BWStellung := int(Status.CNC.ZBETR); ActiveImage :=Image1; Form2.ClientWidth:=512; Form2.ClientHeight:=256; Form2.Image1.Width:=511; Form2.Image1.Height:=255; F_obereAchsen:=false; F_KeyA := false; end; //===================================================== procedure TForm2.MenueDestroy(Sender: TObject); [Fehler] menueREF.pas(35): Feld- oder Methodenbezeichner erwartet Gruss Anton |
AW: OnChangeValue ?
Du solltest eigentlich schon wissen, was du da tust. Das Property soll gelesen und geschrieben werden von getfBWStellung und SetfBWStellung. Dann mußt du deine Methoden auch so benennen. Wenn du, wie von mir empfohlen, auf der Property-Zeile Ctrl-Shift-C gedrückt hättest, wären diese Methoden automatisch richtig erstellt worden. Oder gibt's das bei deiner alten Version noch nicht? Das kann ich natürlich nicht wissen. Also wie gesagt: das, was hinter read steht, ist die Methode zum lesen des Property's, und das, was hinter write steht, die zum schreiben. Wenn du jetzt in der Deklaration ebenso wie in der Implementation dieses f einfügst, sollte es funktionieren.
Und vergiß nicht, die Tutorials durchzuarbeiten, damit deine Kenntnisse über OOP (Objektorientiertes Programmieren) voranschreiten können. Weißt du, ich hab das damals auch nicht alles auf Anhieb verstanden, sondern erst nach & nach durch viel Übung und ständiges Anwenden. Einfach nur so was abtippen und dann wie der Ochs vor einer kryptischen Fehlermeldung zu stehen, wird dich nicht wirklich weiterbringen ... |
AW: OnChangeValue ?
Habe ich das jetzt so verstanden, dass
Delphi-Quellcode:
irgendwo außerhalb gesetzt wird und man auf die Änderung dieses Speicherbereiches reagieren will? Das kann mit der Lösung von Perlsau nicht funktionieren.
STATUS.CNC.ZBETR
Laut Variable ist das der Status irgendeiner CNC-Maschine. Und dieser Wert ändert sich dann, wenn die CNC-Maschine ihren Status ändert. In der SPS-Welt pollt man den Wert (alle paar ms) und reagiert dann auf Änderungen. Wenn der Treiber kein Callback anbietet, muss man selbst pollen. Das geht mit einem Timer, nur bekommt man die Änderungen dann nicht in Echtzeit mit. Falls damit ein Leitstand, also eine Anzeige des Status umgesetzt werden soll, reicht es aber. Besser wäre es, eine Threadklasse zu schreiben, die den Status kontinuierlich prüft und bei Änderung ein Event auslöst (per Synchronize oder Queue). Dann hat man sein Event. |
AW: OnChangeValue ?
Hallo mitenand
Beitrag von Perlsau: Zitat:
ist immer die Gleiche. Auch das mit Ctrl-Shift-C funktioniert nicht. Ich fürchte das Problem liegt tatsächlich an meiner alte Delphi version. Ja nun was tun ? Allzuviel will ich in eine neue Delphi Version nicht investieren. Was empfielst Du mir ? Uebrigens bin ich hauptsöchlich ein Hardware Entwickler (VHDL,FPGA)darum bereitet mir dass OOP denken ziemliche Schwierigkeiten. In den Tutorials die ich schon X-mal durchgelesen habe ist es immer so schön erklärt, aber die Praxis ist eine andere. Ja, ich gebs mir Mühe !!! Gruss Anton Beitrag von Dejan Vu Zitat:
die in unregelmässigen Abständen über RS232 in einem Thread empfangen wird. Die Meldung selber kommt relativ häufig aber der STATUS.CNC.ZBETR ändert sich nur dann wenn der Benützer das Betriebswahlschalter wechselt.Und das kann Stunden dauern. Ausserdem gibt es ganzer Menge andere Meldungen. Bis jetzt habe ich es mit Polling gelöst was aber nicht gerade sauber ist. Der Grund warum ich es anders machen will ist, dass bei einem BW Wechsel das aktuelle Menü komplett neu aufgebaut wird. Sonst bleibt das Menue bestehen und es werden nur Anzeigen geändert. Aber auch das stösst an Grenzen mit Polling. Eigentlich suchte ich eine Komponente die auf Aenderung einer Variable reagiert (OnChangeValue). Dieser Komponente möchte ich dann für verschiedene Variablen anwenden (OnChangeBWStellung, OnChangeIstwert, OnchangeAchsenWahl usw.) Die Polling Lösung hat ein gewichtige Nachteil, es verbraucht sehr viel Rechenzeit(bei allen diesen Meldungen). Im übrigem ist mir klar, dass wenn die neue Lösung funktioniert ich mich auch mit "kritische Region" befassen muss, das aber später,eines nach dem anderem. Die RS232 ist sowieso nur vorläufige (alte) Lösung , im Zukunft möchte ich auf EtherCAT(oder OpenCAN) umstellen, schon deswegen möchte ich die Resourcen sparen. Du hast dich offenbar auch schon mit der SPS Welt befasst, was schlägst Du vor ? Gruss Anton |
AW: OnChangeValue ?
Delphi-Quellcode:
Hattes du überhaupt den Getter implementiert?
//interface-Teil
TMeineKlasse = class private fBWStellung: Integer; procedure setBWStellung(value: Integer); function getBWStellung:Integer; public OnValueChange :TNotifyEvent; Property BWStellung :Integer read getBWStellung write SetBWStellung; end; //implementation-Teil procedure TMeineKlasse.setBWStellung(value: Integer); begin if (fBWStellung = value) then Exit; fBWStellung := value; if Assigned(OnValueChange) then OnValueChange(Self); end; function TMeineKlasse.getBWStellung:Integer; begin Result:=fBWStellung; end; |
AW: OnChangeValue ?
Getter ist ja nicht wirklich nötig, außer man will den Zugriff threadsicher machen, oder man muß mehr machen, als nur ein Feld auszulesen.
Delphi-Quellcode:
type
TMeineKlasse = class//(TComponent) private FBWStellung: Integer; FOnValueChange :TNotifyEvent; procedure SetBWStellung(Value: Integer); public//published? (vorallem für OnValueChange, wenn man TMeineKlasse im Designer AUF die Form legt) Property BWStellung: Integer read FBWStellung write SetBWStellung; property OnValueChange: TNotifyEvent read FOnValueChange write FOnValueChange; end; procedure TMeineKlasse.SetBWStellung(Value: Integer); begin if FBWStellung = Value then Exit; FBWStellung := Value; if Assigned(FOnValueChange) then FOnValueChange(Self); end; Im Thread kannst du nun per TThread.Synchronize oder TThread.Queue dem Property was zuweisen. Der Thread wertet also die Records aus und setzt die entsprechenden Property und die Klasse kümmert sich um die Notifications. (mit Queue, wenn der Thread nicht hängen soll, so lange der Hauptthread arbeitet, aber mit Generice/anonymen Methroden geht sowas einfacher) |
AW: OnChangeValue ?
Hallo
jetzt läuft es durch den Compiler auch durch. Es ist jetzt auch klar warum es immer ein Fehler bei der Compilation gab.
Delphi-Quellcode:
Wenn es in der Zeile das " read getBWstellung" gibt, ist natürlich auch die Funktion
Property BWStellung :Integer read getBWStellung write SetBWStellung;
"getBWStellung" notwendig. Ersetzt man dagegen das read getBWStellung durch read fBWStellung kann man die getFunktion weglassen. Es ist zwahr jetzt beim Compiler auch durch, aber es gibt leider kein Event beim änderung der BWStellung.
Delphi-Quellcode:
Die Procedur StatusBild wurde gar nicht aufgerufen bei
procedure TForm2.OnValueChange;
begin StatusBild; end; BWStellung Aenderung.Das konnte ich eindeutig mit dem Debugger feststellen. Nun eine Frage: Ich habe versucht nebenbei eine eigene Komponente zu schreiben. Nun in den Tutorials wird für ein Event Auslösung z.Bsp. ein OnKeyPress genommen und entsprechend geändert.Was ich für mein Problem nicht brauchen kann. In allen Tutorials die ich gefunden habe, wurden immer als Beispiel Event von Tasten genommen. Ist es darum, dass es keine andere WindowsMessage gibt? Weiss jemand, wie man in eine eigene Komponente ein Event auslöst für eine Wertänderung ? Oder ist es gar nicht möglich ? Gruss Anton |
AW: OnChangeValue ?
Zitat:
Delphi-Quellcode:
DeinVariablenName := TMeineKlasse.Create;
DeinVariablenName.OnValueChange := Form2.OnValueChange |
AW: OnChangeValue ?
Hallo TiGü
Entschuldige, aber mir ist nicht ganz klar welche Stelle in meinem Programm sehen willst ? Soll ich Dir die ganze Unit senden ? Gruss Anton |
AW: OnChangeValue ?
Das schreibt TiGü doch "laut" und deutlich: Er möchte sehen, wo du eine Instanz deiner neuen Klasse erzeugst. Wenn du eine solche Stelle nicht finden kannst, dann erzeugst du keine Instanz deiner Klasse und kannst auch nicht mit dieser Klasse arbeiten.
Ich würde dir wirklich dringendst emfpehlen, mal das eine oder andere Class-Turorial durchzuarbeiten, denn offenbar verstehst du von dem, was man dir ständig an wertvollen Tips gibt, nicht mal die Hälfte. Diesen Umstand kannst nur du selbst ändern. |
AW: OnChangeValue ?
Hallo Perlsau
So habe ich die neue Klasse Instanziert, gemäss dem Tutorial :
Delphi-Quellcode:
Genügt das nicht ?
//====================================================
procedure TForm2.MenueCreate(Sender: TObject); begin keypreview:=true; ActiveImage :=Image1; Form2.ClientWidth:=512; Form2.ClientHeight:=256; Form2.Image1.Width:=511; Form2.Image1.Height:=255; F_obereAchsen:=false; F_KeyA := false; MeineKlasse :=TMeineKlasse.Create; //MeineKlasse.fBWStellung.OnvalueChange := Form2.OnValueChange; //MeineKlasse.fBWStellung.OnvalueChange := OnValueChange; //MeineKlasse.OnvalueChange := OnValueChange; //MeineKlasse.OnvalueChange := Form2.OnValueChange; //fBWStellung := Form2.OnValueChange; //fBWStellung := OnValueChange; // das frisst der Compiler nicht.. end; Ich meinte wenn die neue Klasse instanziert ist, sind auch die drin deklarierte Proceduren bekannt, oder nicht ? Muss man die OnValueChange noch zusätzlich deklarieren ? das habe ich probiert, aber das schluckt der Compiler nicht. Ich habe den verdammten Tutorial von vorne und zurück heute nachmittag sicher 5 mal durchgelesen aber die Verwirrung wird nur noch grösser. Gruss Anton |
AW: OnChangeValue ?
ja übrigens das fehlt noch :
Delphi-Quellcode:
TMeineKlasse = class private fBWStellung: Integer; //Hier ist der Wert gespeichert fOnValueChange :TNotifyEvent; procedure setBWStellung(const value: Integer); //function getBWStellung:Integer; public //BWStellung steht für Eigenschaft von fBWStellung Property BWStellung :Integer read fBWStellung write SetBWStellung; property OnValueChange: TNotifyEvent read FOnValueChange write FOnValueChange; end; // setBWStellung :Setter ist eine Methode um in fBWStellung zu schreiben //fBWStellung kann nur über das propperty ändern var Form2: TForm2; MeineKlasse: TMeineKlasse; fBWStellung :integer; ActiveImage :TImage; F_KeyA :boolean; procedure OptionFehlt; implementation usw. |
AW: OnChangeValue ?
Akurka, tut mir leid, aber ich geb's hier auf. Offenbar fehlen mir noch weitere Informationen, um dein Problem richtig zu verstehen. Es gibt hier zahlreiche berufenere Geister als mich, die dir sicher gerne weiterhelfen werden.
|
AW: OnChangeValue ?
Hallo Perlsau
ja ok, ich meine ich habe mein Problem genügend erklärt (siehe Antwort an Dich und Dejan Vu), vollständigkeits halber zitiere ich es noch einmal : Zitat:
was dem Polling eigentlich gleich kommt, ist das nicht so ? Nun ich verstehe, dass Du genug hast Dich mit OOP Anfänger zu plagen. Trotzdem vielen Dank für Deine Hilfe, ich habe wieder einiges gelernt. Gruss Anton |
AW: OnChangeValue ?
Lies dir mal
![]() Da geht es auch um ein TNotifyEvent und wie man eine entsprechende Prozedur definiert, erzeugt und benutzt. Oder informiere dich einmal zum Stichwort "Methodenzeiger". Musst du eigentlich mehrere verschiedene Werte überwachen (du würdest dann für jeden ein entsprechendes Objekt von TMeineKlasse brauchen) oder geht es nur um einen Wert? Im letzteren Fall könntest du dir den ganzen Aufwasch ja sparen und mit einer Variablen + Setter + Property direkt in Form2 arbeiten. |
AW: OnChangeValue ?
Zitat:
Du möchtest einen Event... Aber wo soll der den her kommen? Wer soll den auslösen? Wie pollst Du den? Du Fragst doch sicherlich etwas ab... Oder? Gibt es einen Trigger der RS232 Routine, nach dem Motto "Neue Daten da"? Das wäre eine Event... Auf den kannst Du reagieren, dann den Wert abfragen und gut ist. Kein Pollen mehr... Mavarik |
AW: OnChangeValue ?
So wäre das im Ansatz richtig:
Delphi-Quellcode:
Nun müsstest du uns nur noch die Stelle zeigen, wo du das machst:
procedure TForm2.MenueCreate(Sender: TObject);
begin keypreview := True; ActiveImage := Image1; Self.ClientWidth := 512; Self.ClientHeight := 256; Self.Image1.Width := 511; Self.Image1.Height := 255; F_obereAchsen := False; F_KeyA := False; MeineKlasse := TMeineKlasse.Create; MeineKlasse.OnvalueChange := Self.OnValueChange; end;
Delphi-Quellcode:
MeineKlasse.BWStellung := ... // Die Zuweisung des neuen Wertes
// Das musst du ja irgendwie durch Pollen im Timer oder Thread umgesetzt haben?! |
AW: OnChangeValue ?
Hallo Jumpy
Besten Dank für Dein Tipp. Ja nach der ersten Durchsicht ist es genau das was mir fehlt. Habe es augedrückt und werde es genau studieren. Zu Deiner Frage: Ja es sind mehrere Werte aus den Meldungen die von der CNC über RS232 kommen. Die Wichtigste ist die Status.CNC Meldung(16 Byte,Array) und daraus das ZBETR(BetriebswahlSchalterStellung=BWStellung= 1 Byte). Aber es soll aber auch bei der IstWertMeldung ( Anzahl Bytes variert,je nach Anzahl Achsen,pro Achse 24bit) festgestellt werden ob sich irgend ein Istwert(24bit =>Integer) verändert hat. Jetzt mache ich es mit Polling und Vergleich AltWert <> NeuWert und nur wenn eine Aenderung da ist, wird es Angezeigt. Ziemlich umständlich und ein Resourcen Fresser. Im grossen Ganzen sind es (je nach Betriebswahl) 2 bis 4 unterschiedliche Meldungen die permanent überwacht werden müssen. Andrererseits muss ich sagen, dass die bisherige Lösung eigentlich nicht schlecht läuft. Eleganter wäre natürlich eine Lösung wie bei Tasten z.Bsp. OnKeyPress, darum meine Idee mit OnChangeValue. Nur wenn sich ein Wert ändert wird entsprechender Erreigniss ausgelöst und der Wert Angezeigt. Ob es dann weniger Rechenzeit braucht kann ich nicht beurteilen, aber ich will es probieren und testen. Gruss Anton |
AW: OnChangeValue ?
Zitat:
|
AW: OnChangeValue ?
Hallo TiGü
Besten Dank, das " MeineKlasse.OnvalueChange := Self.OnValueChange;" hat gefehlt. Ja mit der Polling, dass ist genau das Problem, das mache ich jetzt schon: Zitat:
Wird es punkto Rechenzeit überhaupt etwas bringen mit dem setter, wenn ich den Wert der Variable pollen muss ?? Gruss Anton |
AW: OnChangeValue ?
Zitat:
|
AW: OnChangeValue ?
Zitat:
Da scheinst du ja mit den Vergleich von Alt- zu Neuwert nur zu erneuern, wenn du es musst. Das Pollen scheint dein eigentliches Problem zu sein. Hier wären mal konkrete Zahlenwerte gefragt. Verbraucht dein Abfragethread ungewöhnlich viel CPU-Arbeit im Task-Manager? Wenn ja, wieviel Prozent? Wie oft pollst du denn? Mit welcher Frequenz oder im welchen Intervall? Wenn du das nicht beantworten kannst, dann hast du einen Abfragethread, der stumpf im Execute die serielle Schnittstelle ausliest. Dann erklärt sich der Ressourcenhunger. |
AW: OnChangeValue ?
Hallo Mavarik
Entschuldige die späte Antwort. Ich musste nach den ersten Antworten schnell weg. Du hast es richtig angesprochen, woher soll der Event kommen ? Leider bringt es nichts auf Empfang der Meldungen vom RS232 zu triggern. Der Grund ist, dass es z.Bsp mehrere Status oder Istwert Meldungen die genau gleich sind, also müssen gar nicht berücksichtigt werden. Du kanst Dir das so vorstellen wenn z.Bsp die CNC Achsen gar nicht in Bewegung sind wird im Prinzip immmer der gleiche Istwert öbermittelt. Ab un zu mal bedingt durch Regelung gibt es ein Unterschied +/-1 um dies aber u.U.in Abständen von Sekunden. Die Status-, Istwert-, Endlage- usw. werden aber in Abständen von ca. 50 - 100 mS empfangen.Es gibt also ganze menge Meldungen die nicht relevant sind. Auf der andere Seite gibt es Situationen wo eine sehr schnelle Reaktion notwendig ist, darum die relativ kurzen Zeitabstände. Die jetztige Polling Rate bei 4 Achsen ist ca. 50 mS, es ist ein Kompromiss. Wenn man eine Taste drückt hat man die Methode OnKeyPress, ohne das man die Taste ständig abtasten muss. So etwas stelle ich mir vor aber für die Aenderung einer Variable. Soviel ich weiss werden die Tastaur-Nachrichten im Supervisor Modus des uP's abgearbeitet, und damit sind auch die Windows Message verfügbar. Ob so etwas auch für Memory ànderungen gibt entzieht sich meiner Kenntnis. Vermutlich ist das bestehende, zugegeben etwas holprige Lösung gleich das optimale. Aber ich will es genau abklären ob es der Wahrheit letzter Schluss Schluss ist. Gruss Anton |
AW: OnChangeValue ?
Ich mische mich jetzt auch mal kurz ein:
das mit dem OnKeyPress ist recht einfach zu erklären: Wenn du eine Taste drückst generiert deine Tastatur einen Interrupt. Dieser wird von diversen Treibern "aufgefangen" und dann als Windows Message versendet...und auf dies Message reagieren dann halt entsprechende Komponenten. Ist aber eine gaaannnzz doll abstahierte Darstellung. Wenn du nun deine CNC dazu bringen könntest Nachrichten über die RS232 nur dann zu senden, wenn sich auch was geändert hat hättest du auch ein "event" auf das du reagieren könntest. Ansonsten bleibt dir halt nur übrig die Infos von der CNC "kontinuierlich" auszulesen und das ist dann halt Polling.... |
AW: OnChangeValue ?
Hallo Dirk
Danke, jetzt ist mir klar, dass ich kein OnChangeValue machen kann. Bei der CNC wird es schwierig, resp. mit sehr grossem Aufwand verbunden (FPGA Aenderungen). Aber vielleicht im Empfangs Thread für den COM Port nach jedem MeldungsEmpfang ein Vergleich zu machen und damit den Event auszulösen. Während dem ein Byte empfangen wird kann man den vorherigen testen. Mal versuchen. Das Polling später im Programm tut u.a. auch der Empfang über den COM Port behindern, das habe ich bereits festgestellt wenn ich die Baudrate erhöht habe. Besten Dank für den Tipp. Anton |
AW: OnChangeValue ?
Ich verstehe noch immer nicht, wo das Problem sein soll. Was ich bisher, nachdem nun weitere Informationen vorliegen, verstanden habe:
Nachtrag: Es gibt doch diese ![]() The ![]() Triggers and trigger handlers Async Professional uses the term "trigger" for any serial port action that can cause its communications dispatcher to generate a VCL event. There are four types of triggers:
Quelle: Reference Guide, Seite 22 |
AW: OnChangeValue ?
Zitat:
Die Kommunikation mit der CNC-Maschine läuft über die RS-232 Schnittstelle. PUNKT. Also muss man die eingehenden Daten - je nach Baudrate - mit für heutige Rechner wenig CPU Last - SOWIESO einlesen... Das ist der einzige Kommunikations-Kanal hier werden dann die Datenpakete auseinander genommen... Wenn dann eine Änderungen eintritt, die für die Software relevant ist, sendet der RS-232 Treiber eine Windows-Message. Bingo damit hast Du Deinen Event-Trigger... Ohne zu pollen! |
AW: OnChangeValue ?
Genau so :thumb: :!: :thumb:
|
AW: OnChangeValue ?
Hallo mitenand,
mit der AsyncPro rennt Ihr offene Türe ein, ich verwende es bereits. Dirk hat schon recht, dass ich falsche Vorstellung von den OnChange... Methoden hatte. Ja nun man lernt nie aus. Besten Dank für die Unterstützung von Euch allen. Gruss Anton |
AW: OnChangeValue ?
Zitat:
Wenn du AsyncPro bereits verwendest, dann werden da auch Ereignisse ausgelöst, wenn am Comport ein Signal eintrifft. Wieso verwendest du das nicht so, wie es in den Manuals steht? Leider kann ich nichts weiter dazu sagen, da du uns bislang verschwiegen hast, daß du AsyncPro einsetzt, und somit auch kein Code vorliegt, der zeigt, wie du das anwendest. Vermutlich wäre es das Beste, du würdest erstmal das Handbuch zu AsyncPro studieren, bevor du eine Komponente aus dieser Sammlung verwendest. |
AW: OnChangeValue ?
Hallo Perlsau
Entschuldige, war falsch,ich habe schon Dich gemeint- Ich habe das AsyncPro darum nicht erwähnt weil ist es im Form1 verwende und zwar in einem Thread der die Empfangene Meldungen direkt in Globale Variable abspeichert. Da gibt es in Abständen von 50mS z.Bsp Status.CNC Meldungen und es kommen bis zu 10 Meldungen die genau gleich sind. Mich interessiert aber nur, wenn sich etwas verändert hat, und so bin ich auf die doofe Idee gekommen es wäre nett eine OnChangeValue Erreigniss zu haben. Ja nu manchmal hat man ein Brett vor dem Kopf, vor allem wenn man allein arbeitet und mit niemandem die doofe Ideen diskutieren kann. Mir jetzt auch klar das es am besten ist, die Meldungen im EmpfangsThread auf Gleichheit zu testen. Für gar nichts ist das Exploit doch nicht gewesen, ich habe etwas mehr gelernt über OOP. Vielen Dank für Deine Erklärungen betr.setter und nicht zu ungut. Heute schneit es wie verrückt im Engadin, so habe jede menge Zeit den EmpfangsThread zu ändern. Wenn es dich Interessiert für was das ganze ist : ![]() An dem Delphi Programm bin ich mit unterbrüchen schon fast zwei Jahren dran. Da die Hardware jetzt endlich richtig funktioniert, kann ich mich jetzt voll mit der Bedienungs Software (Delphi) beschäftigen. Ubrigens habe ich mir erlaubt Dein Profil anzuschauen,sehr interessant Dein Werdegang. Du hast die ganze Entwicklung praktisch von Anfang an miterlebt. Gruss Anton |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05: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-2025 by Thomas Breitkreuz