WoodGrain

How do I Click a button with ControlSend or ControlClick with a variable button name?

6 posts in this topic

Hi All,

I'm wanting to learn how to use ControlSend or ControlClick to be able to click a button when prompted, part of the problem is the button text changes.
The button I want to click displays "NO (XX)" where XX is a countdown each second from 90 - image attached.

I've not done Control based code before, so the below code may be wrong lol, but this is what I've got so far:

While 1
   If WinExists("System", "reboot") Then
      Local $hWnd = WinWait("System", "reboot", 5)
      Local $iPID = WinGetProcess($hWnd)
      ControlClick($hWnd, "", "[CLASS:Button; Text: NO"]
      ;ProcessClose($iPID)
   EndIf
   Sleep(10000)
WEnd

Thanks!

Reboot Countdown.jpg

Share this post


Link to post
Share on other sites



What I do when I can't directly send to the specific control is use TAB and ENTER, like this:

WinWait ("[CLASS:#32770]")
$id = WinGetHandle("[CLASS:#32770]")
ControlSend($id, "", "","{TAB 3}")
ControlSend($id, "", "","{ENTER}")


Maybe this work for you, but I'm almost sure there is a better way to do it and the ones with more experience will say.

Regards
Alien.

Share this post


Link to post
Share on other sites
ControlClick($hWnd, "", "[Class:Button;Instance:2]")

Idk what instance the No button really is but since there's only two buttons on there, I'm gonna guess it's 2. If you put the finder tool over it (Autoit Window info tool) you can see what instance it is.

Share this post


Link to post
Share on other sites

Thanks Inuno, that looks like what I need.

I don't have access to the dialogue as it tends to run when I'm away from my computer, but I could write a log file of when it happens that way I'll know if it's working or not.

Share this post


Link to post
Share on other sites

You could use this to log what instance the button is for the dialog, in case it's not actually 2. Go through every button control on the dialog and if it matches the expression, click it.

#include <Array.au3>

Global $hWnd = WinGetHandle("System", "reboot")
Global $aClassList = StringSplit(WinGetClassList($hWnd), @LF, 2)

For $i = UBound($aClassList) - 1 To 0 Step -1
    If ($aClassList[$i] <> "Button") Then _ArrayDelete($aClassList, $i)
Next

For $i = 1 to UBound($aClassList)
    Local $sButtonText = ControlGetText($hWnd, "", "[Class:Button;Instance:" & $i & "]")
    If (StringRegExp($sButtonText, "(?i)No \(\d{1,2}\)")) Then
        ControlClick($hWnd, "", "[Class:Button;Instance:" & $i & "]")
        ExitLoop
    EndIf
Next

 

Share this post


Link to post
Share on other sites

