Autor Beitrag
HenryHux
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: Sa 06.11.10 19:16 
Hi,

wie der Titel schon sagt, suche ich einen Weg unter Programmen eine Variable auszutauschen.
Die Programme sind alle von mir selber geschrieben, und sind alle recht umfangreich, deswegen auch lieber ein Austausch,
als alles in ein Projekt mit mehreren Formen zu stecken.


Lg

Henry
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 06.11.10 19:29 
Man kann keine Variablen zwischen Prozessen austausche, nur deren Inhalt. Gehen tut das mit zum Beispiel WM_COPYDATA: www.michael-puff.de/...ts/WM_COPYDATA.shtml

Für diesen Beitrag haben gedankt: BenBE
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.11.10 19:31 
Der Möglichkeiten gibt es viele, je nach Anwendungszweck. Das Stichwort hier ist IPC (Interprozesskommunikation).

Möglichkeiten:
  • Integervariablen z.B. via normaler Messages in wParam oder lParam
  • WM_COPYDATA
  • Pipes
  • MMFs
  • ...

Für diesen Beitrag haben gedankt: BenBE
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Sa 06.11.10 20:33 
Eine Möglichkeit ist auch die Inifiles-Datei. Du schreibst in dem einen Programm eine Prozedur zur Speicherung der Daten in ein Inifile und mit dem anderen Programm lädst Du die Daten wieder ein.

Sicher, etwas antiquiert, aber es funktioniert.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
uall@ogc
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1826
Erhaltene Danke: 11

Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
BeitragVerfasst: Sa 06.11.10 22:16 
mit MemoryMappedFiles relativ einfach gemeinsamen Speicherbereich verwenden

_________________
wer andern eine grube gräbt hat ein grubengrabgerät
- oder einfach zu viel zeit

Für diesen Beitrag haben gedankt: BenBE
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: Sa 06.11.10 22:21 
Ok, danke erstmal für die ganzen Möglichkeiten, ich werd mich noch mal melden,
ggf. mit der Lösung, mit der ichs geschafft hab, dank euch=)

Lg

Henry
Implementation
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 33
Erhaltene Danke: 2

Parabola, Trisquel GNU/linux-libre
FPC, GCC
BeitragVerfasst: Sa 06.11.10 22:21 
Du könntest dir eigene Messages deklarieren.
Auf den ersten Blick geh'n damit nur Zahlen, aber mit etwas Nachdenken ...
Hab' mir damit mal eine kleine IPC-Bibliothek (NRDE) geschrieben, mit der auch Strings möglich waren.
NRDE ist aber leider so fest in ein Framework (NWL) verankert, dass ich es nicht so einfach herauslösen kann.

_________________
Free as in Freedom!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.11.10 23:40 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Sicher, etwas antiquiert, aber es funktioniert.
Aber nur so lange wie keine parallelen Zugriffe erfolgen usw. :roll:
Ob nun INIs oder andere Dateien, wie willst du die Zugriffe synchronisieren?

Da sind andere Lösungen sehr sehr viel einfacher.
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: So 07.11.10 12:12 
Ok, also vom anderen Thread wieder back.
Meine Empfehlung probiert das Synchronisieren nicht mit MMF :D
Ich bin jetzt dabei es mit messages zu versuchen, sieht immoment doch etwas erfolgverpsrechender aus.

Meine Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function action1() : integer;
var
MyRecord: PMyRecord;
cds: TCopyDataStruct;
hWnd1, hWnd2, hWnd3, hWnd4: THandle;
begin
  repeat
    GetMem(MyRecord, sizeof(TMyRecord));
  until myrecord.b=false;
  myrecord.b:=true;
  cds.dwData := 0;
  cds.cbData := sizeof(TMyRecord);
  cds.lpData := MyRecord;
  hWnd1 := FindWindow(nil'QND1');
  hWnd2 := FindWindow(nil'QND2');
  hWnd3 := FindWindow(nil'QND3');
  hWnd4 := FindWindow(nil'QND4');
  SendMessage(hWnd1, WM_COPYDATA, Handle, Integer(@cds)); //undeclared identifier : handle ?? wieso erkennt ers nicht?
  SendMessage(hWnd2, WM_COPYDATA, Handle, Integer(@cds));
  SendMessage(hWnd3, WM_COPYDATA, Handle, Integer(@cds));
  SendMessage(hWnd4, WM_COPYDATA, Handle, Integer(@cds));
