![]() |
Datentransfer zwischen Programmen
Hallo,
ich versuche, zwischen zwei Delphi Programmen Daten via "BroadcastSystemMessage" zu versenden.
Delphi-Quellcode:
// im FormCreate definiere ich meine Veriable MSG_SHOW_ADDRESS := RegisterWindowMessage('ShowAddress'); // Hier der Ausschnitt aus der Methode zum Versenden.. var dwRecipient : DWord; begin dwRecipient := BSM_APPLICATIONS; BroadcastSystemMessage(BSF_POSTMESSAGE, @dwRecipient, MSG_SHOW_ADDRESS, myKndNr, 0); end; Auf der Empfängerseite läufts auch geschmeidig mit :
Delphi-Quellcode:
If Message.Msg = MSG_ADD_ADDRESS
Then ShowMessage (InttoStr(Message.wParam)); Soweit so gut. Jetzt kommt das Problem: Eine Intergerzahl zu übertragen ist recht trivial. Kann man das auch mit einem Record machen ? Die Idee hinter dem Senden:
Delphi-Quellcode:
T_Adresse = Record
Keycode : String[20]; Anrede : String[10]; Titel : String[30]; Vorname : String[30]; Nachname : String[30]; Adresse2 : String[30]; Strasse : String[30]; Hausnr : String[30]; PLZ : String[10]; Ort : String[30]; End; P_Adresse= ^T_Adresse; procedure TForm1.Button2Click(Sender: TObject); VAR A : P_Adresse; begin New(A); A.Keycode := 'SA01-02'; A.Anrede := 'Frau'; A.Vorname := 'Maxi'; Senden (Integer(@A)); end; procedure TForm1.Senden(X: Integer); var dwRecipient : DWord; begin dwRecipient := BSM_APPLICATIONS; BroadcastSystemMessage(BSF_POSTMESSAGE, @dwRecipient, MSG_ADD_ADDRESS, X, 0); end; und auf der Empfangenseite:
Delphi-Quellcode:
Wie zu erwarten - sonst würde der Post hier nicht stehen - klappt das nicht. procedure TForm2.WndProc(var Message: TMessage); VAR A : P_Adresse; begin if Message.Msg = MSG_ADD_ADDRESS then Begin New(A); A := @Message.wparam; ShowMessage('ADRESSE HINZUFÜGEN !!!' + A^.Vorname); End; inherited; end; Mir stellt sich hier folgende Frage : Klappt es nicht, weil ich einen Fehler beim Pointerhandling mache oder kann es evtl. gar nicht funktionieren, da ich zwischen 2 Programmen keinen "Speicherbereich" übergeben kann ? Für eine Idee wäre ich sehr dankbar ! Tom |
AW: Datentransfer zwischen Programmen
Übertragung von Daten per Windows-Messages geht nur mit
![]() |
AW: Datentransfer zwischen Programmen
Ich würde den Austausch von Daten zwischen zwei Programmen heutzutage generell nicht mehr Windows Messages machen.
Persönlich finde ich glaube ich eine Kommunikation über TCP am elegantesten und vllt. sogar am einfachsten. |
AW: Datentransfer zwischen Programmen
Hallo und Herzlich Willkommen in den Heiligen Hallen des Wissens und des Wahnsinns :love:
Mit einem einfachen Delphi-Integer hat es unter 32 Bit zufällig geklappt da
Delphi-Quellcode:
bzw.
WPARAM
Delphi-Quellcode:
definiert ist als
LPARAM
Delphi-Quellcode:
. Unter 32 Bit sind das 4 Byte, ebenso wie ein
LONG_PTR
Delphi-Quellcode:
unter Delphi (
Integer
![]() Wenn es jetzt um einen Record geht bleibt nur die Möglichkeit einen Zeiger auf diesen Speicherbereich über den LPARAM/WPARAM auszutauschen. Leider (oder auch: Zum Glück) hast du mit deiner Vermutung Zitat:
Natürlich ist es möglich nun genau das zu tun, dafür scheint man etwas mit einer ![]() Es ist sicher auch irgendwo eine Geschmacksfrage, es gibt ja so viele Möglichkeiten für Interprozesskommunikation (IPC) unter Windows. Das mit
Delphi-Quellcode:
ist eine von vielen. - Aber ich persönlich würde Kommunikation zwischen 2 Prozessen nicht über Messages machen - Es sei denn du hast ganz bestimmte Anforderungen wie super-niedrige Latenz oder super-hohen Durchsatz.
WM_COPYDATA
Ich persönlich kann mich nicht mehr erinnern wann ich das letzte mal IPC nicht über Sockets gemacht habe - Ein Programm hat einen Netzwerksocket offen und lauscht, das andere verbindet sich und schickt. Das ist nicht nur leichter zu debuggen, es funktioniert auch praktisch ohne Mehraufwand über Rechner- und Betriebssystemgrenzen hinweg. Aber klar, das wäre nicht so "schnell" wie blanken Speicher auszutauschen. Hoffentlich hilft dir das ein bisschen weiter, ich habe mit WM_COPYDATA oder Shared Memory (eine weitere Möglichkeit) noch nie etwas gemacht... |
AW: Datentransfer zwischen Programmen
Kurze Strings sind Managed Types, sprich, sie haben eine Referenzzählung und werden initialisiert.
Das bedeutet, dass sie am Ende der Routine freigegeben werden. Du brauchst PChar. Außerdem solltest du Pointer immer nach NativeInt und nicht nach Integer casten, denn Integer ist immer 32 Bit (auch auf 64-Bit Systemen), was dort zu Fehlern führt. |
AW: Datentransfer zwischen Programmen
Entschuldigung Dennis
Diese Aussage ist schlicht falsch. Zitat:
Ein Shortstring kann maximal 255 Zeichen aufnehmen. Du kannst das als Array of Ansichar betrachten, wobei in Array[0] die länge steht. String[xx] is eine kürzere Version davon. Ein String[20] z.b ist 21 Byte gross in [0] steht die Aktuelle Länge im Rest die Daten. Deshalb haben wir in Delphi (Windows) immer noch Strings die mit Index ab 1 arbeiten |
AW: Datentransfer zwischen Programmen
Ja richtig. Hä, ich weiß aber jetzt nicht wie das im Widerspruch zu dem von mir gesagten stehen soll.
Versuch es mal mit PChars. Also bei mir funktioniert das bisher immer ohne Probleme. |
AW: Datentransfer zwischen Programmen
Wenn Du Daten per Message an eine andere Anwendung übergeben willst ist WM_COPYDATA die einzige generelle Methode, wie schon in einigen der anderen Antworten gesagt. Die Message bekommt von Windows eine Sonderbehandlung um die übermittelten Daten aus dem Addressbereich des Senders in den des Empfängers zu kopieren. Allerdings sollte man diese Message tunlichst nicht per BroadcastMessage an *alle* Fenster verschicken, sondern gezielt an dass Message-Handle des Empfängers.
Ich habe in meinem Archiv einen alten Post zu dem Thema gefunden, der Dir vielleicht den Einstieg erleichtert. Die Frage war damals, wie man für eine Anwendung, von der nur eine Instanz zur Zeit laufen soll, Parameter auf der Kommandozeile von einer 2. Instanz an die erste schickt, bevor die 2. sich beendet. I take it you want to pass the commandline from a second instance of your program to the already running first instance. Open the projects DPR file (Project|View source) and add this line immediately after the Begin of the main block: If Alreadyrunning Then Exit; Then scroll up and add this function after the Uses clause: Function AlreadyRunning: Boolean; Var wnd: HWND; S: String; copydata: TCopyDataStruct; Begin wnd:= FindWindow('TMyAppsMainformclass', Nil ); Result := wnd <> 0; If Result and (ParamCount > 0) Then Begin S:= ParamStr(1); With copydata Do Begin dwData := 0; cbData := Sizeof(Char)*(Length(S)+1); {Need to transfer terminating #0 as well} lpData := @S[1]; End; SendMessage( wnd, WM_COPYDATA, 0, LPARAM( @copydata )); End; End; Note that you need to make sure the main form class for your application has a reasonably unique name, so FindWindow finds the correct window. The second change needed is made to the main form class itself. It needs a handler for the WM_COPYDATA message. private { Private declarations } procedure WMCopyData(Var msg: TWMCopyData); message WM_COPYDATA; Procedure TMyAppsMainformclass.WMCopyData(Var msg: TWMCopyData); Var param : String; Begin param := PChar(msg.CopyDataStruct^.lpData); ...process param End; |
AW: Datentransfer zwischen Programmen
Hallo an alle,
vielen Dank für Eure Anregungen und den Beispielcode. Ich werde es aus Kompatibilitätsgründen erst mit der PChar Variante versuchen, ansonsten müsste ich zig vorhandene PlugIns umschreiben. (Es handelt sich bei den beiden "Programmen" um PlugIns, die mit dem Hauptprogramm kommunizieren sollen. Bislang wurden nur Integer Werte übergeben.) Also, nochmals DANKE ! Tom-Tom |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 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