Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Daten zwischen 2 Prozessen austauschen?? Wie? (https://www.delphipraxis.net/788-daten-zwischen-2-prozessen-austauschen-wie.html)

thomasdrewermann 6. Sep 2002 17:22


Daten zwischen 2 Prozessen austauschen?? Wie?
 
Hi,
ich möchte zwei programme programmieren, die untereinander daten austausen können, wenn beide laufen. (NICHT ÜBERS NETZWERK!!!!)

MFG
Thomas

d3g 6. Sep 2002 18:37

Hi thomas,

schau mal im PSDK/MSDN unter dem Stichwort WM_COPYDATA, das sollte das richtige für dich sein.

MfG,
d3g

Daniel 6. Sep 2002 18:38

Alternativ schau' im PSDK nach den Stichworten "Shared Memory" oder "Pipe".


Grüße,
Daniel

Christian Seehase 6. Sep 2002 18:39

Moin Thomas,

welches Volumen können die Daten denn haben, und von welchem Typ sind diese?

So auf Anhieb fallen mir vier Möglichkeiten ein:
  1. Verwendung von WM_COPYDATA
  2. Registieren einer eigenen Message via RegisterWindowMessage
  3. Nutzung der Atom Table
  4. DDE (auch wenn ich keine Ahnung von der Umsetzung habe ;-)


EDIT: 19:37, 19:38, 19:39 :mrgreen: /EDIT

thomasdrewermann 6. Sep 2002 20:08

Das mit der Window-Message hört sich gut an auch für Strings???
Kann mir jemand n Code-Schnipsel posten?

d3g 6. Sep 2002 20:55

Hi Thomas,

Sender:

Code:
procedure TForm1.FormCreate(Sender: TObject);
var
  aCopyData: TCopyDataStruct;
  p: PChar;
begin
  p := 'Hallo!';

  with aCopyData do begin
    dwData := 0;
    cbData := StrLen(p) + 1;
    lpData := p;
  end;

  SendMessage(FindWindow('TFormRecv', nil), WM_COPYDATA, Longint(Handle),
              Longint(@aCopyData));

  Application.Terminate;
end;
Receiver:

Code:
type
  TFormRecv = class(TForm)
  private
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  end;

// ...

procedure TFormRecv.WMCopyData(var Msg: TWMCopyData);
begin
  ShowMessage(String(Msg.CopyDataStruct.lpData));
end;
MfG,
d3g

thomasdrewermann 7. Sep 2002 06:29

Hat super geklappt, danke für den Source CODE!!!!


MFG
THOMAS

thomasdrewermann 18. Sep 2002 18:11

Irgendwie ist das jetzt unzuverlässig :-(

Hat jemand noch ne Idee warum???
Da kommt nie ne Messagebox, obwohl die namen Stimmen :-(

Luckie 18. Sep 2002 18:53

Messagebox? Die müßtest du dan aber gemacht haben oder?

Sollte eigentlich funktioniern. Überprüf mal, ob das Fensterhandle gültig ist. Sprich, ob der Sender die Daten auch an das richtige Fenster schickt.

thomasdrewermann 18. Sep 2002 20:28

Kann das sein, dass das nur mit sichtbaren Fenstern geht?

Luckie 18. Sep 2002 20:35

Nein. Es sollte nur existieren das Fenster.

thomasdrewermann 18. Sep 2002 20:37

Das ist ganz komisch, wenn ich den Empfäner einmal sichtbar eine Nachricht zusende, dann empfängt er sie. Wenn ich das empfänger-fenster dann unsichtbar mache auch. Wenn ich ihm die erste Nachricht aber im Unsichtbaren Modus schick, empfängt er sie net :-(

thomasdrewermann 18. Sep 2002 20:47

Liste der Anhänge anzeigen (Anzahl: 1)
Hier ich hab die beiden EXE-DATEIN zum testen angefügt.
Ihr müsst alles in ein Verzeichnis kopieren.
Sender=Project.exe
Empfänger=applock.exe

Luckie 18. Sep 2002 21:04

Das war das falsche Archiv. Eine Exe Applock.exe und zwei Ini's. und eine DLL fehlt.

thomasdrewermann 18. Sep 2002 21:13

Liste der Anhänge anzeigen (Anzahl: 1)
jetzt aber ;-)

Luckie 18. Sep 2002 21:23

Kann man dein Programm auch irgendwie wieder beenden? Ohne es über den Taskmanger abzuschießen?

Und was soll das werden wenn es fertig ist? Eine kleine Bedienungsanleitung wäre auch nicht schlecht.

Bei mir kommt der Exe-Name auch an, wenn es in die TNA minimiert ist (Win2000 SP2).

thomasdrewermann 18. Sep 2002 21:29

Wie mienste, der EXE-Name kommt auch an?
Ich habe gerade gemert, das das Prog nicht unter Win95, Win98 und WinME läuft.
Ich schreib noch eine Bedienungsanleitung :-)

Luckie 18. Sep 2002 21:35

Na Projekt1 schickt doch den Dateinamen an das andere Programm oder? Und das geht auch wenn das zweite Programm in der TNA minimiert ist. Das war doch dein Problem oder?

Was ist der Sinn des Programmes? Was soll das werden?

thomasdrewermann 18. Sep 2002 22:00

Ja, ich hab es gerade wie schon gesagt unter Win98 getestet, die neue Version läuft auch unter Win98 :-) DANKE FÜr DEINE MÜHE ;-) :D

