AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) HWND_BROADCAST, ist relativ langsam, blockiert das System usw.
Thema durchsuchen
Ansicht
Themen-Optionen

HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

Ein Thema von Kostas · begonnen am 11. Mai 2020 · letzter Beitrag vom 16. Mai 2020
Antwort Antwort
Seite 1 von 2  1 2      
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 11. Mai 2020, 18:04
Hallo Zusammen,

ich habe ein Testprojekt angehängt.
In diesem Projekt sendet und empfängt die Anwendung BROADCAST Nachrichten in einer Anwendung!

Die Test-Anwendung scheint so weit zu funktioniert und macht auch scheinbar keine Probleme da sie auch kaum Funktionalität beinhaltet. Integriere ich es jedoch in meiner Anwendung kommt es vor dass die Anwendung spürbar langsamer wird. Auch habe ich den Effekt dass wenn eine Nachricht gesendet wird und Thunderbird im Hintergrund aktiv ist, wird Thunderbird in den Vordergrund gezogen. Warum Thunderbird, keine Ahnung.

Die gesamte Technik habe ich in der Form BroatcastSenderReceiver.pas gesteckt. Ich binde die Form ein der MainForm ein und registriere einen Event.

Ich habe es in eine separate Form extrahiert und nicht in ein DataModul da SendMessage ein Form handle benötigt.

Das Ziel ist eigentlich, eine Datenbank-Anwendung wird auf einem Rechner zweimal gestartet, und läuft jeweils auf einem Monitor, wird auch so benötigt. Wenn die Anwendung A einen Datensatz ändert, soll die Anwendung B ein refresh durchführen wenn zufällig der gleiche Datensatz angezeigt wird. Als Datenbank verwende ich Firebird. Ich habe auch die Events benutzt die Firebird und Firedac anbietet, doch es gab fälle da hat es eben nicht zuverlässig funktioniert. Deshalb versuche ich jetzt selbst über BROADCAST Nachrichten.

Ich habe leider keine Erfahrung mit Windows messaging. Was zuverlässig funktionieren würde wäre eine TCP Kommunikation. Für eine einfache Benachrichtigung wollte ich eben keinen Listener aufsetzen. Möglicherweise sollte ich keine BROADCAST Nachricht senden sondern nur eine bestimmte registrieren, aber wie gesagt, da habe ich keine Erfahrung damit.

