How to detect when a window created by another process is closed in PureBasic?

Just starting out? Need help? Post your questions and find answers here.
rosebl

How to detect when a window created by another process is closed in PureBasic?

Post by rosebl »

Hi everyone,

I’m working on a small PureBasic tool that monitors a window created by another application (for example, Notepad or a custom app). I can get the window handle using FindWindow_(), but I’m not sure how to detect when that external window is closed.

Is there a reliable way in PureBasic to receive a notification or continuously check the window state without consuming too many resources (like using an infinite loop with Delay())?

Any example code or best practice for this kind of task would be really appreciated.

Thanks!
eJan
Enthusiast
Enthusiast
Posts: 367
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Re: How to detect when a window created by another process is closed in PureBasic?

Post by eJan »

This is how i'm using monitoring app inside thread. I have tested with other methods which uses lot of cpu in small Delay(), this one checks for app every second and it closes itself when the monitoring app is closed. Edit: added timeout to reduce CPU usage "WaitWindowEvent(10)".

Code: Select all

Global Opera.s = "C:\Program Files\Opera GX\opera.exe", Quit

Procedure CheckRunningExe(FileName.s)
  Proc32.PROCESSENTRY32
  Proc32\dwSize = SizeOf(PROCESSENTRY32)

  snap = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  If Snap
    If Process32First_(snap, @Proc32)
      While Process32Next_(snap, @Proc32)
        ImageName$ = PeekS(@Proc32\szExeFile)
        If LCase(ImageName$) = FileName
          ProcedureReturn 1
        EndIf
      Wend
    EndIf
    CloseHandle_(Snap)
  EndIf
EndProcedure

Procedure Run(*Val)
  If CheckRunningExe("opera.exe") = 0
    If FileSize(Opera) > 0
      RunProgram(Opera, "https://eon.tv/guide/1051", "", #PB_Program_Wait)
    Else
      MessageRequester("Opera Hook", "'Opera.exe' was not found.")
    EndIf
  EndIf
  Repeat
    Delay(1000)
    If CheckRunningExe("opera.exe") = 1
      Quit = 0
    Else
      Quit = 1
    EndIf
  Until Quit = 1
EndProcedure

If OpenWindow(0, 0, 0, 222, 200, "ButtonGadgets", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(0, 10, 10, 200, 20, "Standard Button")

  CreateThread(@Run(), 1)

  Repeat
    Select WaitWindowEvent(10)
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
EndIf
Win 11 24H2 Pro
BarryG
Addict
Addict
Posts: 4239
Joined: Thu Apr 18, 2019 8:17 am

Re: How to detect when a window created by another process is closed in PureBasic?

Post by BarryG »

rosebl wrote: Thu Nov 06, 2025 3:09 amI can get the window handle using FindWindow_(), but I’m not sure how to detect when that external window is closed.
Since you've got the handle (hWnd), the IsWindow_(hWnd) command will return 0 if the window doesn't exist (like when closed).

eJan's solution tests if the window's executable is no longer running, as opposed to just a specific window being open.

Side-note: Why is rosebl's profile not showing? It's not clickable and it's trying to load a profile pic endlessly.
CalamityJames
User
User
Posts: 82
Joined: Sat Mar 13, 2010 4:50 pm

Re: How to detect when a window created by another process is closed in PureBasic?

Post by CalamityJames »

This seems to work:

Code: Select all

; https://learn.microsoft.com/en-us/windows/win32/winauto/event-constants
; This program is adapted from https://purebasic.developpez.com/sources/?page=Pg_windows#read_url (Lecture des adresses URL des navigateurs Internet exploreur ou Firefox.)

EnableExplicit
#WINEVENT_OUTOFCONTEXT = 0
#WINEVENT_SKIPOWNPROCESS = $2
#EVENT_OBJECT_DESTROY = $8001

Global NotepadHwnd.i, NotePadThreadId.i, NotePadProcessId.i, EventHook.i, EventId.i

Procedure WinEventFunc(HookHandle.i, hEvent.i, hwnd.i, idObject.i, idChild.i, idEventThread.i, dwmsEventTime.i)
  Protected WindowTitle.s
  Select hEvent
    Case #EVENT_OBJECT_DESTROY
      WindowTitle = Space(256)
      GetWindowText_(hwnd, @WindowTitle, 256)
      Debug "The Window with the title " + Chr(34) + WindowTitle + Chr(34)  + " has closed"    
  EndSelect
EndProcedure

NotepadHwnd =  FindWindow_("Notepad", "Untitled - Notepad")
If NotepadHwnd
  NotePadThreadId = GetWindowThreadProcessId_(NotepadHwnd, @NotePadProcessId)
  If OpenWindow(0, 0, 0, 230, 90, "Event handling example...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    EventHook = SetWinEventHook_(#EVENT_OBJECT_DESTROY, #EVENT_OBJECT_DESTROY, #Null, @WinEventFunc(), NotePadProcessId, NotePadThreadId, #WINEVENT_OUTOFCONTEXT | #WINEVENT_SKIPOWNPROCESS)
    Repeat
      EventId = WaitWindowEvent()    
    Until EventId = #PB_Event_CloseWindow
  EndIf
Else
  Debug "Notepad not found"
EndIf
If EventHook
  UnhookWinEvent_(EventHook) ; true if successful
EndIf
Post Reply