end;


(Werde noch rausnehmen, dass sich das eigene Fenster ne Meldung schickt)


Und der Empfänger:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TMain.WMCOPYDATA(var msg: TWMCopyData);
var
  MyRecord: PMyRecord;
  b: Boolean;
  s: String[255];
begin
  b := PMyRecord(msg.CopyDataStruct.lpData)^.b;
  CheckBox1.Checked := b;
  Edit1.Text := s;
end;


Kann das damit gut klappen?
Habe die befürchtung, dass wenn 1 oder 2 Fenster absürzen dann die anderen automatisch untergehen.

Lg

Henry
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 07.11.10 12:19 
er erkennt es nicht weil Du:
ausblenden Delphi-Quelltext
1:
function action1() : integer;					


Deklariert hast
als entweder

ausblenden Delphi-Quelltext
1:
function Form1.action1() : integer;					


oder besser gleich
ausblenden Delphi-Quelltext
1:
function action1(HWND:THandel) : integer;					



LG
Thomas
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 12:21 
Mit WM_COPYDATA habe ich selbst noch nie gearbeitet. Ich persönlich finde es zu umständlich. ;-)

Was mir aber auffällt ist, dass du den Speicher nirgends wieder freigibst.
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 07.11.10 12:27 
@jaenicke

Ich verwende es sehr gern, man muss es nur etwas Kapseln dann wird es handlicher.
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: So 07.11.10 14:39 
So, denke habe es jetzt so hinbekommen, dass es einigermaßen gut läuft.

Hier ein Teil der Funktion:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
begin
    try
      repeat
        GetMem(MyRecord, sizeof(TMyRecord));
      until myrecord.b=false;                     //bis variable frei ist
      myrecord.b:=true;                           //variable besetzen
      cds.dwData := 0;
      cds.cbData := sizeof(TMyRecord);
      cds.lpData := MyRecord;
      wincaption();                              //andere fenster besetzt schicken
      //meine anweisungen hier
      wait(1000);                                //1ne sekunde warten bis er die variable wieder freigibt
      myrecord.b:=false;
      cds.dwData := 0;
      cds.cbData := sizeof(TMyRecord);
      cds.lpData := MyRecord;
      wincaption();                             //andere fenster freizeichen geben
    finally
      FreeMem(MyRecord, sizeof(TMyRecord));    //speicher leeren
    end;
  end;



Wincaption is ne andere Funktion:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
function wincaption() : integer;
begin
  if main.Caption='QND 1' then
  begin
    hWnd2 := FindWindow(nil'QND 2');
    hWnd3 := FindWindow(nil'QND 3');
    hWnd4 := FindWindow(nil'QND 4');
    SendMessage(hWnd2, WM_COPYDATA, hWnd2, Integer(@cds));
    SendMessage(hWnd3, WM_COPYDATA, hWnd3, Integer(@cds));
    SendMessage(hWnd4, WM_COPYDATA, hWnd4, Integer(@cds));
  end
  else if main.Caption='QND 2' then
  begin
    hWnd1 := FindWindow(nil'QND 1');
    hWnd3 := FindWindow(nil'QND 3');
    hWnd4 := FindWindow(nil'QND 4');
    SendMessage(hWnd1, WM_COPYDATA, hWnd1, Integer(@cds));
    SendMessage(hWnd3, WM_COPYDATA, hWnd3, Integer(@cds));
    SendMessage(hWnd4, WM_COPYDATA, hWnd4, Integer(@cds));
  end
  else if main.Caption='QND 3' then
  begin
  hWnd1 := FindWindow(nil'QND 1');
  hWnd2 := FindWindow(nil'QND 2');
  hWnd4 := FindWindow(nil'QND 4');
  SendMessage(hWnd1, WM_COPYDATA, hWnd1, Integer(@cds));
  SendMessage(hWnd2, WM_COPYDATA, hWnd2, Integer(@cds));
  SendMessage(hWnd4, WM_COPYDATA, hWnd4, Integer(@cds));
  end
  else if main.Caption='QND 4' then
  begin
    hWnd1 := FindWindow(nil'QND 1');
    hWnd2 := FindWindow(nil'QND 2');
    hWnd3 := FindWindow(nil'QND 3');
    SendMessage(hWnd1, WM_COPYDATA, hWnd1, Integer(@cds));
    SendMessage(hWnd2, WM_COPYDATA, hWnd2, Integer(@cds));
    SendMessage(hWnd3, WM_COPYDATA, hWnd3, Integer(@cds));
  end;
