It is better to close the window via the ClassName, as the title can change. I have extended my include.
Code: Select all
;-TOP
; Comment : Window Functions
; Author : mk-soft
; Version : v1.03.0
; Create : ?
; Update : 20.11.2021
Structure udtListWindows
Name.s
Class.s
Handle.i
Process.i
Childs.i
Level.i
EndStructure
Threaded NewList ListWindows.udtListWindows()
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
;- Windows
Procedure.s GetTitle(Handle)
Protected Name.s
Name.s = Space(1024)
GetWindowText_(Handle, @Name, Len(Name))
ProcedureReturn Left(Name, Len(Name))
EndProcedure
Procedure.s GetClassName(Handle.i)
Protected Class.s
Class.s = Space(1024)
GetClassName_(Handle, @Class, Len(Class))
ProcedureReturn Left(Class, Len(Class))
EndProcedure
Procedure EnumProc(Handle.i, lParam.i)
Protected *tmp.udtListWindows
AddElement(ListWindows())
ListWindows()\Handle = Handle
ListWindows()\Process = 0
GetWindowThreadProcessId_(Handle, @ListWindows()\Process)
ListWindows()\Name = GetTitle(Handle)
ListWindows()\Class = GetClassName(Handle)
If lParam
*tmp = lParam
*tmp\Childs + 1
ListWindows()\Level = *tmp\Level + 1
Else
ListWindows()\Level = 0
EndIf
EnumChildWindows_(Handle, @EnumProc(), @ListWindows())
ProcedureReturn #True
EndProcedure
Procedure GetAllWindows() ; Result = Count of Windows
Protected r1, len
ClearList(ListWindows())
r1 = EnumWindows_(@EnumProc(), 0)
ProcedureReturn ListSize(ListWindows())
EndProcedure
Procedure FindNamedWindow(Name.s) ; Result = Handle
Protected cnt, len
len = Len(Name)
GetAllWindows()
ForEach ListWindows()
If FindString(ListWindows()\Class, "CabinetWClass")
Continue
EndIf
If FindString(ListWindows()\Class, "ShellTabWindowClass")
Continue
EndIf
If Left(ListWindows()\Name, len) = Name
ProcedureReturn ListWindows()\Handle
EndIf
Next
ProcedureReturn 0
EndProcedure
Procedure FindClassWindow(Name.s) ; Result = Handle
Protected cnt, len
len = Len(Name)
GetAllWindows()
ForEach ListWindows()
If FindString(ListWindows()\Class, "CabinetWClass")
Continue
EndIf
If FindString(ListWindows()\Class, "ShellTabWindowClass")
Continue
EndIf
If Left(ListWindows()\Class, len) = Name
ProcedureReturn ListWindows()\Handle
EndIf
Next
ProcedureReturn 0
EndProcedure
Procedure CloseNamedWindow(Name.s) ; Result = Count of Windows
Protected cnt, len
len = Len(Name)
GetAllWindows()
ForEach ListWindows()
If Left(ListWindows()\Name, len) = Name
If FindString(ListWindows()\Class, "CabinetWClass")
Continue
EndIf
If FindString(ListWindows()\Class, "ShellTabWindowClass")
Continue
EndIf
SendMessage_(ListWindows()\Handle, #WM_CLOSE, 0, 0)
cnt + 1
EndIf
Next
ProcedureReturn cnt
EndProcedure
Procedure CloseClassWindow(Name.s) ; Result = Count of Windows
Protected cnt, len
len = Len(Name)
GetAllWindows()
ForEach ListWindows()
If ListWindows()\Class = Name
SendMessage_(ListWindows()\Handle, #WM_CLOSE, 0, 0)
cnt + 1
EndIf
Next
ProcedureReturn cnt
EndProcedure
CompilerCase #PB_OS_MacOS
;- MacOS
Threaded __IsMainScope
__IsMainScope = #True
Procedure GetAllWindows() ; Result = Count of Windows
Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, Pool
If Not __IsMainScope
Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
EndIf
ClearList(ListWindows())
RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
RunningAppsCount = CocoaMessage(0, RunningApps, "count")
i = 0
While i < RunningAppsCount
RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
AddElement(ListWindows())
ListWindows()\Name = AppName
ListWindows()\Handle = RunningApp
i + 1
Wend
If Pool
CocoaMessage(0, Pool, "release")
EndIf
ProcedureReturn i
EndProcedure
Procedure FindNamedWindow(Name.s) ; Result = RunningApp
Protected r1, RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
If Not __IsMainScope
Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
EndIf
RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
RunningAppsCount = CocoaMessage(0, RunningApps, "count")
i = 0
While i < RunningAppsCount
RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
If Name = AppName
r1 = RunningApp
Break
EndIf
i + 1
Wend
If Pool
CocoaMessage(0, Pool, "release")
EndIf
ProcedureReturn r1
EndProcedure
Procedure CloseNamedWindow(Name.s) ; ; Result = Count of Windows
Protected RunningApps.i, RunningAppsCount.i, RunningApp.i, AppName.s, i, cnt, Pool
If Not __IsMainScope
Pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
EndIf
RunningApps = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "runningApplications")
RunningAppsCount = CocoaMessage(0, RunningApps, "count")
i = 0
While i < RunningAppsCount
RunningApp = CocoaMessage(0, RunningApps, "objectAtIndex:", i)
AppName.s = PeekS(CocoaMessage(0, CocoaMessage(0, RunningApp, "localizedName"), "UTF8String"), -1, #PB_UTF8)
If Name = AppName
CocoaMessage(0, RunningApp, "terminate")
cnt + 1
EndIf
i + 1
Wend
If Pool
CocoaMessage(0, Pool, "release")
EndIf
ProcedureReturn cnt
EndProcedure
CompilerCase #PB_OS_Linux
;- Linux
;- Install Paket 'sudo apt-get install wmctrl'
Procedure GetAllWindows()
Protected Compiler, Output.s, Temp.s, pos
ClearList(ListWindows())
Compiler = RunProgram("wmctrl", "-l -x", "", #PB_Program_Open | #PB_Program_Read)
Output = ""
If Compiler
While ProgramRunning(Compiler)
If AvailableProgramOutput(Compiler)
Output = ReadProgramString(Compiler)
AddElement(ListWindows())
temp = "$" + Mid(Output, 3, 8)
ListWindows()\Handle = Val(temp)
temp = Mid(Output, 15)
pos = FindString(temp, " ")
ListWindows()\Class = Left(temp, pos)
temp = Trim(Mid(temp, pos))
pos = FindString(temp, " ")
ListWindows()\Name = Mid(temp, pos + 1)
Else
Delay(10)
EndIf
Wend
CloseProgram(Compiler) ; Close the connection to the program
Else
Output = "Error - Programm konnte nicht gestartet werden!"
EndIf
EndProcedure
Procedure FindNamedWindow(Name.s)
Protected len = Len(Name)
GetAllWindows()
ForEach ListWindows()
If Left(ListWindows()\Name, len) = Name
If Not FindString(ListWindows()\Class, "nautilus", 1, #PB_String_NoCase)
ProcedureReturn ListWindows()\Handle
EndIf
EndIf
Next
ProcedureReturn 0
EndProcedure
Procedure CloseNamedWindow(Name.s) ; Result = #True or #False
RunProgram("wmctrl", "-a " + Name, "")
Delay(100)
RunProgram("wmctrl", "-c " + Name, "")
Delay(100)
ProcedureReturn #True
EndProcedure
CompilerEndSelect
;- Example
CompilerIf #PB_Compiler_IsMainFile
Enumeration Windows
#Main
EndEnumeration
Enumeration Gadgets
EndEnumeration
Enumeration Status
#MainStatusBar
EndEnumeration
Procedure Main()
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 400, 200, "Window" , #PB_Window_SystemMenu)
GetAllWindows()
; ForEach ListWindows()
; If FindString(ListWindows()\Name, "Editor")
; Debug ListWindows()\Name
; Debug ListWindows()\Class
; EndIf
; Next
r1 = FindClassWindow("Notepad")
Debug "Notepad Handle = " + Hex(r1)
Debug "Notepad Title = " + GetTitle(r1)
CloseClassWindow("Notepad")
;Debug GetTitle(r1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
EndIf
EndProcedure : Main()
CompilerEndIf