Jump to content
Sign in to follow this  
amanda089

Window Class & Instance help

Recommended Posts

amanda089

I'm trying to automate some things utilizing both firefox and chrome and a flash website. I would like to know the best and fastest way to correctly identify the flash control (and instance) for both browsers.

Here is the code that I use now. I had to remove the instance checking because it wasn't identifying anything.

Called in every loop of the main program:

Func CheckHWnd($HWnd, $Call)
Local $size = WinGetPos($HWnd)
Select
  Case (Not IsArray($size) Or Not IsDeclared($size[3])) Or $HWnd = ""
   Call($Call)
   Return
  Case Else
   If ($size[2] <> 1024 Or $size[3] <> 820) Then Call($Call)
EndSelect
EndFunc   ;==>CheckHWnd

The above function will call either of these functions:

Func GetFireFox()
Local $classlist = StringSplit(WinGetClassList($Title_Firefox, ""), @LF, 2)
Local $PluginWindows = _ArrayFindAll($classlist, "GeckoPluginWindow")
For $flash = 0 To (UBound($PluginWindows) - 1)
  Local $str = "[CLASS:GeckoPluginWindow]"
  Local $FFC = ControlGetHandle($Title_Firefox, "", $str)
  Local $posi = WinGetPos($FFC, "")
  If ($posi[2] = 1024) Then
   $FF_Pos = $posi
   $FireFoxCtrl = $FFC
   Return $FFC
  EndIf
Next
Return $FireFoxCtrl
EndFunc   ;==>GetFireFox
 
Func GetChrome()
Local $classlist = StringSplit(WinGetClassList($Title_Chrome, ""), @LF, 2)
Local $PluginWindows = _ArrayFindAll($classlist, "NativeWindowClass")
For $flash = 0 To (UBound($PluginWindows) - 1)
  Local $str = "[CLASS:NativeWindowClass]"
  Local $CHC = ControlGetHandle($Title_Chrome, "", $str)
  Local $posi = WinGetPos($CHC, "")
  If ($posi[2] = 1024) Then
   $CH_Pos = $posi
   $ChromeCtrl = $CHC
   Return $CHC
  EndIf
Next
Return $ChromeCtrl
EndFunc   ;==>GetChrome

I use the returned HWnd pointer in both direct drawing and in these functions:

Func FirefoxClick($x, $y)
ControlClick("", "", $FireFoxCtrl, "primary", 1, $x, $y)
EndFunc   ;==>FirefoxClick

Func ChromeClick($x, $y)
ControlClick("", "", $ChromeCtrl, "primary", 1, $x, $y)
EndFunc   ;==>ChromeClick

The direct drawing (a cross and text, found in these forums) and the clicking work correctly, when the pointer is valid. But, say, when the window in chrome is refreshed and the flash plugin instance is incremented. It doesn't return the correct pointer at all.

If you know of any ways to optimize this code, or correctly identify the instance number, I would much appreciate it.

Share this post


Link to post
Share on other sites
kaotkbliss

What does controlgethandle return before and after the refresh? How about for each multiple refresh? Maybe there's a pattern you can use to predict what it will be when it refreshes?


010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Share this post


Link to post
Share on other sites
amanda089

It depends on the instance and if there is another instance in a different tab. That is the confusing part. the instance number only changes with additional websites that use plugins such as java or flash.

You can test the code out yourself by opening a flash website in both browsers, etc.

Edited by amanda089

Share this post


Link to post
Share on other sites
kaotkbliss

Just thinking out loud..

Maybe if you kept track of each PID in an array as more instances are opened, you can get the correct control for each PID and add that to the array (multi-demension array)

then you could have your code see which instance it's looking at and "look-up" the control from the array? Maybe?


010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Share this post


Link to post
Share on other sites
amanda089

Grr, I hate using arrays or more variables than I need to. Particularly since I'm already using 4 byte ptr's and having to check if they are still valid every loop

Share this post


Link to post
Share on other sites
kaotkbliss

That's the only thing I can think up right now :graduated:

I haven't really done much yet in the way of automating flash and web browsers so I'm a bit limited


