Autor |
Beitrag |
HenryHux
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: 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
|
Verfasst: 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
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: 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
      
Beiträge: 1826
Erhaltene Danke: 11
Win 2000 & VMware
Delphi 3 Prof, Delphi 7 Prof
|
Verfasst: 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 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: 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
      
Beiträge: 33
Erhaltene Danke: 2
Parabola, Trisquel GNU/linux-libre
FPC, GCC
|
Verfasst: 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
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 06.11.10 23:40
Tranx hat folgendes geschrieben : | Sicher, etwas antiquiert, aber es funktioniert. |
Aber nur so lange wie keine parallelen Zugriffe erfolgen usw.
Ob nun INIs oder andere Dateien, wie willst du die Zugriffe synchronisieren?
Da sind andere Lösungen sehr sehr viel einfacher.
|
|
HenryHux 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: So 07.11.10 12:12
Ok, also vom anderen Thread wieder back.
Meine Empfehlung probiert das Synchronisieren nicht mit MMF
Ich bin jetzt dabei es mit messages zu versuchen, sieht immoment doch etwas erfolgverpsrechender aus.
Meine Funktion:
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)); 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:
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
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: So 07.11.10 12:19
er erkennt es nicht weil Du:
Delphi-Quelltext 1:
| function action1() : integer; |
Deklariert hast
als entweder
Delphi-Quelltext 1:
| function Form1.action1() : integer; |
oder besser gleich
Delphi-Quelltext 1:
| function action1(HWND:THandel) : integer; |
LG
Thomas
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: So 07.11.10 12:27
@jaenicke
Ich verwende es sehr gern, man muss es nur etwas Kapseln dann wird es handlicher.
|
|
HenryHux 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: 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:
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; myrecord.b:=true; cds.dwData := 0; cds.cbData := sizeof(TMyRecord); cds.lpData := MyRecord; wincaption(); wait(1000); myrecord.b:=false; cds.dwData := 0; cds.cbData := sizeof(TMyRecord); cds.lpData := MyRecord; wincaption(); finally FreeMem(MyRecord, sizeof(TMyRecord)); end; end; |
Wincaption is ne andere Funktion:
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
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: 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
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 07.11.10 15:43
Also das sieht alles sehr sehr komisch aus.
Schon alleine das HenryHux hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| begin try repeat GetMem(MyRecord, sizeof(TMyRecord)); until myrecord.b=false; myrecord.b:=true; | |
Du bekommst einen neuen Speicherplatz reserviert und statt den zu füllen schaust du was drin ist und holst du dir ggf. einen neuen?
(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? 
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: 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 
      
Beiträge: 542
Erhaltene Danke: 33
Windows 7 Premium
Delphi XE, Eclipse
|
Verfasst: 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
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: 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
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
|
Verfasst: 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.
|
|
|