How to check a Window of another Program?

Mac OSX specific forum
Wolfram
Enthusiast
Enthusiast
Posts: 610
Joined: Thu May 30, 2013 4:39 pm

How to check a Window of another Program?

Post by Wolfram »

Is there a way to check if a window of another program is open?
All parameters I have is the App name and the Window name.

Thanks
macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to check a Window of another Program?

Post by wilbert »

Maybe you can use CGWindowListCreate and go over all windows it returns.
Windows (x64)
Raspberry Pi OS (Arm64)
Wolfram
Enthusiast
Enthusiast
Posts: 610
Joined: Thu May 30, 2013 4:39 pm

Re: How to check a Window of another Program?

Post by Wolfram »

wilbert wrote:Maybe you can use CGWindowListCreate and go over all windows it returns.
OK. But how do I create a CFArray as result of the function?

Code: Select all

;Window List Option Constants
#kCGWindowListOptionAll                 = 0
#kCGWindowListOptionOnScreenOnly        = (1 << 0)
#kCGWindowListOptionOnScreenAboveWindow = (1 << 1)
#kCGWindowListOptionOnScreenBelowWindow = (1 << 2)
#kCGWindowListOptionIncludingWindow     = (1 << 3)
#kCGWindowListExcludeDesktopElements    = (1 << 4)


ImportC "/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices"
  CGWindowListCreate(option, relativeToWindow)
  
EndImport


Global Window_0, Button_0


Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
EndProcedure

Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case -1
          ProcedureReturn #False
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
          
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure


OpenWindow_0()

Option.l = #kCGWindowListOptionAll
CFArray = CGWindowListCreate(Option, WindowID(Window_0))


Repeat
  event = WaitWindowEvent()
Until Window_0_Events(event) = #False

End

macOS Catalina 10.15.7
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to check a Window of another Program?

Post by wilbert »

Code: Select all

;Window List Option Constants
#kCGWindowListOptionAll                 = 0
#kCGWindowListOptionOnScreenOnly        = (1 << 0)
#kCGWindowListOptionOnScreenAboveWindow = (1 << 1)
#kCGWindowListOptionOnScreenBelowWindow = (1 << 2)
#kCGWindowListOptionIncludingWindow     = (1 << 3)
#kCGWindowListExcludeDesktopElements    = (1 << 4)

ImportC "/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices"
  CFArrayGetCount(theArray) 
  CFArrayGetValueAtIndex(theArray, idx)
  CFRelease(cf)
  CGRectMakeWithDictionaryRepresentation(dict, *rect)
  CGWindowListCopyWindowInfo(option, relativeToWindow = 0)
EndImport

Procedure.i WindowExists(ApplicationName.s, WindowName.s, Option = #kCGWindowListOptionAll | #kCGWindowListExcludeDesktopElements)
  Protected.i c, d, i, r, s, s_app, s_win, w
  s_app = CocoaMessage(0, 0, "NSString stringWithString:$", @ApplicationName)
  s_win = CocoaMessage(0, 0, "NSString stringWithString:$", @WindowName)
  w = CGWindowListCopyWindowInfo(Option)
  c = CFArrayGetCount(w)
  While i < c
    d = CFArrayGetValueAtIndex(w, i)
    s = CocoaMessage(0, d, "objectForKey:$", @"kCGWindowOwnerName")
    If s And CocoaMessage(0, s, "isEqualToString:", s_app)
      s = CocoaMessage(0, d, "objectForKey:$", @"kCGWindowName")
      If s And CocoaMessage(0, s, "isEqualToString:", s_win)
        r = #True
        Break
      EndIf
    EndIf
    i + 1
  Wend
  CFRelease(w)  
  ProcedureReturn r  
EndProcedure




Global Window_0, Button_0


Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
EndProcedure

Debug WindowExists("PureBasic", "Debug Output - ")

Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case -1
          ProcedureReturn #False
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
          
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure


OpenWindow_0()




Repeat
  event = WaitWindowEvent()
Until Window_0_Events(event) = #False

End
Alternative approach with separate procedure to check window existence

Code: Select all

;Window List Option Constants
#kCGWindowListOptionAll                 = 0
#kCGWindowListOptionOnScreenOnly        = (1 << 0)
#kCGWindowListOptionOnScreenAboveWindow = (1 << 1)
#kCGWindowListOptionOnScreenBelowWindow = (1 << 2)
#kCGWindowListOptionIncludingWindow     = (1 << 3)
#kCGWindowListExcludeDesktopElements    = (1 << 4)

ImportC "/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices"
  CFArrayCreate(allocator, *values, numValues, *callBacks)
  CFArrayGetCount(theArray) 
  CFArrayGetValueAtIndex(theArray, idx)
  CFRelease(cf)
  CGRectMakeWithDictionaryRepresentation(dict, *rect)
  CGWindowListCopyWindowInfo(option, relativeToWindow = 0)
  CGWindowListCreateDescriptionFromArray(windowArray)
EndImport

Procedure.i WindowNumber(ApplicationName.s, WindowName.s, Option = #kCGWindowListOptionAll | #kCGWindowListExcludeDesktopElements)
  Protected.i c, d, i, r, s, s_app, s_win, w
  s_app = CocoaMessage(0, 0, "NSString stringWithString:$", @ApplicationName)
  s_win = CocoaMessage(0, 0, "NSString stringWithString:$", @WindowName)
  w = CGWindowListCopyWindowInfo(Option)
  c = CFArrayGetCount(w)
  While i < c
    d = CFArrayGetValueAtIndex(w, i)
    s = CocoaMessage(0, d, "objectForKey:$", @"kCGWindowOwnerName")
    If s And CocoaMessage(0, s, "isEqualToString:", s_app)
      s = CocoaMessage(0, d, "objectForKey:$", @"kCGWindowName")
      If s And CocoaMessage(0, s, "isEqualToString:", s_win)
        r = CocoaMessage(0, CocoaMessage(0, d, "objectForKey:$", @"kCGWindowNumber"), "integerValue")
        Break
      EndIf
    EndIf
    i + 1
  Wend
  CFRelease(w)  
  ProcedureReturn r  
EndProcedure

Procedure.i WindowExists(WindowNumber.i)
  Protected.i a1, a2, r
  a1 = CFArrayCreate(#Null, @WindowNumber, 1, #Null)
  a2 = CGWindowListCreateDescriptionFromArray(a1)
  r = CFArrayGetCount(a2) 
  CFRelease(a2)
  CFRelease(a1)
  ProcedureReturn r  
EndProcedure



Global Window_0, Button_0


Procedure OpenWindow_0(x = 0, y = 0, width = 450, height = 160)
  Window_0 = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
EndProcedure

WindowNumber = WindowNumber("PureBasic", "Debug Output - ")
Debug WindowExists(WindowNumber)

Procedure Window_0_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
        Case -1
          ProcedureReturn #False
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
          
          
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure


OpenWindow_0()




Repeat
  event = WaitWindowEvent()
Until Window_0_Events(event) = #False

End
If you wish, you can also get the location and size of the window.

Code: Select all

CGRectMakeWithDictionaryRepresentation(CocoaMessage(0, d, "objectForKey:$", @"kCGWindowBounds"), @Bounds.NSRect)
Debug "bounds: (" + Bounds\origin\x + "," + Bounds\origin\y + "," + Bounds\size\width + "," + Bounds\size\height + ")"

See also http://www.purebasic.fr/english/viewtop ... 92#p449292
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply