![]() |
Synchroner Datenaustausch zwischen verschiedenen Anwendungen
Hallo zusammen, :-D
bin neu hier und habe gleich eine Frage an Euch. Ich habe eine kleine Oberfläche programmiert, auf der sich einige Komponenten (diverse Schieberegler, Checkboxen und ein paar Buttons) befinden, über die man verschiedene Parameter für mein Programm einstellen kann. Nun möchte ich aber aus meiner Anwendung heraus eine andere Anwendung steuern, die eine identische Oberfläche besitzt. Wenn ich die Regler etc. so eingestellt habe wie ich möchte und dann über ein MemoryMappedFile an den Receiver (andere Anwendung) sende, funktioniert alles problemlos. Ich möchte aber das Programm soweit modifizieren, daß beim Verstellen der Regler in der Anwendung A (mein Hauptprogramm) automatisch und gleichzeitig die entsprechende Regler in der Anwendung B (Receiver) verstellt werden. Irgendwie habe ich im Moment keine richtige Idee, wie das elegant (eventuell mittels MMF?!!!) funktionieren könnte. So, ich glaube ich habe mich einigermaßen klar ausgedrückt :) und hoffe, daß mir jemand helfen kann. Im Moment programmiere ich mit Delphi 6 unter WinXP. Schöne Grüsse, M44 |
Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
Die wohl einfachste Möglichkeit wäre ein Event (
![]() ![]() ![]() |
Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
Liste der Anhänge anzeigen (Anzahl: 1)
Prinzipiell könnte man das ganze auch über Window Messages machen. Allerdings wäre mir das bei vielen Elementen und komplexeren Daten irgendwie zu aufwändig. Kleine Demo attached :).
|
Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
Hi,
wir haben so etwas ähnliches mit einer DDE Verbindung gelöst. Geht ganz einfach, auch bidirektional. Delphi7: System verschiedene entsprechende Komponenten. Eine Demo gibts auch. Viele Grüsse |
Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
Du könntest dir eine Recordstruktur bauen, die die vorzunehmenden Änderungen beschreibt, z.B. so:
Delphi-Quellcode:
Hier die Implementierung des Senders. Das Handle des Empfänger-Formulars muss allerdings bekannt sein. Das ginge per 'FindWindow'.
Type
TControlCommand = Record ccControlName : String[80]; // Wichtig! Statische Strings nehmen. Case Integer Of // Eine variante Record-Struktur 0 : (ccNewBoolean : Boolean); 1 : (ccNewInteger : Integer); 2 : (ccNewString : String[255]);// S.o.! Unbedingt ein statischer ShortString! End; PControlCommand = ^TControlCommand; // Alternativ eine Klasse, die Du serialisieren und deserialisieren kannst
Delphi-Quellcode:
Und hier der Receiver....
...
// Sender verschickt Änderungen. Dazu alle OnChange-Ereignisse der Controls mit diesem Event verbinden! Procedure TSenderForm.SendChange (Sender : TObject); Var cmd : TControlCommand; copystruct : TCopyDataStruct; HwndReceiver : THandle; Begin // Hier wurde der 'Sender' (irgendein Control) verändert, bewegt, angeklickt, getippt etc. If Sender is TControl Then Begin cmd.ccControlName := TControl(Sender).Name; If Sender is TCheckBox Then cmd.ccNewBoolean := TCheckBox(Sender).Checked Else If Sender is TRadiobutton Then cmd.ccNewBoolean := TRadiobutton(Sender).Checked Else If Sender is TTrackBar Then cmd.ccNewInteger := TTrackBar(Sender).Position Else If Sender is TEdit Then cmd.ccNewString := TEdit(Sender).Text Else Raise Exception.CreateFmt ('Controls der Klasse %s werden nicht unterstützt',[TControl(Sender).ClassName]); copyStruct.dwData := 0; // Hier kannst Du einen 32bit-Integer angeben (Ein 'Kommando' z.B.) copyStruct.cbData := SizeOf (TControlCommand); copystruct.lpData := @cmd; HwndReceiver := FindWindow('TReceiverForm',nil); If HwndReceiver>0 Then PostMessage (HwndReceiver, WM_COPYDATA, Handle, integer (@copystruct)); End; End;
Delphi-Quellcode:
(getippt und nicht getestet)
Type
TReceiverForm = Class (TForm) ... // Deklaration des Message-Handlers Procedure CMCopyData (Var Msg : TMessage); Message WM_COPYDATA; ... End; Procedure TReceiverForm.CMCopyData (Var Msg : TMessage); Var cmd : PControlCommand; ctrl : TControl; Begin // In Msg.lParam steht ein Zeiger auf eine TCopyDataStruct. // Der lpData-Member ist widerum ein Zeiger auf ein TControlCommand cmd := PControlCommand (PCopyDataStruct(Msg.lParam)^.lpData); ctrl := FindControl (cmd^.ccControlName); if Assigned (ctrl) then If ctrl is TCheckBox Then TCheckBox(ctrl).Checked := cmd^.ccNewBoolean Else If ctrl is TRadiobutton Then TRadiobutton(ctrl).Checked := cmd.ccNewBoolean Else If ctrl is TTrackBar Then TTrackBar(ctrl).Position := cmd.ccNewInteger Else If ctrl is TEdit Then TEdit(ctrl).Text := cmd.ccNewString End; Das funktioniert, wenn die zu synchronisierenden Controls auf dem Sender- und Receiver-Formular den gleichen Namen haben. Im Prinzip übertrage ich über die TControlCommand-Struktur nur den Namen des geänderten Controls sowie eine Information, *was* sich verändert hat (bei einer Checkbox die 'Checked' Eigenschaft, bei einem TEdit der Text usw.) Auf der Empfängerseite suche ich das korrespondierende Control und änderen eben entsprechend die korrespondierende Eigenschaft. Das lässt sich natürlich beliebig erweitern. Allerdings kann es sein, das es zu Problemen kommt, wenn man sehr viele Änderungen durchführt, weil der WM_COPYDATA-Mechanismus auf Empfängerseite nicht besonders geschützt ist: Laut OH soll man die Daten aus der CopyStruct 'so schnell wie möglich' abholen. Vielleicht wäre hier eine Crictical Section angebracht. |
Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
Hallo an alle :)
vielen Dank für Eure schnellen Antworten. Ich werde mir Eure Vorschläge mal genauer anschauen und den einen oder den anderen ausprobieren. Schöne Grüsse und bis bald M44 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:33 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