Luckie 18. Sep 2002 22:03

Ich wüprde aber immer noch gerne wissen, was ich da getestet habe, bzw. was es werden soll.

thomasdrewermann 19. Sep 2002 13:29

Es ist ein Teil der Schulschutz-software die ich und theomega entwickeln.
Diese Teil, sperrt alle anwendungen. Der Lehrer kann dann eine Anwendung freigeben. Das Basis-Prg auf dem Client sendet diese Anwedung dann an die anwendung, die du testetes.

Ich hoffe du konntest was mit der Beschreibung anfangen :-)

thomasdrewermann 29. Sep 2002 14:51

Kann mir jemand noch ein Code zur Verwendung von WM_COPYDATA basteln?

Wäre echt nett, da die Register Window Message Methode nicht sehr zuverlässig ist :-(

MFG
Thomas

Christian Seehase 29. Sep 2002 16:52

Moin Thomas,

bist Du mal so gut, mir zu erklären, was an RegisterWindowMessage unzuverlässig ist? ;-)

Um zu verhindern, dass Du einen String angibst, der eventuell schon von einem anderen verwendet wird, lässt Du Dir am Besten von der IDE einen GUID String generieren (Strg-Shift-G). Der sollte, zumindest gemäss der Theorie, weltweit eindeutig sein.

thomasdrewermann 29. Sep 2002 18:34

