Seite 1 von 2

Jetzt aber doch gelöst! Problem mit Sendmessage

Verfasst: 03.09.2019 19:24
von bin_neu_hier
Hallo!

habe gleichzeitig 3 Progs am Laufen, nämlich "Hausbelegung-Kalender", "Hausbelegung-Reminder" und "Hausbelegung-Vertrag"

Wenn in "...Vertrag" an einem Vertragsstatus irgendwas geändert wird, soll eine Info an "...-Kalender" und "...-Reminder" gesendet werden, damit diese ihren Datenstand updaten.

Habe ich so geschrieben:

Sender:

Code: Alles auswählen

Global handle
Global Message.s
Global cd.COPYDATASTRUCT


   handle = 0
   handle = FindWindow_(#Null,"Hausbelegung-Kalender")
    If handle <> 0
      Message.s="xxx"
      cd\dwData = 0
      cd\cbData = (Len(Message) + 1) * SizeOf(Character)
      cd\lpData = @Message
      SendMessage_(handle,#WM_COPYDATA,1,cd)
    EndIf
    
    handle = 0
    handle = FindWindow_(#Null,"Hausbelegung-Reminder")
    If handle <> 0
      Message.s="yyy"
      cd\dwData = 0
      cd\cbData = (Len(Message) + 1) * SizeOf(Character)
      cd\lpData = @Message
      SendMessage_(handle,#WM_COPYDATA,1,cd)
    EndIf

Empfänger:

Code: Alles auswählen

Procedure EmpfangCallback(WindowID,message,wParam,lParam)
  Protected result
  Protected *cd.COPYDATASTRUCT
  result = #PB_ProcessPureBasicEvents
  Select message
    Case #WM_COPYDATA
      SendMessage_(GadgetID(#update), #BM_CLICK, 0, 0)
  EndSelect
  ProcedureReturn result
EndProcedure


parentwindow = OpenWindow(#PB_Any, 800, 0, 795, 250, "Hausbelegung-Reminder", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
SetWindowCallback(@EmpfangCallback())
  
Meistens, updaten beide Progs wenn Sendmessage_ feuert, manchmal nur eines davon, d. h., eines erhält offenbar keine Nachricht. Evtl. findet es den Fenstertitel nicht und "handle" erhält keinen Wert. Wie kann man sicherstellen, dass "handle" einen Wert erhält, ohne dass das Prog blockiert, falls einer oder beide Empfänger gar nicht gestartet wurden?

Der Code ist natürlich durch viele Beispiele aus dem Forum inspiriert oder auch voll abgekupfert, will mich da nicht mit fremden Federn schmücken! Habe schon einige Versuche gehabt, auch mit Postmessage, hat nie "immer" funktioniert, einer der Empfänger hatte immer mal einen Aussetzer.

Re: Problem mit Sendmessage

Verfasst: 04.09.2019 00:25
von Bisonte
Da deine Beispiele so schonmal gar nicht laufen, muss man erstmal was lauffähiges bauen ...

Sender :

Code: Alles auswählen

Procedure.i SendToWindow(WindowTitle$, Message$)
  
  Protected cd.COPYDATASTRUCT
  Protected hWnd, Result = #False
  
  hWnd = FindWindow_(#Null, WindowTitle$)
  
  If hWnd
    cd\dwData = 0
    cd\cbData = Len(Message$) + SizeOf(CHARACTER)
    cd\lpData = @Message$
    SendMessage_(hWnd, #WM_COPYDATA, #Null, cd)
    Result = #True
  EndIf
  
  ProcedureReturn Result
  
EndProcedure

Debug SendToWindow("Hausbelegung-Kalender", "xxx")
Debug SendToWindow("Hausbelegung-Reminder", "yyy")
Empfänger (hier nur das "Reminder" Fenster)

Code: Alles auswählen

#update = 1

Procedure EmpfangCallback(WindowID,message,wParam,lParam)
  Protected result
  Protected *cd.COPYDATASTRUCT
  result = #PB_ProcessPureBasicEvents
  Select message
    Case #WM_COPYDATA
      *cd = lParam
      If *cd
        Debug PeekS(*cd\lpData) ; Um die geschickte Nachricht auszulesen
      EndIf
      SendMessage_(GadgetID(#update), #BM_CLICK, 0, 0)
      Result = #True ; Wichtig !!!
  EndSelect
  ProcedureReturn result
EndProcedure


OpenWindow(0, 0, 0, 640, 480, "Hausbelegung-Reminder", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)

ButtonGadget(#update, 20, 20, 200, 20, "Update")

SetWindowCallback(@EmpfangCallback())

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_CloseWindow
      Break
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Debug "Button clicked"  
      EndSelect
  EndSelect
  
ForEver
Ob ein Fenster existiert, prüfe ich beim Senden, bevor überhaupt was zusammengebaut wird.
Wenn das Senden geklappt hat, gibt die Prozedure ein #True zurück.

Beim Empfang muss man darauf achten, das ein "#True" als "Result" aus dem Callback gebracht wird,
ansonsten funktioniert es nicht.

Re: Problem mit Sendmessage

Verfasst: 04.09.2019 08:51
von Kiffi
@bin_neu_hier:

Zum Thema IPC ("Prozesse kommunizieren miteinander") kannst Du Dir beispielsweise auch SharedMemory anschauen.

Grüße ... Peter

Re: Problem mit Sendmessage

Verfasst: 04.09.2019 08:56
von Bisonte
Kiffi hat geschrieben:@bin_neu_hier:

Zum Thema IPC ("Prozesse kommunizieren miteinander") kannst Du Dir beispielsweise auch SharedMemory anschauen.

Grüße ... Peter
Daran hatte ich auch gedacht ;)
Da wäre nur das Problem, dass man den ständig periodisch abfragen muss. Wenn man nur ein "Signal" braucht, ist das eigentlich ungünstig.

Re: Gelöst! Problem mit Sendmessage

Verfasst: 04.09.2019 18:19
von bin_neu_hier
Super! Läuft wie geschmiert! Besten Dank!

Da fällt mir kleines Heinz-Ehrhardt-Gedicht ein:

Ich wälze keine Problöeme,
ich denk' nicht über die Zeit,
ich weiß nicht, wohin ich dann käme,
ich weiß nur, ich käme nicht weit.

(so oder so ähnlich, ist schon jahrzehnte her, dass ich das mal aufgeschnappt habe)

Ohne Euch und Pureboard käme ich sicherlich auch nicht sehr weit.

Re: Leider doch nicht gelöst! Problem mit Sendmessage

Verfasst: 11.09.2019 21:09
von bin_neu_hier
Hallo Bisonte,

habe Deine Programmfragmente 1:1 in meine Anwendung eingebaut (das Debug habe ich mit einer Variablenzuweisung ersetzt). In der Anwendung werden nach ein paar Dateioperationen 2 andere, parallel laufende Anwendungen (die vorher gestartet wurden) per Sendmessage informiert, damit diese ihren Datenstand aktualisieren.

Das funktioniert auch meistens, aber nicht immer. Manchmal führt eine der beiden Anwendungen das update nicht aus, in seltenen Fällen sogar beide.

Habe schon mit verschiedenen Delays experimentiert, beispielsweise mit Delay(2000) nach dem letzten "closefile" verzögert und erst dann per Sendmesswage "gefunkt" - hat auch nichts gebracht.

Wäre da Postmessage zuverlässiger?

Re: Leider doch nicht gelöst! Problem mit Sendmessage

Verfasst: 11.09.2019 21:24
von Mijikai
UDP/TCP wäre eventuell noch eine Möglcihkeit.

Re: Leider doch nicht gelöst! Problem mit Sendmessage

Verfasst: 12.09.2019 05:39
von Bisonte
Für eine dauerhafte Datenverbindung ist das ganze auch nicht gedacht.
Da ist eine UDP Netzwerkverbindung dann die beste Lösung (sofern die Programme auf dem gleichen Rechner oder gleichem Netzwerk laufen).
Ansonsten TCP.

Re: Leider doch nicht gelöst! Problem mit Sendmessage

Verfasst: 13.09.2019 18:53
von bin_neu_hier
Hallo!

Es geht nicht um eine dauerhafte Datenverbindung. Mein Sender soll an zwei Empfänger ein Zeichen geben, damit die Empfänger ihre Updateprozedur durchlaufen. Und das nur alle paar Minuten mal.

Kann man mit Postevent() in einer fremden Anwendung den Klick auf den "Update"-Button simulieren?

Re: Leider doch nicht gelöst! Problem mit Sendmessage

Verfasst: 13.09.2019 19:22
von RSBasic
bin_neu_hier hat geschrieben:Kann man mit Postevent() in einer fremden Anwendung den Klick auf den "Update"-Button simulieren?
Nein, aber du kannst mit WinAPI den Klick auf einen Button eines fremden Fensters simulieren:

Code: Alles auswählen

SendMessage_(Handle, #BM_CLICK, 0, 0)
Die Handle-Nummer kannst du mit FindWindow_()/FindWindowEx_() oder EnumWindows_()/EnumWindowsEx_() ermitteln.