How can I use my handle number? - autoit

I have 2 windows that have the same title. So, I have to detect them by handle. They use very long time to begin from the beginning of my code, too. So I have to begin them before, then debug the middle of code by detect them by their handle. The codes are difference between them, so I must specify the handle by my hand. However, thank you very much.
I got my own window's handle number by Au3Info application.
But It didn't work when I use like this:
;run Au3Info.exe to get calc.exe window's handle number
;then activate minimizing calc.exe by copied window's handle number from Au3Info.exe
Run("C:\Program Files\AutoIt3\Au3Info.exe")
WinWaitActive("(Frozen) AutoIt v3 Window Info")
WinSetOnTop("(Frozen) AutoIt v3 Window Info", "", 0)
WinMove("(Frozen) AutoIt v3 Window Info","",0,0)
Run("calc.exe")
WinWaitActive("Calculator")
Winmove("Calculator","",500,500)
WinActivate("(Frozen) AutoIt v3 Window Info")
WinWaitActive("(Frozen) AutoIt v3 Window Info")
MouseClickDrag("left",261, 156,505,505)
MouseClick("left",136, 374,10) ;copy calculator window's handle number form Au3Info
WinSetState ( "Calculator", "", #SW_MINIMIZE )
WinActivate(ClipGet ( ))
;$hWnd=0x004D01DE ; window's handle number copy from Au3Info
;ConsoleWriteError(#crlf & WinActivate($hWnd) & #crlf)
Above, I want to active current session 0x004D01DE-handle windows, but it didn't work, returned me "0", not found specific window. Although the window's handle number still be the same, when I recheck.
I debugging some part of my script, so I have to copy the specific handle window's number by myself to save a long period of time for debugging from the full code.
Did I use that window's handle number in right way?

I see no reason to use Au3Info.exe. WinWaitActive already returns the handle. Just use it:
Run("calc.exe")
$hCalc=WinWaitActive("Calculator")
MsgBox(0,"Handle","Calculatior's handle is: " & $hCalc)
WinMove($hCalc,"",500,500)
WinSetState($hCalc,"",#SW_MINIMIZE)
Another possibility is WinGetHandle

The answer is HWnd(). Just change WinActivate(ClipGet()) to WinActivate(HWnd(ClipGet())).

Related

I need help for gamemaker 2.3

Pls help me
A few weeks ago it came out of gamemaker 2.3, practically in the gamemaker language they changed the scripts into functions, but now after converting the files to be able to reopen them, I double-checked all the scripts and etc but anyway when I start it it remains a black screen, however it doesn't give me any compilation errors or whatever, what could be the problem?
Ps.
I might sound stupid, but if someone has the same program as me I can pass the project to them so they can see the scripts for themselves, so basically it's just the base and there is only the script to make the player walk and for collisions, I know that no one would want to waste time, but I ask the same
Its possible that your code is stuck in an infinite loop, here's an example of what that might look like:
var doloop = true
while(doloop == true){
x += 1
y += 1
}
the "doloop" variable is never changed within the while loop, so it is always equal to true and the loop never ends. Because the code never finishes looping, it can never get around to drawing anything, so you end up with a black screen. The easiest way to check for these is to put a breakpoint/debugging point at the beginning and just after every while/for/do/ect loop and debug it. e.g. (I am using asterisks "*" to represent breakpoints)
var doloop = true
* while(doloop == true){
x += 1
y += 1
}
*
When you get to one of the loops remove the first breakpoint and hit the "continue" button in the debugger. If it (it being the computer) takes an longer than it should to hit the second breakpoint (as in, you wait for a ten seconds to or two minutes (depends on how complex the code is) and it still hasn't hit the second breakpoint), then you should replace the breakpoint at the beginning of the loop to check and make sure it is still in there. If it is still in the loop, then that is likely where the code is getting stuck. Review the loop and everywhere any associated variables are set/changed, and you should be able to find the problem (even if it takes a while).
Majestic_Monkey_ and the commentors are correct: use the debugger. It's easy and it's your friend. Just place a red circle on the very first line of code that runs, and click the little bug icon and you can step through your code easily.
But to address your specific issue (or if anyone in the future has this issue): scripts have changed into files that can have many functions. Where you used to have
//script_name
var num = argument0 + argument1;
return num;
You would now have
function script_name(a, b) {
var num = a + b;
return num;
}
All you have to do is create a decleration for your new function:
function my_function_name(argument_names, etc...)
Then wrap all your old code in { }, and replace all those ugly "argument0" things with actual names. It's that easy. Plus you can have more than one function per script!

Making AutoIT wait until Audacity completes command

I have a script that I'd like to use to automate processes in Audacity. I have it set up so that all the functions I want to do in Audacity are keyboard shortcuts (since I don't think Audacity uses standard window menus like is required for WinMenuSelectItem()) In other words, my whole code consists of multiple instances of the Send() command. The problem is, AutoIT executes the code too fast. I've tried using WinWait(), but the processes take variable amounts of time. I've also tried ShellExecuteWait() and RunWait()Is there a way to get it to wait until the program isn't doing something, and then execute my send commands? Here's some of my code
Run("C:\Program Files (x86)\Audacity\audacity.exe")
; wait until it's active
WinWaitActive("Audacity")
; get the dialogue box to go away
Send("{ENTER}")
RunWait("Audacity")
; open files
Send("^o")
RunWait("Audacity")
; open the certain file & press enter
Send("test.wav")
RunWait("Audacity")
Send("{ENTER}")
RunWait("Audacity")
; select left boundary of silence period
Send("[")
RunWait("Audacity")
Send("000000100{ENTER}")
RunWait("Audacity")
; select right boundary of silence period
Send("]")
RunWait("Audacity")
Send("200000000{ENTER}")
RunWait("Audacity")
; Use for debugging issues. Systray icon show current line.
Opt('TrayIconDebug', 1)
; Delay default: 250s
Opt('WinWaitDelay', 400)
; Delay default: 5s
Opt('SendKeyDelay', 100)
; Path of the wav file.
$sInFile = #WorkingDir & '\test.wav'
; Optional permanent change of splash screen setting.
_SplashScreen(True)
; Run Audacity and argument of the wav file.
$iPid = Run('"C:\Program Files (x86)\Audacity\audacity.exe" "' & $sInFile & '"')
; Check if Run Audacity failed.
If #error Then
MsgBox(0x40030, #ScriptName, 'Failed to run Audacity')
Exit 1
EndIf
; Wait for main window to get handle. Title is the filename with no extension.
$hMainWindow = WinWait('[TITLE:test; CLASS:wxWindowNR]', '', 10)
; Check allowed timeout of window.
If Not $hMainWindow Then
MsgBox(0x40030, #ScriptName, 'Audacity window not detected.')
Exit 1
EndIf
; If splash screen setting not 0 then handle the window.
If _SplashScreen() Then
AdlibRegister('_WelcomeWindow')
WinWait('Welcome to Audacity', '', 3)
AdlibUnRegister('_WelcomeWindow')
EndIf
; Send '[' to main window to trigger Left Boundary window.
ControlSend($hMainWindow, '', '', '[')
; Get handle of Left Boundary window.
$hMsgWindow = WinWait('Set Left Selection Boundary', '', 5)
; Check allowed timeout of window.
If Not $hMsgWindow Then
MsgBox(0x40030, #ScriptName, 'Selection Boundary window not detected.')
Exit 1
EndIf
; Activate window, set time and click OK.
If WinActivate($hMsgWindow) Then
ControlSend($hMsgWindow, '', 'wxWindowNR1', '{LEFT 3}1'); 1000
ControlClick($hMsgWindow, '', 'Button2'); OK
EndIf
; Send ']' to main window to trigger Right Boundary window.
ControlSend($hMainWindow, '', '', ']')
; Get handle of Right Boundary window.
$hMsgWindow = WinWait('Set Right Selection Boundary', '', 5)
; Check allowed timeout of window.
If Not $hMsgWindow Then
MsgBox(0x40030, #ScriptName, 'Selection Boundary window not detected.')
Exit 1
EndIf
; Activate window, set time and click OK.
If WinActivate($hMsgWindow) Then
; Audacity shows 1000 and focus is on the 1st non zero digit which is 1.
ControlSend($hMsgWindow, '', 'wxWindowNR1', '2'); 2000
ControlClick($hMsgWindow, '', 'Button2'); OK
EndIf
; More code to do.
Sleep(1000)
MsgBox(0x40040, #ScriptName, 'End of automation.' & #CRLF & #CRLF & _
'You can close Audacity to finish.')
; Wait for Audacity process to close.
ProcessWaitClose($iPid)
Exit
Func _WelcomeWindow()
; Used by AdlibRegister to handle the Welcome window.
; Welcome window hides if closed so need to check if exist and is visible (2).
If WinExists('Welcome to Audacity') Then
If BitAND(WinGetState('Welcome to Audacity'), 2) Then
WinClose('Welcome to Audacity')
Else
AdlibUnRegister('_WelcomeWindow')
EndIf
EndIf
EndFunc
Func _SplashScreen($bDisable = False)
; Write to audacity.cfg to disable splash screen.
Local $sIniFile = #AppDataDir & '\Audacity\audacity.cfg'
If IniRead($sIniFile, 'GUI', 'ShowSplashScreen', '1') = '1' Then
If $bDisable Then
; Return 1 if ini file change is success.
If IniWrite($sIniFile, 'GUI', 'ShowSplashScreen', '0') Then
Return 1
EndIf
Else
; Return 1 if check for splash screen is enabled.
Return 1
EndIf
EndIf
EndFunc
Opt() is used to slow down the wait of windows and the sends.
Also added Opt('TrayIconDebug', 1) for debugging though if
the script is considered good then you can remove that Opt().
ControlSend() is used instead of Send() as ControlSend()
targets windows and controls based of title, text, etc.
The Opt() delays are not required though was added to
demonstrate the usage, though perhaps Audacity may struggle
to keep with the speed that AutoIt can automate.
If possible, suggest use of Control*() functions for automation.
Storing window handles in a variable can help save retyping titles
in the code. WinWait() returns a window handle which is ideal and
if the timeout parameter is used, then 0 indicates the window not
found so automation can be aborted.
The Classname of the main window is not enough on its own as
Audacity creates many invisible windows with the same Classname.
So, the title may need to be used as well. The title could be
used alone though titled by filename may not be unique at times.
See Window Titles and Text Advanced for usage.
WinActivate() is used on the Boundary windows although it
may not be needed as control*() usually do not need active
windows. Standard Msgboxes in comparison may require to be
active to accept messages sent to them.
ShellExecuteWait() and RunWait() are no good for automation
as they block the script from continuing until the executed
process has finished.
So use ShellExecute() or Run() instead.
The repetitive use of RunWait("Audacity") seems like
desperation to correct the behavior perhaps, though flawed.
Waiting for windows to appear is how to control flow and then
functions such as ControlCommand() can detect state of controls.
ControlClick() is used on the buttons.
CtrlID of Classname Button2 is used though if the script
is always for English users then you can use the text which
would be OK for the OK button.
The ProcessWaitClose($iPid) is optional.
It is sometimes useful to wait for the program
being automated to exit before the script exits.
You comment "get the dialogue box to go away" in you code
after starting Audacity. You can change the setting on the
dialogue box or Preferences -> Interface options. Advice
disabling as it is a future problem to keep handling.
I added some code to disable the setting in the
audacity.cfg file. If not preferred to disable with
_SplashScreen(True) or done manually then
the AdLibRegister('_WelcomeWindow') call will handle
closing the window. Note that the Welcome window does
not close but rather hides.
_SplashScreen(True) changes splash setting to 0 to disable the splash.
_SplashScreen(False) or _SplashScreen() does no change of settings.
The call returns 1 if splash is enabled else 0.

AutoIt Scripting for an External CLI Program - eac3to.exe

I am attempting to design a front end GUI for a CLI program by the name of eac3to.exe. The problem as I see it is that this program sends all of it's output to a cmd window. This is giving me no end of trouble because I need to get a lot of this output into a GUI window. This sounds easy enough, but I am begining to wonder whether I have found one of AutoIt's limitations?
I can use the Run() function with a windows internal command such as Dir and then get the output into a variable with the AutoIt StdoutRead() function, but I just can't get the output from an external program such as eac3to.exe - it just doesn't seem to work whatever I do! Just for testing purposesI I don't even need to get the output to a a GUI window: just printing it with ConsoleWrite() is good enough as this proves that I was able to read it into a variable. So at this stage that's all I need to do - get the text (usually about 10 lines) that has been output to a cmd window by my external CLI program into a variable. Once I can do this the rest will be a lot easier. This is what I have been trying, but it never works:
Global $iPID = Run("C:\VIDEO_EDITING\eac3to\eac3to.exe","", #SW_SHOW)
Global $ScreenOutput = StdoutRead($iPID)
ConsoleWrite($ScreenOutput & #CRLF)
After running this script all I get from the consolWrite() is a blank line - not the text data that was output as a result of running eac3to.exe (running eac3to without any arguments just lists a screen of help text relating to all the commandline options), and that's what I am trying to get into a variable so that I can put it to use later in the program.
Before I suggest a solution let me just tell you that Autoit has one
of the best help files out there. Use it.
You are missing $STDOUT_CHILD = Provide a handle to the child's STDOUT stream.
Also, you can't just do RUN and immediately call stdoutRead. At what point did you give the app some time to do anything and actually print something back to the console?
You need to either use ProcessWaitClose and read the stream then or, you should read the stream in a loop. Simplest check would be to set a sleep between RUN and READ and see what happens.
#include <AutoItConstants.au3>
Global $iPID = Run("C:\VIDEO_EDITING\eac3to\eac3to.exe","", #SW_SHOW, $STDOUT_CHILD)
; Wait until the process has closed using the PID returned by Run.
ProcessWaitClose($iPID)
; Read the Stdout stream of the PID returned by Run. This can also be done in a while loop. Look at the example for StderrRead.
; If the proccess doesnt end when finished you need to put this inside of a loop.
Local $ScreenOutput = StdoutRead($iPID)
ConsoleWrite($ScreenOutput & #CRLF)

Check if window has focus with AutoIt

I wonder if it is possible to check to see if a window has focus in AutoIt. I have checked and not found much. I have tried using WinSetOnTop but this didn't seem to do anything so then I considered using WinActivate but this didn't seem to do what I need.
The reason I want to do this is because I have this application I am writing as a prank and I do not want the co-worker on whom I'm playing the prank to just ignore the window when it starts automatically. I am wanting to put a shortcut to it in the startup folder and we have several applications that run on startup and so I want mine to either always be on top or audibly shout rude words at the user if they try and ignore the application.
Is this possible and, if so, can you help me out because I am out of ideas.
Regardless of your motives, you may try WinWaitActive.
Syntax:
WinWaitActive ( "title" [, "text" [, timeout = 0]] )
Example that may be useful to try it out:
Func Example()
; Run Notepad
Run("notepad.exe")
; Wait 10 seconds for the Notepad window to appear.
WinWaitActive("[CLASS:Notepad]", "", 10)
; Wait for 2 seconds to display the Notepad window.
Sleep(2000)
; Close the Notepad window using the classname of Notepad.
WinClose("[CLASS:Notepad]")
EndFunc ;==>Example
Reference:
https://www.autoitscript.com/autoit3/docs/functions/WinWaitActive.htm

AutoIt: Send("{DOWN}") not working

I am running an "autoit3.chm" file. When it runs, I would like to send a down key arrow but it doesn't work:
$file = FileGetShortName("C:\Users\PHSD100-SIC\Desktop\AutoIt3.chm")
Run(#ComSpec & " /c start " & $file)
WinWaitActive("AutoIT Help")
Send("{DOWN}")
Well, you're just waiting for the wrong Window Title... Try WinWaitActive("AutoIt Help") and it will work... Your "T" must be a "t"...
To find this out, you just need to check your script output and after your CHM-File has been opened you'll see that your script is still running. But you would have expected it to execute the Send(...) and then terminate. So your script must still be waiting for the expected window to appear. Which will lead you to double check your window title, probably you'll directly copy the window title with the AutoIt Window Info Tool, and this shows your mistake. Correct it. Viola, be happy =)
Besides: You don't need to run a Command-Prompt first, you can call ShellExecute($file) directly instead.
If you use the AutoIt Window Info tool, it helps with these issues, and it's also good practice to debug with ConsoleWrite(...)s.
For example, a simple one would be as before. However, you should probably use timeouts or variables and use the return for success/fail.
WinWaitActive("Window")
ConsoleWrite("Success")
Send("{DOWN}")
ConsoleWrite("Success")
Use following syntax for down key enter
Send("{DOWN 2}")
and similar for Up key enter
Send("{UP 2}")

Resources