Mal kommt die Message an mal passiert gar nichts :-(


Was kann ich damit verhindern?
Zitat:

Um zu verhindern, dass Du einen String angibst, der eventuell schon von einem anderen verwendet wird, lässt Du Dir am Besten von der IDE einen GUID String generieren (Strg-Shift-G). Der sollte, zumindest gemäss der Theorie, weltweit eindeutig sein.
Was ist ein IDE/GUID String?


MFG
Thomas

Chewie 29. Sep 2002 18:43

GUID heißt Global Unique IDentifier. Das ist eine ID, die weltweit nur einmal vorkommen soll. In der IDE von Delphi gibt es eine Option, so einen zu erzeugen. Eben besagtes Strg+Alt+G.

thomasdrewermann 29. Sep 2002 18:45

Und welchen Fehler kann ich jetzt damit verhindern?
Oder was bringt mich das Weiter?
Was kann ich mit so einer ID machen?

Christian Seehase 29. Sep 2002 19:20

Moin Thomas,

Du hattest die Zuverlässigkeit von Messages angezweifelt, die Du mit RegisterWindowMessage erzeugst.
Das würde stimmen, wenn der String der übergeben wird nicht eindeutig ist. Nimmst Du an dieser Stelle aber einen GUID String, so sollte dieser eindeutig sein.

Wenn die Message mal ankommt, und mal nicht, würde mich mal interessieren, wie Du das Ganze implementiert hast.
Da die Message ja nur einmal registriert werden muss, platzierst Du den Aufruf von RegisterWindowMessage am Besten im initialization Abschnitt des Hauptformulares.

Ich schau aber auch noch mal nach, wo ich eine Demo für WM_COPYDATA habe.

thomasdrewermann 29. Sep 2002 19:46

Die Window Message wird doch beim Sender erzeugt, oder?

Wenn ja, dann hab ich die tatsächlich öfter erzeugt :oops:

MFG
Thomas

Christian Seehase 30. Sep 2002 00:38

Moin Thomas,

wie oft Du RegisterWindowMessage in einem Programm aufrufst spielt keine Rolle. Wenn jedesmal der gleiche String übergeben wird, erhältst Du auch jedes mal den gleichen Rückgabewert. Deshalb ist es auch wichtig einen eindeutigen String anzugeben.
Aufrufen musst Du das bei allen beteiligten Programmen (müssen nicht nur zwei sein). Damit auch alle die gleiche Message erhalten muss auch bei allen beteiligten Programmen exakt der gleiche String übergeben werden.

Um allen Programmen die die entsprechende Message behandeln können gleichzeitig die Message zu schicken könntest Du

SendMessage(HWND_BROADCAST,.....)

verwenden. Es wird also kein spezielles Handle angegeben, sondern eben, als Ersatz, HWND_BROADCAST.
Da sich dieser Aufruf allerdings auf alle Fenster bezieht sollte man ihn sparsam einsetzen.

Luckie 30. Sep 2002 01:04

Zitat:

Zitat von Christian Seehase
Es wird also kein spezielles Handle angegeben, sondern eben, als Ersatz, HWND_BROADCAST.
Da sich dieser Aufruf allerdings auf alle Fenster bezieht sollte man ihn sparsam einsetzen.

Und wenn man dann doch eine doppelte MessageID erwischt hat, könnte das hier zu Problemen führen.

Christian Seehase 30. Sep 2002 10:06

Moin Luckie,

das ist zwar soweit richtig, allerdings ist die Chance dass so etwas passiert bei Verwendung eines GUID Strings wohl nahezu ausgeschlossen.
Ansonsten würde auch das ganze Prinzip von MSI oder COM nicht so richtig sauber funktionieren können.

Luckie 30. Sep 2002 11:19

Schon klar, ich meine ja nur.

Andererseits, wenn man beide Anwendungen selber programmiert, sollte man eigentlich in der Lage sein seine Fenster zufinden via Klasse oder Titel. Warum also andere Fenster mit der Nachricht belästigen?

"Programmierer gegen Windows-Message Spam :!:"

thomasdrewermann 30. Sep 2002 17:42

Wo setzte ich den in dem Code-Beispiel die GUID ein?

Christian Seehase 30. Sep 2002 17:46

Moin Thomas,

das würde ich so machen:

Code:
[b]var[/b]
  Form1: TForm1;
  dwMessage : DWORD;

[b]implementation[/b]

[color=#000080]{$R *.DFM}[/color]

[b]initialization[/b]
[b]begin[/b]
  dwMessage := RegisterWindowMessage('BB3D446B-80C1-4A0E-843F-1376A2CEF1D6');
[b]end[/b];
Die GUID ist natürlich nur ein Beispiel. Sie muss aber zwingend in jedem der beteiligten Programme exakt die gleiche sein.

thomasdrewermann 30. Sep 2002 17:49

Wie bau ich das bezogen auf diesen Code ein?
Sender:

Code:
Code:
procedure TForm1.FormCreate(Sender: TObject);
var
  aCopyData: TCopyDataStruct;
  p: PChar;
begin
  p := 'Hallo!';

  with aCopyData do begin
    dwData := 0;
    cbData := StrLen(p) + 1;
    lpData := p;
  end;

  SendMessage(FindWindow('TFormRecv', nil), WM_COPYDATA, Longint(Handle),
              Longint(@aCopyData));

  Application.Terminate;
end;

Receiver:
Code:
Code:
type
  TFormRecv = class(TForm)
  private
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  end;

// ...

procedure TFormRecv.WMCopyData(var Msg: TWMCopyData);
begin
  ShowMessage(String(Msg.CopyDataStruct.lpData));
end;

Christian Seehase 30. Sep 2002 18:53

Liste der Anhänge anzeigen (Anzahl: 1)
Moin Thomas,

da in Deinem Beispiel mit WM_COPYDATA als Message gearbeitet wird: Gar nicht. ;-)

Ich hab' da mal eine Demo angehängt für RegisterWindowMessage.

Beim Button "Einfach" wird, mittels der selbst registrierten Message, und HWND_BROADCAST an alle Fenster die Message geschickt. Alle laufenden Instanzen des Programmes erhalten den Index der aktuell angewählten Zeile weitergeleitet, so dass im Edit Feld der Inhalt der Zeile steht.

Beim Button "Gezielt" wird, mit Hilfe des Fenstertitels, gezielt nach allen laufenden Instanzen des Programmes gesucht, und diesen gezielt die eigene Message geschickt. Hierbei wird dann der Pointer auf einen String als Parameter mitgegeben, und dieser String dann im Edit Feld angezeigt.

Man könnte das Ganze noch so ergänzen, dass die sendende Instanz eine Message an sich selber verwirft, und/oder das kein String, sondern ein Pointer auf eine beliebige andere (eigene) Struktur übergeben wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:00 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