Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Synchroner Datenaustausch zwischen verschiedenen Anwendungen (https://www.delphipraxis.net/133898-synchroner-datenaustausch-zwischen-verschiedenen-anwendungen.html)

M44 11. Mai 2009 22:08


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

Fridolin Walther 11. Mai 2009 22:55

Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
 
Die wohl einfachste Möglichkeit wäre ein Event (MSDN-Library durchsuchenCreateEvent). Du erstellst einfach ein Event (z.B. EventSettingsChanged). Dann startest Du einen Thread der mit MSDN-Library durchsuchenWaitForSingleObject in einer Schleife auf EventSettingsChanged wartet. Sobald sich die Einstellungen ändern in einer der Instanzen deiner Anwendung (OnChanged Handler der Komponenten z.B.), packst Du die neuen Settings in Deine MMF und löst danach dann mit MSDN-Library durchsuchenSetEvent EventSettingsChanged aus. Der Thread wird dadurch aktiv und lädt die neuen Settings (allerdings bitte ohne den OnChanged Handler auszulösen ;)).

Fridolin Walther 11. Mai 2009 23:43

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 :).

R2009 12. Mai 2009 05:13

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

alzaimar 12. Mai 2009 07:04

Re: Synchroner Datenaustausch zwischen verschiedenen Anwendu
 
Du könntest dir eine Recordstruktur bauen, die die vorzunehmenden Änderungen beschreibt, z.B. so:
Delphi-Quellcode:
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
Hier die Implementierung des Senders. Das Handle des Empfänger-Formulars muss allerdings bekannt sein. Das ginge per 'FindWindow'.
Delphi-Quellcode:
...
// 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;
Und hier der Receiver....
Delphi-Quellcode:
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;
(getippt und nicht getestet)

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.

M44 12. Mai 2009 19:53

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