Page 1 of 1

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

Posted: Thu Nov 06, 2025 3:09 am
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!

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

Posted: Thu Nov 13, 2025 5:04 pm
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

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

Posted: Fri Nov 14, 2025 1:00 am
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.

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

Posted: Sat Nov 15, 2025 11:34 am
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