Programm2 soll Programm1 eine Event schicken?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Skywalker
Beiträge: 77
Registriert: 22.09.2004 23:35

Programm2 soll Programm1 eine Event schicken?

Beitrag von Skywalker »

Ich versuche gerade selber eine Lösung zu finden, aber vielleicht hat von euch schon jemand eine Idee parat.

Folgendes Scenario:

Programm1 ist gestartet, befindet sich im SysTray, aber das Icon ist auf unsichtbar gestellt.
Beim Aufruf von Programm2 soll dieses dem Programm1 eine Nachricht schicken,
das es sich wieder zeigen soll, also im SysTray zu sehen ist.

Kann ich irgendwie ein Event schicken, oder so?

Gruß
Thomas
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich habe da vielleicht etwas für dich.
///Edit:

Hab das ganze von vorhin jetzt unter "Codes, Tipps & Tricks" untergebracht. Du findest es hier.

Wenn das allerdings nichts für dich ist, dann schau dir mal Rings SharedMemory-Userlib in der PureArea an.
Benutzeravatar
Skywalker
Beiträge: 77
Registriert: 22.09.2004 23:35

Beitrag von Skywalker »

Danke für die Antwort.
Dein Client /Server Code werde ich mir merken. Leider ist mir das zu komplex.
Auch das mit dem SharedMemory ist nicht übel, aber dadurch wird kein Event ausgelöst.
Möchte aber auf Timer Funktion verzichten, so kommt es also auch nicht in Frage.
Oder könnte ich irgendwie mit Programm2 ein Event in Programm1 auslösen? Dann würde SharedMemory mir doch weiter helfen.

Gruß
Thomas
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Skywalker hat geschrieben:Leider ist mir das zu komplex.
Du brauchst nur eine Window Message zu registrieren, und kannst
dann mit PostMessage_() an andere Fenster senden.

Das Handle des Fensters, an das Du senden möchtest, kannst
Du mit z.B. FindWindow_() bekommen, wenn Du den eindeutigen
Fenstername kennst.
Oder Du nimmst dafür #HWND_BROADCAST, dann geht die Nachricht
an alle Fenster. Aber nur Deine Programme reagieren darauf, da Du
Deine Nachricht ja im System registriert hast.

Kleines Beispiel:


Programm 1, öffnet ein unsichtbares Fenster und wartet auf
eine Nachricht. Trifft eine Nachricht ein, zeigt es das Fenster
wieder an und sendet eine Bestätigung zurück.
Wenn Programm 1 sich beendet, meldet es sich noch bei
Programm 2 ab, falls Programm 2 sich schonmal gemeldet
hatte.

Code: Alles auswählen

MYMESSAGE  = RegisterWindowMessage_("Skywalker-Message")

Enumeration
  #MSG_PING     = 1
  #MSG_RECEIVED
  #MSG_EXIT
EndEnumeration

