Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von Thomas »

Hallo,

ich möchte dauerhaft von einem Fenster (Fremdes Programm) den WindowTitle abfragen.
Der erste Teil des "Title"'s ist mir bekannt und daran kann ich's erkennen.
Dafür hab ich auch ein paar coole Code-Schnipsel im Forum hier gefunden z.B.:

Code: Alles auswählen

Procedure EnumWindows(hwnd,lParam)
  Protected Title.s{128}
  
  SendMessage_(hwnd,#WM_GETTEXT,128,@Title) ; <--
  If Len(Title)
    Debug Title
    ;Debug hwnd
  EndIf
  
  ProcedureReturn #True
EndProcedure

EnumWindows_(@EnumWindows(),0)
End
Mit

Code: Alles auswählen

If findstring ...
fange ich mir mein Fenster heraus.

- Aber wie lasse ich das Ganze in Dauerschleife (evtl. im Hintergrund) laufen ohne dass die CPU-Last in die Höhe schießt?

- Wäre es einfacher über den "*.exe"-Namen das Fenster bewusst abzufragen und nicht alle nach einem Schlüsselwort zu durchsuchen?

ich steh mal wieder voll am Schlauch ...
v6.00
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von RSBasic »

Oh der Thomas ist auch mal wieder da, nach 6 Jahren. Wo warst du denn die ganze Zeit? Willkommen zurück. :allright:

Was genau möchtest du denn machen? Warum ist es notwendig, in einer Schleife stets nach einem Fenster mit Hilfe eines Titels zu suchen? Reicht da nicht einmal oder was ist das für ein Fenster? Ist es dein Fenster oder ein fremdes Fenster?
Mit Hilfe des Prozessnamens deiner Executable-Datei bekommst du erstmal nur die PID-Nummer, aber nicht die Handle-Nummer des Fensters. Das Herausfinden der Fenster-Handle-Nummer eines Prozesses mit Hilfe der PID-Nummer ist zwar auch möglich, aber aufwendiger.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von NicTheQuick »

Du musst ja nur einmal EnumWindows_() nutzen. Wenn du das WindowHandle hwnd dann einmal gefunden hast, musst du es ja nicht wieder finden. hwnd ändert sich nicht wieder, solange das Fenster offen bleibt. Und dann kannst du regelmäßig den Namen des Fensters darüber abfragen.
Bild
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von Thomas »

@RSBasic
Dir entgeht auch nix :mrgreen:
Schon 6 Jahre - omg - Der Job hatte mich fest in seinen Fängen :oops: - aber für hier und da mal ein kleines Script war PB immer dabei :allright:

Ich habe eine Fotobox-Software, die für mich als einzige Schnittstelle den Fenstertitel (der immer schön den Status enthält) hat. Den möchte ich nutzen um meine Hardware (LEDs, ...) anzusteuern.

In der Szene ist Autohotkey sehr verbreitet, aber wenn du PB, C, PHP, ... gewohnt bist bekommst bei dem Syntax nen Anfall >_<

Unterm strich geht's darum den Fenstertitel permanent abzugreifen und auf Veränderungen zu reagieren, diese dann über den COM-Port (USB) Daten rauszuschicken. Letzeres funktioniert soweit schon.
v6.00
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von RSBasic »

Ist die Fotobox-Software die ganze Zeit offen? Wenn ja, dann musst du, wie NicTheQuick bereits schrieb, nur einmal die Handle-Nummer dieses Fensters ermitteln und dann kannst du in deiner Eventschleife oder in einem separaten Thread den Fenstertitel auslesen. Im Thread kannst du in der Schleife ein Delay(500) oder Delay(1000) setzen. Dann verbraucht es keine CPU-Last.
Thomas' Signatur hat geschrieben:v5.11
Es gibt inzwischen 5.62 bzw. 5.70, falls du noch nicht geupdatet hast.
Und deine Website existiert auch schon lange nicht mehr.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von Thomas »

Ja, "normal" ist die Software andauernd geöffnet, aber in irgendeiner Form abzufragen obs den Handle noch gibt, ist mit Sicherheit kein Schaden (um dann gegebenfalls den Handle neu ermitteln zu können)

Ja, an das Delay habe ich auch schon gedacht, obwohl ich da eher unter Delay(100) bleiben sollte.
Muss ich mal antesten. Könnte aber interessant werden Threads hab ich bisher immer gemieden :praise:

Windows-API war ja für mich damals schon ein spanisches Dorf:

Code: Alles auswählen

EnumWindows_(@EnumWindows(),0)
Wie muss ich diese Codezeile verstehen, warum wird die Funktion öfter aufgerufen und keine Parameter übergeben?

Ja, die Website ist schon draußen, wenn ich meinen Zugang noch finde, update ich mal ;)