Möglicherweise ist jemand dabei der Erfahrung mit Windows messaging hat und kann mir an den angehängten Projekt zeigen was nicht in Ordnung ist.
Angehängte Dateien
Dateityp: zip SenderReceiverMain.zip (2,9 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
763 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 11. Mai 2020, 18:35
Mit HWND_BROADCAST in deinem Code

SendMessage(HWND_BROADCAST, WM_COPYDATA, Integer(Handle), Integer(@copyDataStruct)) ; sendest du deine Nachricht ja gleich an alle Apps (auch deinem Thunderbird). Es genügt, wenn du die Nachricht von deiner App A an deine App B (und umgekehrt) sendest.

A benötigt dazu ein Handle HANDLE_B von B und umgekehrt B eines von A. In App A sendest du dann SendMessage(HANDLE_B,....)

Beispiele gibt's viele:
https://www.thoughtco.com/send-infor...ations-1058476

Du musst daran denken, dass SendMessage(…) erst zurückkehrt, wenn die Gegenstelle die Meldung quittiert hat. Vielleicht willst du dies - eventuell aber auch nicht.

Via Sockets ist die Sache vielleicht flexibler, wenn die Apps A und B irgendwann nicht mehr auf der gleichen Kiste laufen (?).
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#3

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 11. Mai 2020, 18:41
Benutze das Broadcast doch nur einmal um die beiden Prozesse miteinander zu verbinden. Jeder Prozess sendet beim Start ein Broadcast mit seinem Handle. Der empfangende Prozess sendet sein Handle zurück und verwendet dabei als Ziel das Handle des Broadcasters. Danach sind die beiden Handles jeweils bekannt und die Prozesse können sich privat untereinander Messages zusenden, wie Michael das vorgeschlagen hat. Bei Programmende meldet sich der Prozess bei seinem Gegenüber wieder ab. Das Broadcast wird somit nur einmal bei jedem Programmstart benötigt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 11. Mai 2020, 19:12
Eigentlich schickt man Broadcasts nicht via SendMessage, sondern per PostMessage umher, dazumal man sowieso keine Rückgabewerte bekommen kann,
ansonsten musst du natürlich warten, bis ALLE TopLevel-Fenster fertig sind, womöglich auch mit der Fehlerbehandlung deiner "unverständlichen" Daten.

Gut, WM_COPYDATA schickt man natürlich via SendMessage an ein Programm Fenster,
und ich bin mir auch relativ sicher, dass man WM_COPYDATA eh nicht als Broadcast an ALLE versenden sollte,
und du willst nicht wissen was alles kaputt gehen kann, wenn irgendein Programm das Format deines WM_COPYDATA nicht versteht, weil es etwas Anderes erwartet.
Also siehe der Vorschlag meines Vorredners.
$2B or not $2B

Geändert von himitsu (11. Mai 2020 um 19:22 Uhr)
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
763 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 11. Mai 2020, 23:33
... oder nutze HWND_BROADCAST gar nicht.

Wenn du von App B den Namen des Fensters FB kennst, welches die WM_COPYDATA Meldungen auswerten soll, dann kannst du in App A das Handle HANDLE_B von FB mittels FinwdWindow ermitteln.

Danach sendest du deine Daten von FA nach FB mittels SendMessage( HANDLE_B, WM_COPYDATA, ... );

Etwa so:

https://www.delphipraxis.net/201045-..._copydata.html

Oder: Falls App A immer App B startet, dann kannst du beim Starten von App B als Parameter das Handle des Fensters FA übergeben. App B liest den Wert HANDLE_A via paramstr(..) aus.


Vielleicht interessiert dich in diesem Zusammenhang auch
WM_MEINEMELDUNG := RegisterWindowMessage( 'MeinePrivateMeldung' );

https://docs.microsoft.com/en-us/win...windowmessagea
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#6

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 12. Mai 2020, 02:56
Zitat:
Wenn du von App B den Namen des Fensters FB kennst
Ich hoffe du meinst den Namen der Klasse und nicht die Caption, welche eventuell Statuswerte enthalten oder eine Übersetzung.

Unter dem Punkt Interprozesskommunikation (IPC) gibt es noch unzählige weitere Möglichkeiten.
Man kann sich sogar ein unsichtbares MessageOnlyWindow (ähnlich dem Application.Handle) selbst basteln und via GetWindowLong(GWL_USERDATA) direkt einen Handle/TCPPort/Sonstwas oder eben dort geziehlt WM_COPYDATA hinsenden/abfragen.
$2B or not $2B
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 12. Mai 2020, 07:56
Vielen Dank für die vielen Antworten.
Ich werde leider erste heute Abend dazu kommen mich damit zu beschäftigen.

Die Anwendung um die es geht ist eine MDI Anwendung. Da hatte ich massive Probleme das Handle zu bekommen, bzw. die Nachrichtien sind nie angekommen. Deshalb habe ich eine normale Form die zwar instantiiert jedoch nicht angezeigt wird und die Nachrichten per eigenen Event bereitstellt. Am liebsten wäre mir allerdings ein DataModul. Gibt es dafür auch eine Lösung oder muss es immer eine Form sein?
  Mit Zitat antworten Zitat
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
763 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 12. Mai 2020, 09:02
Zitat:
Wenn du von App B den Namen des Fensters FB kennst
Ich hoffe du meinst den Namen der Klasse und nicht die Caption, welche eventuell Statuswerte enthalten oder eine Übersetzung.
Mir "völlig egal"* - wenn du willst auch gleich Klassenname und Windowstitel/Caption - Hauptsache ist: Der Wert muss systemweit eindeutig sein. Wenn Kostas ein unsichtbares Fenster nutzt, dann ändert Kostas wohl kaum was an der Caption.

* Ich nehme auch einen eindeutigen Klassennamen
Michael Gasser
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#9

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 12. Mai 2020, 09:28
muss es immer eine Form sein?
Es kann jede beliebige Klasse sein. Man muss sie nur passend aufbereiten. Hier ein Basisgerüst:

Delphi-Quellcode:
type
  TMessageListener = class
  private
    FWindowHandle: HWND;
    procedure WndProc(var Msg: TMessage);
  public
    constructor Create;
    destructor Destroy; override;
  end;

constructor TMessageListener.Create;
begin
  inherited;
  FWindowHandle := AllocateHWnd(WndProc);
end;

destructor TMessageListener.Destroy;
begin
  if FWindowHandle <> 0 then
  begin
    DeallocateHWnd(FWindowHandle);
    FWindowHandle := 0;
  end;
  inherited;
end;

procedure TMessageListener.WndProc(var Msg: TMessage);
begin
  Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Kostas

Registriert seit: 14. Mai 2003
Ort: Gerstrhofen
1.099 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: HWND_BROADCAST, ist relativ langsam, blockiert das System usw.

  Alt 12. Mai 2020, 19:44
Hallo Uwe,

deinen Vorschlag mit der eigenen Klasse würde ich gerne umsetzen.

Ich habe folgenden Zustand: die gleichen source werden über zwei unterschiedliche .dpr Dateien kompiliert. Somit habe ich eine Eingang.exe und eine Ausgang.exe Die Anwendung selbst ist eine MDI-Anwendung. Ich könnte also eine zwei Klassen haben z.B.: TMessageListernerE und eine TMessageListernerA anlegen und über die .dpr entsprechend einbinden. Mit findWindow kann ich vermutlich nur sichtbare Formklassen finden. Gibt es eine Möglichkeit wie findWindow um die zwei Klassen TMessageListernerE und TMessageListernerA die auch keine Forms sind zu finden? Dann könnte ich gleich direkt adressieren und brauchte auch kein Broadcast um das handle an Eingang zu Ausgang und umgekehrt zu übertragen.

Alternativ könnten ich wenn findWindow auch unsichtbare Forms finden könnte, auch zwei Forms Eingang und Ausgang verwenden und in der jeweiligen Projektdatei entsprechend einbinden.

Zum nächsten, möchte die Nachricht versenden und NICHT warten bis die Anwendung antwortet. Sollte ich dafür besser PostMessage anstelle von SendMessage verwenden?
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 02:14 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