Sign in to follow this  
Followers 0
wfaulk

ControlGetPos works matching window Title, but not Class

19 posts in this topic

#1 ·  Posted (edited)

I have a piece of code that waits for a window to become active, then manipulates a particular control:

$swwin = WinWaitActive("Window Title")
$cpos = ControlGetPos($swwin, "", "[ID:177]")

If I match the window based on the title text, as shown above, it works fine. However, the window title is not always the same, so I wanted to move to matching the window class instead:

$swwin = WinWaitActive("[CLASS:Afx:400000:0]")
$cpos = ControlGetPos($swwin, "", "[ID:177]")

This does not work, but not in the way that you're expecting. The WinWaitActive() call matches and returns, but when I try to reference $cpos[0] later in the code, it claims that it's not an array variable, and if I check @error immediately after the ControlGetPos() call, it's set to 1.

Why would it work correctly with the window title, but not the window class? What debugging steps can I take to see what's going on?

Edited by wfaulk

Share this post


Link to post
Share on other sites



Check the return value of $swwin using both the title and the class and see if they match.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

I will try that as soon as my application administrator unbreaks the application I'm trying to automate. :/

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

And now it works. I wonder if it's something my application admin changed.

Regardless, nevermind.

Edited by wfaulk

Share this post


Link to post
Share on other sites

Grr. Now it's back to failing again, and I can confirm that the window handles returned by the two calls to WinWaitActive() are not the same.

Share this post


Link to post
Share on other sites

Double check that the class for the window is actually CLASS:Afx:400000:0 and you're not getting a control handle instead.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

I'm positive that that's the Window Class, at least as according to AutoIt v3 Window Info.

I'm also running WinFlash() against the two handles. The one selected by title shows the correct window. The one selected by class doesn't show any window, though it waits the appropriate amount of time before continuing as if it were flashing the taskbar.

Also, GetWinTitle() and GetWinText() are returning blank strings for the class-selected window handle.

As it turns out, some of the other open windows from the same program have similar classes: Afx:400000:0:0:0:24300c57 and Afx:400000:0:0:0:b6dd166f. I don't know if that might be relevant or not.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

I do it somewhat differently. If the window contains a unique title, I just nab the handle(s) early in the program. Then I just deal with handles only for the remainder of the script. It's how I had to work my AS400 Emulator automation script several years ago. I had up to 6 windows on screen with the same class, but each one had a different title.

$hwnd_EmuA = WinGetHandle("A - [80x24]", "")
$hwnd_EmuB = WinGetHandle("B - [80x24]", "")
$hwnd_EmuC = WinGetHandle("C - [80x24]", "")

{stuff goes here}

WinActivate($hwnd_EmuA)
If Not WinWaitActive($hwnd_EmuA, "", 30) Then
   ConsoleWrite("Error:  Timeout waiting for Emulator A to activate." & @CRLF)
   Exit(101)
EndIf
Edited by Blue_Drache

Lofting the cyberwinds on teknoleather wings, I am...The Blue Drache

Share this post


Link to post
Share on other sites

It is neither unique nor consistent.

Share this post


Link to post
Share on other sites

Looks like its an "Microsoft Foundation Class (MFC)" application. When you search microsoft web site for "afx" you'll find something like this.

I'm not familiar with this kind of programming but when you search the forum for "MFC" you'll find some other users having problems.

Just my 0,02$


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

What about screen scraping the window? Is there some unique TEXT in the window that you can check against?


Lofting the cyberwinds on teknoleather wings, I am...The Blue Drache

Share this post


Link to post
Share on other sites

@water:

It looks like that MSDN article seems to indicate that this is a sloppily programmed MFC application, which seems to fit with my experience. I'll bet that there is a hidden window somewhere that has the same class. I'm going to have to find some other way to uniquely identify these windows. Perhaps there is some unique text in the window that I can match against, as Blue_Drache suggests.

Share this post


Link to post
Share on other sites

@wfaulk: Your program: Posted Image


Lofting the cyberwinds on teknoleather wings, I am...The Blue Drache

Share this post


Link to post
Share on other sites

I ran WinList() against that class and found that there are two invisible windows with that class running all the time. I wonder if WinWaitActive() waits for a window matching that class to become active, but then doesn't necessarily return that active window.

I'm going to try using WinWaitActive() followed by a WinList() and WinGetState() to find the active one. If that turns out to be the problem, I'd consider that a bug.

Share this post


Link to post
Share on other sites

This seems to work, but I'll have to live with it for a while to be more sure.

$swwin = 0
WinWaitActive("[CLASS:Afx:400000:0]")
$winlist = WinList("[CLASS:Afx:400000:0]")
For $i = 1 To $winlist[0][0]
  If BitAnd(WinGetState($winlist[$i][1]), 8) Then
   $swwin = $winlist[$i][1]
  EndIf
Next
If $swwin = 0 Then
  MsgBox(1, "Error", "Window active but not active?!?")
  Sleep(5000)
  ContinueLoop
EndIf

Share this post


Link to post
Share on other sites

FWIW, I created a bug report:

http://www.autoitscript.com/trac/autoit/ticket/2181

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