@RSBasic, @NicTheQuick, echt cool, dass ihr alle noch hier seid, gibt's @Stargate auch noch? :D
v6.00
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von RSBasic »

Thomas hat geschrieben:Ja, "normal" ist die Software andauernd geöffnet, aber in irgendeiner Form abzufragen obs den Handle noch gibt
Dafür gibt es IsWindow_(), um zu prüfen, ob die Handle-Nummer des Fensters noch gültig ist. Du bekommst 1 zurück, wenn das Fenster noch existiert, ansonsten 0.
Thomas hat geschrieben:warum wird die Funktion öfter aufgerufen und keine Parameter übergeben?
Es ist, wie der Funktionsname lautet, eine Enumerationsfunktion. D.h. die Funkton wird von Windows selbst so lange aufgerufen, bis alle Vorgänge abgeschlossen wurden. In dem Fall alle Fenster, die gefunden wurden. Du kannst aber mit ProcedureReturn #False den Vorgang abbrechen, nachdem dein Fenster gefunden wurde.
Ansonsten gibt es FindWindow_() für ein direktes Finden.
Thomas hat geschrieben:gibt's @Stargate auch noch? :D
Ja, den gibt es auch noch und ist noch aktiv.
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
Thomas
Beiträge: 893
Registriert: 06.07.2006 19:24
Wohnort: Regensburg
Kontaktdaten:

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von Thomas »

sooo, vielen Dank euch Beiden, ich bin zu meinem Ergebnis gekommen.

Damit auch noch andere davon profitieren können:

Code: Alles auswählen

Global window_title$ = ""
Global window_hWnd = 0
Global window$ = "Fenster das den Titel ändert"

Procedure EnumWindows(hWnd,Visibility=#True) ;Prozedur, die die Handles der Fenster erhält
  Static title.s{1024},class.s{1024},PID.l=0

    GetWindowText_(hWnd,@title,1024) ;Fenstertitel auslesen
    GetClassName_(hWnd,@class,1024)  ;Fensterklasse auslesen
    GetWindowThreadProcessId_(hWnd,@PID) ;PID des zugehörigen Prozesses auslesen
    
    
    If  FindString(title, window$)
      
      Debug "[Title]= "+title+" [hWnd]= "+Str(hWnd)+" [ClassName]= "+class+" [PID]= "+Str(PID) ;Werte ausgeben
      
      window_title$ = title
      window_hWnd = hWnd
      ProcedureReturn #False
            
    EndIf
    
  ProcedureReturn #True
EndProcedure

Procedure GetNewTitle(Parameter)
  Static title.s{1024}
  
  Repeat
    If IsWindow_(window_hWnd)
      GetWindowText_(window_hWnd,@title,1024)
      If Not window_title$ = title
        window_title$ = title
        Debug "Titel: "+window_title$
      EndIf
    Else
      Debug "Programm scheinbar geschlossen"
      EnumWindows_(@EnumWindows(),#True)
      Delay(1000)
    EndIf
    Delay(100)
  ForEver

EndProcedure




If OpenWindow(0, 100, 200, 850, 200, "Fenster", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)

  EnumWindows_(@EnumWindows(),#True)
  CreateThread(@GetNewTitle(), 0)


  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget

      Select EventGadget()
        Case 0
          
      EndSelect

    EndIf

  Until Event = #PB_Event_CloseWindow

EndIf

End
v6.00
Benutzeravatar
TheCube
Beiträge: 150
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: Fenster-Titel dauerhaft abfragen ohne Mega-CPU-Last

Beitrag von TheCube »

Danke für den Codeschnipsel ... wird in meiner Sammlung sicher irgendwo mal nützlich sein.
Je nachdem leg ich es dann nicht-casesenitiv aus, also findet Fenster "CalcPi" und "calcpi" etc. ...

P.S: Auch herunter auf Delay(1) (von Delay(100)) hat man noch keine merkliche CPU-Last, selbst auf einem alten Atom-PC.
Trotzdem natürlich besser nur so oft abzufragen wie nötig.
Antworten