Sign in to follow this  
Followers 0

Window name vs PID vs handle ... can someone explain?

8 posts in this topic

Posted

I'm working on a simple script to start (run) an external application and size/position its window. The help file has an example for notepad, which is where I started ... by first adapting it to Wordpad. But I quickly get to the point that I can't be certain of the window's name ... and it could be similar to other open windows. So I started exploring PID and handle methods.

The PID didn't work, even in my simple test file:

#include <Process.au3>
Run("C:\Program Files\Windows NT\Accessories\wordpad.exe")
WinWaitActive("Document", "")
Local $pid = WinGetProcess("Document", "")
Local $name = _ProcessGetName($pid)
MsgBox(0, "Wordpad - ", $pid & "  " & $name)
;WinMove($name, "", 600, 200, 400, 600)  ; <<<< this didn't work
WinMove("Document", "", 600, 200, 400, 600) ;   only this works
MsgBox(48, "Requested Action", "Is this it?")
Exit

Can someone recommend how an AutoIt script can best get the absolute identity of an external window? ... in this case for moving it. And maybe even mention how [Class:NotePad] fits into all this?

Thanks in advance for any help.

Share this post


Link to post
Share on other sites



Posted

wingethandle()

Share this post


Link to post
Share on other sites

Posted

Hi qwert,

I did some searching and found a good way to get the window handle from the PID using

Using _WinAPI_EnumProcessWindows() you can get the window handle from the PID to use in other functions like WinMove().

Something like this:

#include <WinAPIEx.au3>

$pid = Run("C:\Program Files\Windows NT\Accessories\wordpad.exe")
WinWaitActive("Document", "")
$Data = _WinAPI_EnumProcessWindows($pid)
If @error Then
    MsgBox(0, 'ERROR', 'Failed to find window to PID: ' & $pid)
Else
    $hWnd = $Data[1][0]
    MsgBox(0, "Wordpad - ", $pid)
    WinMove($hWnd, "", 600, 200, 400, 600)
    MsgBox(48, "Requested Action", "Is this it?")
EndIf

Please see the UDF post for proper credit and to download it.

Share this post


Link to post
Share on other sites

Posted

Of what? Title? ... Class? ... Last? And in my example, what if there are already windows active that start with "Document ..."?

Again, I'm just trying to use a safe method so I'm not vulnerable to some user's runtime environment tripping up the script.

Share this post


Link to post
Share on other sites

Posted

@danwilli: That sounds like a good approach ... adds the element of certainty. I'll give it a try with my actual application.

Thanks.

Share this post


Link to post
Share on other sites

Posted

Oops, meant to replace the WinWaitActive() with ProcessWait(). Now you are simply running an executable (Run), waiting for the executable to start (ProcessWait), finding the window handle (_WinAPI_EnumProcessWindows) and then performing any actions you want with the window handle (WinMove).

#include <WinAPIEx.au3>

$pid = Run("C:Program FilesWindows NTAccessorieswordpad.exe")
ProcessWait($pid)
$Data = _WinAPI_EnumProcessWindows($pid)
If @error Then
    MsgBox(0, 'ERROR', 'Failed to find window to PID: ' & $pid)
Else
    $hWnd = $Data[1][0]
    MsgBox(0, "Wordpad - ", $pid)
    WinMove($hWnd, "", 600, 200, 400, 600)
    MsgBox(48, "Requested Action", "Is this it?")
EndIf

Share this post


Link to post
Share on other sites

Posted

@danwilli:

Your suggestion worked ... with one caveat: The window for the application took a second or so to actually open (after the process starts) ... so the Enum statement was executing too soon and returning the $PID instead of the window handle.

For now, I've put in a simple pause/delay and everything works. However, I'd like to lock things down a little tighter in the eventual runtime version.

Any suggestions for determining that the window has been created, in order to ask what its handle is? Or is this a Catch 22?

Share this post


Link to post
Share on other sites

Posted

I had a similar problem with Internet Explorer. I needed to watch for a particular instance if IE to be closed and when it was closed, relaunch to a particular URL. Look up WinWaitActive() and WinGetHandle(). Launch Wordpad with Run() and then use WinWaitActive() for your instance to appear. Use $Handle = WinGetHandle() to grab the handle of that particular instance and assign it to a variable. Then you can wait for that variable to no longer exist or simply sleep while it does exist, whatever.

This is what I wound up with for IE.

AutoItSetOption("TrayIconHide", 1)
While 1 = 1
Run(@ProgramFilesDir & "Internet ExplorerIEXPLORE.EXE http://connection.mypage.com/departments/Ops/tewp", "", @SW_MAXIMIZE)
WinWaitActive("http://connection.mypage.com") ; Hard coded page title here
$Handle = WinGetHandle("http://connection.mypage.com") ; And here
While WinExists($Handle)
  Sleep(5000)
WEnd
WEnd

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  
Followers 0