Jump to content
Sign in to follow this  

_ProcessGetWindow() for turning a Process ID into a Window Handle

Recommended Posts


Hello Folks,

A little bit of Googlin' and a couple of Forum searches seems to indicate that, for some reason, this function isn't really prevalent, so I wanted to post the code I wrote here.

Anyone care to pick it apart for me? I write AutoIt code in my spare time, so I may have missed a few gotchas that my limited (but successful!) testing couldn't reveal.

_ProcessGetWindow() is designed to be the counterpart of WinGetProcess(), returning HWND's from an input process ID. It can also be told to provide a single, best guess result in the event you don't want to try parsing multiple windows from the output.

In the event that this is a highly redundant post, I apologize, but I did do some searching in advance, and all I came up with was instructions to do just this :blink:


Ha-ha, found a bug when I went to use it. As originally written, it wouldn't return HWND's for processes owning less than two windows ;)

Code updated.

#include <array.au3>

; #FUNCTION# ============================================================================================================================
; Name...........: _ProcessGetWindow
; Description ...: Returns an array of HWNDs containing all windows owned by the process $p_PID, or optionally a single "best guess."
; Syntax.........: _ProcessGetWindow( $p_PID [, $p_ReturnBestGuess = False ])
; Parameters ....: $p_PID - The PID of the process you want the Window for.
;                  $p_ReturnBestGuess - If True, function will return only 1 reult on a best-guess basis.
;                                           The "Best Guess" is the VISIBLE window owned by $p_PID with the longest title.
; Return values .: Success      - Return $_array containing HWND info.
;                                       $_array[0] = Number of results
;                                       $_array[n] = HWND of Window n
;                  Failure      - Returns 0
;                  Error        - Returns -1 and sets @error
;                                            1 - Requires a non-zero number.
;                                            2 - Process does not exist
;                                            3 - WinList() Error
; Author ........: Andrew Bobulsky, contact: RulerOf <at that public email service provided by Google>.
; Remarks .......: The reverse of WinGetProcess()
; =======================================================================================================================================

Func _ProcessGetWindow( $p_PID, $p_ReturnBestGuess = False )

    Local $p_ReturnVal[1] = [0]

    Local $p_WinList = WinList()

    If @error Then ;Some Error handling
        Return -1

    If $p_PID = 0 Then ;Some Error handling
        Return -1

    If ProcessExists($p_PID) = 0 Then ;Some Error handling
        ConsoleWrite("_ProcessGetWindow: Process " & $p_PID & " doesn't exist!" & @CRLF)
        Return -1

    For $i = 1 To $p_WinList[0][0] Step 1
        Local $w_PID = WinGetProcess($p_WinList[$i][1])

       ; ConsoleWrite("Processing Window: " & Chr(34) & $p_WinList[$i][0] & Chr(34) & @CRLF & " with HWND: " & $p_WinList[$i][1] & @CRLF & " and PID: " & $w_PID & @CRLF)

        If $w_PID = $p_PID Then
            ;ConsoleWrite("Match: HWND " & $p_WinList[$i][1] & @CRLF)
            $p_ReturnVal[0] += 1
            _ArrayAdd($p_ReturnVal, $p_WinList[$i][1])

    If $p_ReturnVal[0] > 1 Then

        If $p_ReturnBestGuess Then


                Local $i_State = WinGetState($p_ReturnVal[2])
                Local $i_StateLongest = WinGetState($p_ReturnVal[1])

                    Case BitAND($i_State, 2) And BitAND($i_StateLongest, 2) ;If they're both visible
                        If StringLen(WinGetTitle($p_ReturnVal[2])) > StringLen(WinGetTitle($p_ReturnVal[1])) Then ;And the new one has a longer title
                            _ArrayDelete($p_ReturnVal, 1) ;Delete the "loser"
                            $p_ReturnVal[0] -= 1 ;Decrement counter
                            _ArrayDelete($p_ReturnVal, 2) ;Delete the failed challenger
                            $p_ReturnVal[0] -= 1

                    Case BitAND($i_State, 2) And Not BitAND($i_StateLongest, 2) ;If the new one's visible and the old one isn't
                        _ArrayDelete($p_ReturnVal, 1) ;Delete the old one
                        $p_ReturnVal[0] -= 1 ;Decrement counter

                    Case Else ;Neither window is visible, let's just keep the first one.
                        _ArrayDelete($p_ReturnVal, 2)
                        $p_ReturnVal[0] -= 1


            Until $p_ReturnVal[0] = 1


        Return $p_ReturnVal

    ElseIf $p_ReturnVal[0] = 1 Then
        Return $p_ReturnVal ;Only 1 window.
        Return 0 ;Window not found.
Edited by RulerOf

Share this post

Link to post
Share on other sites

It can be usefull !

Thanks to share Posted Image

AutoIt X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  


Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.