AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Datentransfer zwischen Programmen

Ein Thema von Tom-Tom · begonnen am 25. Jan 2019 · letzter Beitrag vom 28. Jan 2019
Antwort Antwort
Tom-Tom

Registriert seit: 19. Apr 2010
Ort: Remscheid
25 Beiträge
 
#1

Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 16:04
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:

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;
Wie zu erwarten - sonst würde der Post hier nicht stehen - klappt das nicht.

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
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 17:34
Übertragung von Daten per Windows-Messages geht nur mit WM_COPYDATA
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 17:39
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.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 17:42
Hallo und Herzlich Willkommen in den Heiligen Hallen des Wissens und des Wahnsinns

Mit einem einfachen Delphi-Integer hat es unter 32 Bit zufällig geklappt da WPARAM bzw. LPARAM definiert ist als LONG_PTR . Unter 32 Bit sind das 4 Byte, ebenso wie ein Integer unter Delphi (Quelle).

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:
kann es evtl. gar nicht funktionieren, da ich zwischen 2 Programmen keinen "Speicherbereich" übergeben kann ?
Recht - Ein Prozess kann nicht einfach in den Daten eines anderen Prozesses wühlen.

Natürlich ist es möglich nun genau das zu tun, dafür scheint man etwas mit einer WM_COPYDATA-Nachricht vorher anstellen zu müssen.

Es ist sicher auch irgendwo eine Geschmacksfrage, es gibt ja so viele Möglichkeiten für Interprozesskommunikation (IPC) unter Windows. Das mit WM_COPYDATA 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.

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...
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
485 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 17:44
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.
Dennis
  Mit Zitat antworten Zitat
Fritzew

Registriert seit: 18. Nov 2015
Ort: Kehl
678 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Datentransfer zwischen Programmen

  Alt 25. Jan 2019, 21:15
Entschuldigung Dennis

Diese Aussage ist schlicht falsch.

Kurze Strings sind Managed Types, sprich, sie haben eine Referenzzählung und werden initialisiert.
Das bedeutet, dass sie am Ende der Routine freigegeben werden.
kurze Strings sind keine Managed Types, sondern klar definierte Typen.
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
Fritz Westermann
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
485 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Datentransfer zwischen Programmen

  Alt 26. Jan 2019, 00:26
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.
Dennis
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#8

AW: Datentransfer zwischen Programmen

  Alt 26. Jan 2019, 14:02
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;
Peter Below
  Mit Zitat antworten Zitat
Tom-Tom

Registriert seit: 19. Apr 2010
Ort: Remscheid
25 Beiträge
 
#9

AW: Datentransfer zwischen Programmen

  Alt 28. Jan 2019, 08:32
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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz