WinGetHandle()

Everything else that doesn't fall into one of the other PB categories.
AZJIO
Addict
Addict
Posts: 2171
Joined: Sun May 14, 2017 1:48 am

WinGetHandle()

Post by AZJIO »

WinGetHandle is a very frequently used function in AutoIt3 and I need it in some programs.
But the function in AutoIt3 also accepts window sizes and regular expressions to search for the title as search criteria. I did not complicate this with additional parameters, since this is rarely used.

Code: Select all

EnableExplicit

Structure ResStr
	s.s
	r.s
	slen.i
	rlen.i
	hwnd.l
	match.l
	type.l
	instance.l
EndStructure

Enumeration
	#Title
	#Class
EndEnumeration

; Finding Window
Procedure.l enumChildren(hwnd.l, *s.ResStr)
	Static n.l = 0
	If hwnd
		Select *s\type
			Case 0
				GetWindowText_(hwnd, @*s\r, *s\rlen)
			Case 1
				GetClassName_(hwnd, @*s\r, *s\rlen)
		EndSelect
		Select *s\match
			Case 0
				If *s\r = *s\s
					n + 1
					If n = *s\instance
						n = 0
						Debug *s\r
						*s\hwnd = hwnd
						ProcedureReturn 0
					EndIf
				EndIf
			Case 1
				If Left(*s\r, *s\slen) = *s\s
					n + 1
					If n = *s\instance
						n = 0
						Debug *s\r
						*s\hwnd = hwnd
						ProcedureReturn 0
					EndIf
				EndIf
			Case 2
				If FindString(*s\r, *s\s, 1, #PB_String_NoCase)
					n + 1
					If n = *s\instance
						n = 0
						Debug *s\r
						*s\hwnd = hwnd
						ProcedureReturn 0
					EndIf
				EndIf
		EndSelect
		ProcedureReturn 1
	EndIf
	n = 0
	ProcedureReturn 0
EndProcedure

; type
; 	0 - Title
; 	1 - Class
; match
; 	0 - exact match
; 	1 - match from start
; 	2 - the word occurs in the title
Procedure.l WinGetHandle(hwnd, text.s, instance = 1, type = 0, match = 0)
	Protected s.ResStr
	s\rlen = 256
	s\r = Space(s\rlen)
	s\s = text
	s\slen = Len(text)
	s\match = match
	s\type = type
	s\instance = instance
	EnumChildWindows_(hwnd, @enumChildren(), @s)
	ProcedureReturn s\hwnd
EndProcedure

Define hwnd
; Debug WinGetHandle(0, "PureBasic", 1, #Title)
; Debug WinGetHandle(0, "LTS", 1, #Title, 2)

; hwnd = WinGetHandle(0, "WindowClass_2", 1, #Class, 0) ; PureBasic
; Debug Hex(hwnd)
; If hwnd
; 	hwnd = WinGetHandle(hwnd, "Scintilla", 1, #Class, 0)  ; PureBasic -> Scintilla
; 	Debug Hex(hwnd)
; EndIf

hwnd = WinGetHandle(0, "Properties", 1, #Title, 1) ; Properties
; hwnd = WinGetHandle(0, "#32770", 1, #Class, 0) ; #32770
Debug Hex(hwnd)
If hwnd
	hwnd = WinGetHandle(hwnd, "Button", 4, #Class, 0)  ; Properties -> Others
	Debug Hex(hwnd)
EndIf
; SendMessage_(hwnd, #BM_CLICK, 0, 0)

; Add a size check
; Define win.RECT
; GetWindowRect_(hwnd, win)
; If class = "#32770" And (win\bottom - win\top) = 111 And (win\right - win\left) = 333
; EndIf
Last edited by AZJIO on Wed Feb 22, 2023 10:31 pm, edited 1 time in total.
User avatar
Caronte3D
Addict
Addict
Posts: 1361
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: WinGetHandle()

Post by Caronte3D »

Very useful, thanks! :wink:
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: WinGetHandle()

Post by ChrisR »

Thanks for sharing, it can be useful
The instance is missing in the example:

Code: Select all

Debug WinGetHandle(0, "PureBasic", 1, #Title, 1)
Debug WinGetHandle(0, "LTS", 1, #Title, 2)
Up to you, I would have put the type before the instance

Code: Select all

Procedure.l WinGetHandle(hwnd, text.s, type = #Title, instance = 1, match = 0)
Randy Walker
Addict
Addict
Posts: 1046
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: WinGetHandle()

Post by Randy Walker »

AZJIO wrote: Wed Feb 22, 2023 4:50 pm WinGetHandle is a very frequently used function in AutoIt3 and I need it in some programs.
But the function in AutoIt3 also accepts window sizes and regular expressions to search for the title as search criteria. I did not complicate this with additional parameters, since this is rarely used.
I don't know about all that window sizes and regular expressions stuff, but just searching for an app based on it's title does not require all that code. I use this in my apps to prevent more than one instance. using "notepad" here just to illustrate, so test with and without a blank Notepad running. Change AppName value to suit your needs:

Code: Select all

Global hWin.i, AppName.s

AppName.s = "Notepad"
Procedure.l EnumWindows(WindowHandle.l, Parameter.l) 
  
 Title$ = Space(200) 
 GetWindowText_(WindowHandle, @Title$, 200) 
 
 If FindString(Title$, AppName, 1, #PB_String_NoCase ) <> 0
   HwndDebug = WindowHandle
   hWin.i = WindowHandle
  ProcedureReturn #False
 Else 
  ProcedureReturn #True
 EndIf 
 
EndProcedure
EnumWindows_(@EnumWindows(), 0)
If hWin.i
  Debug "HERE IS YOUR Window Handle: "+Str(hwin.i)
  SetForegroundWindow_(hWin.i) ; and bring current instance into foreground.
  ShowWindow_(hWin.i, #SW_RESTORE)
  Delay(250)
  End ; Quit from this duplicate instance.
Else 
  Debug "NO, there is NO "+AppName
EndIf 
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
idle
Always Here
Always Here
Posts: 5882
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: WinGetHandle()

Post by idle »

to get a window by name though it will only get the 1st instance

Code: Select all

Procedure FindWindowByName(name.s) 
  
  Protected hwnd,TitleSize.l,Title.s  
  
  hwnd = GetWindow_(GetDesktopWindow_(), #GW_CHILD)
  While hwnd
	TitleSize.l = GetWindowTextLength_(hwnd) + 2
	Title = Space(TitleSize)
	GetWindowText_(hwnd, Title, TitleSize)
	If FindString(LCase(Title), LCase(name))
		If hwnd <> WindowID(mhwnd) 
		   ProcedureReturn hwnd
		EndIf   
	EndIf
	hwnd = GetWindow_(hwnd, #GW_HWNDNEXT)
Wend

EndProcedure   
AZJIO
Addict
Addict
Posts: 2171
Joined: Sun May 14, 2017 1:48 am

Re: WinGetHandle()

Post by AZJIO »

Randy Walker wrote: Tue Jun 03, 2025 12:49 am I don't know about all that window sizes and regular expressions stuff, but just searching for an app based on it's title does not require all that code.
Simplified version
EnumWindows
EnumChildWindows
Post Reply