ooh, that's cool, I will definitely use that! Thanks!
I'll spend some time looking through the RegExp code too, looks like exactly what is needed for dealing with a button with a changing value, cheers.

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

  • Similar Content

    • ur
      By ur
      If you observe in below code.
      Func _WinWaitActivate($title,$text,$timeout=$time_out) Logging("Waiting for "&$title&":"&$text) $dHandle = WinWait($title,$text,$timeout) if not ($dHandle = 0) then If Not WinActive($title,$text) Then WinActivate($title,$text) WinWaitActive($title,$text,$timeout) Else Logging("Timeout occured while waiting for the window...") Exit EndIf EndFunc WinActivate("Untitled - Notepad") $p = "Notallowed1!!" Send("{ENTER}{ENTER}{ENTER}{ENTER}"& $p &"{ENTER}create{SPACE}database{SPACE}"& $p &";{ENTER}") In the notepad if you observe, ! is missing in the text got.
       
      Is there way to get that also printed.
    • OtenMoten
      By OtenMoten
      Hello dear community,
       
      definitely I need external help now. I've did all 'ControlClick() - Tutorials' and read a lot of topics about interaction betweend AutoIT and external programs.
      The most of them are about "Clicking a button ...". In my case it's different because I need to click a specific element within the program.
       
      The 'program' what I am talking about is called Mendeley. It's library software for documents administration.
       
      In the attachements in picture '1.jpg' you can see the red marked Help element. 
      In the picture '2.jpg' you see the context menu of the Help element. This is what I'm trying to do with the ControlClick() function.
       
      Following I represent my code which not worked for me:
      #include <MsgBoxConstants.au3> Opt("WinTitleMatchMode", 2) $hWnd = WinGetHandle("Mendeley Desktop", "") MsgBox($MB_SYSTEMMODAL, "handle check", $hWnd) ControlClick($hWnd, "Mendeley Desktop", "Help") The MsgBox tells me the number of the handle of the Mendeley window. It's not 0 so for me it means the window is recognized correctly.
       
      When I'm execute the script the Help element is not clicked.
      Any suggestions for me?
       
      Kind regards
      OtenMoten


    • thoms
      By thoms
      Hello Forum,
      As said in the title, I'm searching a way to disable all tabstops in a GUI. My GUI includes 15 buttons and 3 edit controls.
      My questions:
      - is there a way to disable all tabstops at a time
      - is there a way to list all controls of a GUI and then disable tabstops one by one
      - or should I use the following line after each button creation:
      _WinAPI_SetWindowLong(GUICtrlGetHandle(-1), $GWL_STYLE, BitAND(_WinAPI_GetWindowLong(GUICtrlGetHandle(-1), $GWL_STYLE), BitNOT($WS_TABSTOP))) Thanks in advance for your valuable help!
      Thoms
      Edit: or maybe disable TAB key? I don't remember how to do!
    • rawkhopper
      By rawkhopper
      Hello everyone,
      I have a script that is automating a piece of sluggish software.  I want to automate it with a bit of caution and I am not sure the best way to do it.  ControlSend works great most of the time.  If I have it enter 10 into a text box every once in a while it will enter 1 or 11 and then hit enter.
      To overcome this I use MouseClick to select the text I just entered and then see if it matches the string it was supposed to put in before it hits enter.  This seems to work but what I love about ControlSend is there is less room for human interaction messing it up.  
      Yes I could block input but I prefer not to do that (permissions).
      Is there a better way of doing this?  Any Help would be much appreciated.
      Anyway here is the snippet of the script in question:
      Func KVSend () WinActivate ( "Window", "" ) Local $WindowPos = WinGetPos("Window", "") If $kV < 30 Then WinActivate ( "Window", "" ) ControlClick ("Window", "", 1001) ;Click in Accel Voltage box Sleep (100) ControlSend ("Window", "", 1001, $kV) ; \ kV Sleep (100) MouseMove($WindowPos[0]+130,$WindowPos[1]+75,1) MouseClick($MOUSE_CLICK_LEFT) MouseClick($MOUSE_CLICK_LEFT) Send ("^c") Local $clip = ClipGet () If $clip = $kV Then ControlSend ("Window", "", 1001, "{ENTER}") ;Hit ENTER if value is correct Sleep (100) ControlClick ("Window", "", 1518) ;Lens Clear Else Send ("{BACKSPACE}") KVSend() ; If value is incorrect try again EndIf EndIf  
    • robcull
      By robcull
      Hello all! I have had some issues reading text from different types of windows, occasionally, specifically with controlgettext. 
      **Before I begin, I know there are better ways to do what I attempt in the example below. That's not the point of this post. The point is my issues with controlgettext. 
      I am about to cite an example with an application you may be familiar with called SpeedFan (v4.52). My problem is not specific to speedfan, it is simply the most recent and easily reproducible example I can think of. 
      So, the goal of the script below is to get a string of text containing the current fan RPMs from the highlighted control in the screenshot below (see "speedfan_control_details.png").

      Now, here's a simple script for grabbing the window handle and reading the text from that control: 
      $wintitle = "SpeedFan 4.52" $controlID = "197934" ;will be reformatted as "[ID:######]" $hwnd = wingethandle($wintitle) if @error<>0 then msgbox(0, "WinGetHandle", "FAILURE. @error="&@error) Exit EndIf $text = ControlGetText($hwnd, "", "[ID:"&$controlID&"]") if @error=1 then msgbox(0, "ControlGetText", "FAILURE. @error="&@error) ;failure returns "" and @error=1 Exit EndIf msgbox (0, "ControlGetText", "SUCCESS. @error="&@error &@CRLF& "$text="&$text) ;success returns string and @error=0 You'll see that the ControlGetText operation runs without error, however it does not capture any text from the control. If you explore the other controls in this one window, you'll find mixed results across the board. Neither the temps nor voltages can be read, while the log field and some other elements can be read. Even when you read the text from the whole window, those elements are not included in the visible nor hidden texts. 
       
      I have run into this issue many times in the past- inconsistencies in the ability of autoit to interact with certain controls. What is it which makes this text different than any other readable texts? Is there an alternate method of reading the text in the window/control which could work? Any and all info to help me solve this mystery and satisfy my curiosity would be greatly appreciated. 
      Thanks  -Rob C
      PS: Running Autoit v3.3.14.2 on Win7 Ultimate x64