010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

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  

  • Similar Content

    • RHolmes
      By RHolmes
      I wrote a script a few months ago that was working at the time. When I tried it today it wouldn't retrieve any controls.  The application successfully launches, but I cannot figure out how to retrieve the control from the window that is launched. I'm on a windows 10 machine using AutoIt v3.3.14.2. The only thing I can think of that has changed is windows updates? Code is below, any help is greatly appreciated.    ; Notes: ; HandleError( handleToCheck, MsgToLogOnFailure, terminateAutoItOnFail ) : function that simply checks the handle and quits AutoIt if not present ; all of this works well FileChangeDir( $CLIENT_APPLICATION_DIR ); Run( "Client.exe" ) Local $hClient = WinWaitActive( $CLIENT_TITLE, "", 10 ) $terminateOnFail = 1 HandleError( $hClient, "LaunchClient::Error: Failed to launch client. Either timed-out or failed.", $terminateOnFail ) LogToFile( "Client launched, waiting for system to ready." ) Sleep( 5000 ) ; this part does not work ; $SYSTEM_INDICATOR is a global variable. I have tried these values: "SystemIndicatorWindow" (Text), "Qt5QWindowIcon101" (ClassNN), and ; "[CLASS:Qt5QWindowIcon; INSTANCE:101]" Local $hStatusIndicator = ControlGetHandle( $hClient, "", $SYSTEM_INDICATOR ) HandleError( $hStatusIndicator, "CheckStatus::Error: couldn't retrieve control: " & $SYSTEM_INDICATOR, $terminateOnFail ) This is what the spy reveals: 

       
      Edit: I just tried this code and it works for notepad++.
      FileChangeDir( "C:\Program Files\Notepad++\" ); Run( "notepad++.exe" ) Local $hNotePad = WinWaitActive( "new 1 - Notepad++", "", 10 ) If $hNotePad = 0 Or $hNotePad = -1 Then MsgBox( $MB_SYSTEMMODAL, "Error", "Error getting app handle." ) EndIf Sleep( 1000 ) Local $hNewFileBtn = ControlGetHandle( $hNotePad, "", "[CLASS:ToolbarWindow32; INSTANCE:1]" ) If $hNewFileBtn = 0 Or $hNewFileBtn = -1 Then MsgBox( $MB_SYSTEMMODAL, "Error", "Error getting button handle." ) EndIf MsgBox( $MB_SYSTEMMODAL, "Success", "Success." )  
    • rcmaehl
      By rcmaehl
      A UDF with Extended Functions for Window Management
       
      Notes:
      Fixes WinGetClassList's barbaric returning of a @LF separated string instead of an array.
       
      Potential Uses:
      Automating applications that change their controls' handles/classes on each launch (e.g. half of Cisco's programs)
       
      Functions:
      _WinGetClassList
      _WinGetClassNNList
      _WindowGetHandleList
      _WindowGetHandleListFromPos
       
      Download: 
      WindowEx.zip  (v0.4)
       
      Changelog:
      10/04/2016 (v0.4): _WinGetClassNNList Fixed : Not Returning an Index when using $2D_ARRAY _WinGetClassNNList Fixed : Not Properly returning $aArray[x][1] on Classes with instances > 9 when using $2D_ARRAY 10/03/2016 (v0.3): _WinGetClassList Added : Exactly the same as WinGetClassList but returns a more civilized Array _WinGetClassNNList Added : Returns Classes and their instances in either a 1D or 2D array depending on Flags _WindowGetHandleList Renamed: _WinGetHandleList SCRIPT BREAKING! _WindowGetHandleListFromPos Renamed: _WinGetHandleListFromPos SCRIPT BREAKING! 10/01/2016 (v0.2): WindowsExConstants.au3 Added : Flags in _WindowGetHandleListFromPos _WindowGetHandleListFromPos Removed: ConsoleWrite left in during debug _WindowGetHandleListFromPos Added : Flag for if part of a Control is at $X, $Y return it as well. 10/01/2016 (v0.1): _WindowGetHandleList Added : Retrieves the handles of classes from a window. _WindowGetHandleListFromPos Added : Retrieves the handles of classes at a specific position from a window. Known and Reported Bugs:
      None reported To Do:
      To Be Decided. Opinions welcome! Upcoming Changes:
      To Be Decided.
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good morning everyone

      I was playing a little bit with "Screen Capture" UDF, and I was trying to make a "Window" capture, but, since I made a GUI which through I fire the event "Capture", my GUI is captured as well, and I don't want to
      This is the line of code that makes the capture:
       
      _ScreenCapture_CaptureWnd($strScreenCaptureFileName, $objActiveWindow, 0, 0, -1, -1, False) And these are the lines of code which select the "active" window:
       
      Local $objCurrentWindow = 9999 If _IsPressed("01") Then $objCurrentWindow = WinGetHandle("[ACTIVE]") If $objCurrentWindow <> $objMyGUI Then $objActiveWindow = $objCurrentWindow EndIf EndIf Sorry If I made stupid mistakes
      Thanks in advance.

      Francesco
    • guinness
      By guinness
      #include <Array.au3> #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> ; Proof of concept for using the control id as an index item for an array. I created back on 8th April 2013. Example() Func Example() ; Create the GUI. Local $iHeight = 400, $iWidth = 400 Local $hGUI = GUICreate('', $iWidth, $iHeight) GUISetState(@SW_SHOW, $hGUI) ; Declare variables to be used throughout the example. Local Const $BUTTON_ROWS_COLUMNS = 8 Local Enum $eCTRL_HWND, $eCTRL_VALUE, $eCTRL_MAX Local $aMsg[1][$eCTRL_MAX], _ $iButtonHeight = $iHeight / $BUTTON_ROWS_COLUMNS, _ $iButtonWidth = $iWidth / $BUTTON_ROWS_COLUMNS, _ $iControlID = 0 For $i = 0 To $BUTTON_ROWS_COLUMNS - 1 For $j = 0 To $BUTTON_ROWS_COLUMNS - 1 $iControlID = GUICtrlCreateButton($i & ',' & $j, $i * $iButtonWidth, $j * $iButtonHeight, $iButtonWidth, $iButtonHeight, $BS_CENTER) ; Increase the size of the array if the control id is greater than or equal to the total size of the array. If $iControlID >= UBound($aMsg) Then ReDim $aMsg[Ceiling($iControlID * 1.3)][$eCTRL_MAX] EndIf ; Add to the array. $aMsg[$iControlID][$eCTRL_HWND] = GUICtrlGetHandle($iControlID) $aMsg[$iControlID][$eCTRL_VALUE] = 'Sample string for the control id: ' & $iControlID Next Next ; Clear empty items after the last created control id. ReDim $aMsg[$iControlID + 1][$eCTRL_MAX] ; Display the array created. _ArrayDisplay($aMsg) Local $iMsg = 0 While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aMsg[$eCTRL_HWND][$eCTRL_HWND] To UBound($aMsg) ; If $iMsg is greater than 0 and between the 0th index of $aMsg and the last item then display in the console. If $iMsg > 0 Then ConsoleWrite('Control Hwnd: ' & $aMsg[$iMsg][$eCTRL_HWND] & ', ' & $aMsg[$iMsg][$eCTRL_VALUE] & @CRLF) EndIf EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example  
×