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.