If OpenWindow(0,200,200,200,200,#PB_Window_SystemMenu|#PB_Window_Invisible,"Skywalker Prog 1")
  CreateGadgetList(WindowID())
  ListViewGadget(1,0,0,200,170)
  ButtonGadget(2,50,175,100,20,"Verstecken")

  ; AddSystrayIcon etc...

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        If Absender
          ; Exit-Nachricht schicken
          PostMessage_(Absender,MYMESSAGE,WindowID(),#MSG_EXIT)
        EndIf
        Break
      Case #PB_Event_Gadget
        If EventGadgetID()=2
          If EventType()=#PB_EventType_LeftClick
            HideWindow(0,1)
          EndIf
        EndIf
      Case MYMESSAGE
        Absender  = EventwParam()
        Nachricht = EventlParam()
        AddGadgetItem(1,-1,"Nachricht eingetroffen:")
        AddGadgetItem(1,-1,"  Absender-Fenster: "+StrU(Absender,#LONG))
        Select Nachricht
          Case #MSG_PING     : A$ = "PiNG!"
          Case #MSG_RECEIVED : A$ = "Nachricht erhalten"
          Case #MSG_EXIT     : A$ = "Programm beendet"
          Default            : A$ = "Unbekannt"
        EndSelect
        AddGadgetItem(1,-1,"  Nachricht: "+A$)
        AddGadgetItem(1,-1,"----------")
        ; Bestaetigung, Message erhalten
        PostMessage_(Absender,MYMESSAGE,WindowID(),#MSG_RECEIVED)
        While WindowEvent():Wend
        HideWindow(0,0)
        SetWindowPos_(WindowID(0),#HWND_TOP,0,0,0,0,#SWP_NOSIZE|#SWP_NOMOVE)
    EndSelect
  ForEver
EndIf
Programm 2 pingt Programm 1 an:

Code: Alles auswählen

MYMESSAGE  = RegisterWindowMessage_("Skywalker-Message")

Enumeration
  #MSG_PING     = 1
  #MSG_RECEIVED
  #MSG_EXIT
EndEnumeration

If OpenWindow(0,450,200,200,200,#PB_Window_SystemMenu,"Skywalker Prog 2")
  CreateGadgetList(WindowID())
  ListViewGadget(1,0,0,200,170)
  ButtonGadget(2,50,175,100,20,"Broadcast Message")

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        If EventGadgetID()=2
          If EventType()=#PB_EventType_LeftClick
            ; Ping senden
            PostMessage_(#HWND_BROADCAST,MYMESSAGE,WindowID(),#MSG_PING)
          EndIf
        EndIf
      Case MYMESSAGE
        Absender  = EventwParam()
        If Absender <> WindowID()
          Nachricht = EventlParam()
          AddGadgetItem(1,-1,"Nachricht eingetroffen:")
          AddGadgetItem(1,-1,"  Absender-Fenster: "+StrU(Absender,#LONG))
          Select Nachricht
            Case #MSG_PING     : A$ = "PiNG!"
            Case #MSG_RECEIVED : A$ = "Nachricht erhalten"
            Case #MSG_EXIT     : A$ = "Programm beendet"
            Default            : A$ = "Unbekannt"
          EndSelect
          AddGadgetItem(1,-1,"  Nachricht: "+A$)
          AddGadgetItem(1,-1,"----------")
        EndIf
    EndSelect
  ForEver
EndIf
Mach am besten 2 EXEn daraus und probiere es mal.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Skywalker
Beiträge: 77
Registriert: 22.09.2004 23:35

Beitrag von Skywalker »

Hatte es gestern Abend noch mittels Sentmessage und WindowsCallback hinbekommen.
Aber so wie Du das jetzt gemacht hast, so hatte ich mir das eigentlich vorgestellt. :allright:

Habe sogleich meinen Code geändert.

Supi, vielen Dank
Thomas
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Beitrag von Danilo »

Skywalker hat geschrieben:Hatte es gestern Abend noch mittels Sentmessage und WindowsCallback hinbekommen.
PostMessage schickt halt die Nachricht raus und wartet nicht
darauf ob sie angekommen ist, so wie das SendMessage macht.

SendMessage muß man halt dann verwenden wenn man unmittelbar
einen Rückgabewert braucht.

Ich habe hier nur PostMessage genommen um ein hängen
zu vermeiden. Wenn Programm 1 hängt und Programm 2
dann mit SendMessage sendet, dann wird Programm 2 an
dieser Stelle auch hängenbleiben, solange die Nachricht nicht
bei Programm 1 verarbeitet wurde.

Wenn Programm Empfänger z.B. gerade eine Schleife von 10 Sekunden
ohne Nachrichtenverarbeitung durchläuft, wartet Programm Sender
eben auch diese 10 Sekunden bis SendMessage zurückkehrt.

Also nur eine kleine Vorsichtsmaßnahme... ;)

Ersetze ruhig mal das PostMessage oben durch SendMessage -
geht genauso, solange alles glatt läuft...
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten