Jetzt aber doch gelöst! Problem mit Sendmessage

Anfängerfragen zum Programmieren mit PureBasic.
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Jetzt aber doch gelöst! Problem mit Sendmessage

Beitrag 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.
Zuletzt geändert von bin_neu_hier am 14.09.2019 10:30, insgesamt 3-mal geändert.
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Problem mit Sendmessage

Beitrag 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.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Problem mit Sendmessage

Beitrag von Kiffi »

@bin_neu_hier:

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

Grüße ... Peter
Hygge
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Problem mit Sendmessage

Beitrag 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.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Re: Gelöst! Problem mit Sendmessage

Beitrag 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.
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

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

Beitrag 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?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

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

Beitrag 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.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

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

Beitrag 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?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

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

Beitrag 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.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Antworten