end;


Was haltet ihr davon?
Gut gelöst, fehlerhaft, verbesserungswürdig?

Danke,

Lg

Henry
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 07.11.10 14:57 
Ich würde erstens prüfen ob das Handle gültig ist
und zweitens als Senderhandle nicht das Reciverhandle verwednen.

LG
Thomas
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 15:43 
Also das sieht alles sehr sehr komisch aus. :hair:

Schon alleine das
user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
begin
    try
      repeat
        GetMem(MyRecord, sizeof(TMyRecord));
      until myrecord.b=false;                     //bis variable frei ist
      myrecord.b:=true;                           //variable besetzen
Du bekommst einen neuen Speicherplatz reserviert und statt den zu füllen schaust du was drin ist und holst du dir ggf. einen neuen? :shock:
(Ohne den zuerst reservierten wieder freizugeben wohlgemerkt.)

Das ist wie wenn du einen Gebrauchtwagen kaufst, in das Handschuhfach schaust und siehst, dass da ein Fensterkratzer drin ist und deshalb ein neues kaufst (und beim ersten einfach den Schlüssel wegwirfst und es damit unbenutzbar stehen lässt).

Also ich verstehe nicht was das eigentlich werden soll. SendMessage wartet bis die Message abgearbeitet ist. Und du bekommst da auch ein Ergebnis (das du einfach wegwirfst). Warum wertest du das nicht aus? Und wartest stattdessen nach der Abarbeitung der Messages durch das Zielprogramm eine Sekunde? :gruebel: :nixweiss:
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 07.11.10 15:49 
Ich habe doch einen Link zu funktionierenden Beispielcode gepostet. Warum wird da jetzt wieder wild ohne Sinn und Verstand rumgebastelt?
HenryHux Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 542
Erhaltene Danke: 33

Windows 7 Premium
Delphi XE, Eclipse
BeitragVerfasst: So 07.11.10 16:03 
Hmm, ok.
Habe mir das so überlegt, dass er prüft ob die Variable true ist, wenn ja dann erstmal wieder besetzt und dann am ende wieder freigibt.
Dachte, wenn ich keine Schleife reinsetze, dann macht er einfach gar nichts, wenn die Variable besetzt ist.
An das Beispiel habe ich mich eig gehalten, nur dass das nichts ständig synchronisiert, sondern einfach ne Nachricht schreibt.
Wie sollte denn der Programmablauf dann sonst aussehen?
Kann ich die Schleife weglassen?

Lg

Henry
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 07.11.10 16:29 
Wie wär's z. B. mit SOAP?

Man muss sich heutzutage nicht mehr mit lowest level Dingern wie named pipe, MMF oder WM_COPYDATA rumschlagen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.11.10 16:39 
Ich finde aber man sollte es zuerst machen. Denn sonst hat man kein Verständnis für das was da alles passiert. Und daraus resultieren dann schlechtere Ergebnisse.

Wenn man Pipes, XML und TCP-Verbindungen schon einzeln benutzt hat, kann man (finde ich) viel besser mit SOAP usw. arbeiten.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 07.11.10 16:47 
Ich weiß nicht, was ihr für ein Problem mit WM_COPYDATA habt. Es ist doch ohne Probleme zu Hand haben und wenn man mal schnell kleine Datenmengen austauschen will bestens geeignet. Mit MMFs und Pipes muss man da schon einen wesentlich höheren Aufwand treiben. Hinzukommt, das man zum Synchronisieren auch noch eine Nachricht schicken muss. Da kann ich die Daten doch auch gleich mit der Nachricht verschicken.