Autohotkey: Merging/combining two scripts in one script (#if WinActive, 2 actions) - merge

I have 2 scripts I want to merge in one file, however when I put them together, only the first one gets executed:
Script 1:
#if WinActive("ahk_exe program.EXE")
#Persistent
Loop
{
WinWaitActive, Wizard
Send, !{F4}
}
Return
Script 2:
#if WinActive("ahk_exe program2.EXE")
#Persistent
Loop
{
WinWait, ahk_class bosa_sdm_Mso96
; IfWinNotActive, ahk_class bosa_sdm_Mso96, ,WinActivate, ahk_class bosa_sdm_Mso96
; WinWaitActive, ahk_class bosa_sdm_Mso96
; Sleep, 0
ControlMove, RichEdit20W6, 20, 850, 750, 25 ;Adress box
ControlMove, SysTreeView321, , , 800, 700
ControlMove, TreeViewCFParent1, , , 1000, 700
ControlMove, SysTreeView322, , , 800, 700
ControlMove, TreeViewParent1, , , 760, 940
WinMove, ahk_class bosa_sdm_Mso96, , 600, 50, 1000, 900 ; 900 width
}
Return
I tried removing or changing the location of "#Persistent", "Loop", "Return".. or adding #if at the end of each script.. still only the first one gets executed.. Even when trying to #Include the first script in the second, the first only gets executed. Maybe it needs "else" or something.. not sure..

The #If directive is only used for creating context-sensitive hotkeys and hotstrings.
If you use WinWait or WinWaitActive the script waits until the (first) window exists or becomes active and doesn't go any further to move the second window.
Without WinWait the CPU usage of the script is high.
The better solution in this case is SetTimer:
#Persistent
SetTimer, Close_Move_Windows, 500
return
Close_Move_Windows:
IfWinActive, Wizard
WinClose
IfWinExist, ahk_class bosa_sdm_Mso96
{
WinGetPos, X, Y, Width, Height, ahk_class bosa_sdm_Mso96
If (X != 600 || Y != 50 || Width != 900 || Height != 1000) ; "!" means "NOT" and "||" means "OR"
{
ControlMove, RichEdit20W6, 20, 850, 750, 25 ;Adress box
ControlMove, SysTreeView321, , , 800, 700
ControlMove, TreeViewCFParent1, , , 1000, 700
ControlMove, SysTreeView322, , , 800, 700
ControlMove, TreeViewParent1, , , 760, 940
WinMove, ahk_class bosa_sdm_Mso96,, 600, 50, 900, 1000 ; 900 width
}
}
Return

Related

Script modification(drag and drop)

I have simple script that looks for specified color pixel in restricted area then performs move mouse of this pixel to specified x,y coordinates it looks like this(control hold is added, because it needs to be pressed while moving stock):
#ifwinactive
F10::
PixelSearch, ItemX, ItemY, 1800, 600, 1700, 500, 0xFFE047, 1 , RGB FAST
if ErrorLevel = 0
Mousemove, ItemX, ItemY, 0
Send, {lbutton down}
sleep, 20
Send, {lctrl down}
Random x, 1600, 1700
Random y, 590, 655
Mousemove, x, y, 0
Send, {lbutton up}
Send, {lctrl up}
return
It works great but takes control over my MOUSE which I don't want, so I am trying to modify it to perform action without taking control over my mouse. I have tried to search, using controlclick but this couldn't handle dragging, then I have read about PostMessage which I don't clearly understand but I have come with this kind of script(not fully understand dll calls that's why most likely it doesn't work like intented):
#ifwinactive
x := 1650
y := 620
F10::
PixelSearch, ItemX, ItemY, 1900, 600, 1750, 500, 0xFFC661, 1, RGB Fast
CoordMode, Pixel, Screen
if !hWnd := DllCall("WindowFromPoint", Int,ItemX, Int,ItemY, Ptr)
if !hWnd := DllCall("WindowFromPoint", UInt64,(ItemX&0xFFC661)|(ItemY<<32), Ptr)
if !hWnd := DllCall("WindowFromPoint", UInt64, x|(y << 32), Ptr)
return
VarSetCapacity(POINT, 8, 0)
NumPut(ItemX, POINT, 0, "Int"), NumPut(ItemY, POINT, 4, "Int")
DllCall("user32\ScreenToClient", Ptr,hWnd, Ptr,&POINT)
ItemX := NumGet(POINT, 0, "Int"), ItemY := NumGet(POINT, 4, "Int")
if ErrorLevel
PostMessage, 0x0200, 0, ItemX&0xFFC661|ItemY<<16,, % "ahk_id " hWnd ;WM_MOUSEMOVE
sleep, 5
PostMessage, 0x0201, 0, ItemX&0xFFC661|ItemY<<16,, % "ahk_id " hWnd ;WM_LBUTTONDOWN
sleep, 5
PostMessage, 0x0200, 0, x|y<<16,, % "ahk_id " hWnd ;WM_MOUSEMOVE
sleep, 5
PostMessage, 0x0202, 0, x|y<<16,, % "ahk_id " hWnd ;WM_LBUTTONUP
sleep, 5
return
There is problem with this scirpt it actually act like this: Search for pixel>if it's there>perform post messages under my cursor(actually taking things under my mouse to specified x,y.
While what I want is to look for pixel, pick this pixel and move it. Is it even possible without taking control over my mouse?
EDIT!
NEW CODE
#ifwinactive
CoordMode, Pixel , Screen
x := 1650
y := 620
lparam := pX | (pY << 16)
lparam2 := x | (y << 16)
f10::
PixelSearch, pX, pY, 1900, 1000, 1750, 500, 0xFFE047, 1, Fast
if Errorlevel
{
PostMessage, 0x0200, 0, %lparam%,, ahk_exe something.exe ;WM_MOUSEMOVE
sleep, 10
PostMessage, 0x0201, 0x0001, %lparam%,, ahk_exe something.exe ;WM_LBUTTONDOWN
sleep, 10
PostMessage, 0x0200, 0x0001, %lparam2%,, ahk_exe something.exe ;WM_MOUSEMOVE
sleep, 10
PostMessage, 0x0202, 0, %lparam2%,, ahk_exe something.exe ;WM_LBUTTONUP
}
return

My script breaks down at some point, I've eliminated all the syntax errors the debugger was able to spot

This is a script that is supposed to use the windows snipping tool to sequentially screencap pictures from an online gallery. If anyone can spot the problem that would be much appreciated.
#SingleInstance, Force
a := 112
name :=1
x:: Pause, Toggle
y:: ExitApp
Loop, a
{
MouseClickDrag, Left, 1300, 210, 645, 140
Sleep, 100
MouseClick, Left, 1277, 1038, 0, 5
sleep, 100
MouseClick, Left, 838, 64, 0, 5
sleep, 100
SendInput, %name%
name ++
sleep, 100
SendInput, {Enter}
Sleep, 100
MouseClickDrag, Left, 670, 13, 1393, 153
Sleep, 100
MouseClick, Left, 500, 490, 0, 5
Sleep, 300
MouseClick, Left, 500, 490, 0, 5
SendInput, {Right}
}
Two problems in it.
Firstly, your loop is unreachable code.
Code execution stops when your first hotkey label is encountered. This is called the Auto-execute Section.
Secondly, loop doesn't take an expression to the first parameter. It takes a legacy text parameter. So you'd either want to use the legacy way of referring to a variable, which would be %a%, but personally I'd push you towards using the modern expression syntax and forcing an expression to that parameter by starting the parameter off with a % followed up by a space. So Loop, % a.
To read more about legacy syntax vs expression syntax, see this page of the documentation.
Here's your fixed script:
#SingleInstance, Force
a := 112
name := 1
Sleep, 3000
Loop, % a
{
MouseClickDrag, Left, 1300, 210, 645, 140
Sleep, 100
MouseClick, Left, 1277, 1038, 0, 5
Sleep, 100
MouseClick, Left, 838, 64, 0, 5
Sleep, 100
SendInput, % name
name++
Sleep, 100
SendInput, {Enter}
Sleep, 100
MouseClickDrag, Left, 670, 13, 1393, 153
Sleep, 100
MouseClick, Left, 500, 490, 0, 5
Sleep, 300
MouseClick, Left, 500, 490, 0, 5
SendInput, {Right}
}
;this return here ends the auto-execute section
;but of course, in this specific case it's totally
;useless since the next line is a hotkey label
;which would also stop the auto-execute section
return
;even though the code execution gets stuck inside the loop,
;hotkeys can be specified down here
;they're created even before the auto-execute section starts
x::Pause, Toggle
y::ExitApp

How to change the loop?

The script is searching for a certain text in the clipboard. When found, it shows a MsgBox.
I would like this script to stop when the text has been found. How to achieve that?
#Persistent
MouseMove, 821, 700
Sleep, 500
MouseClick, Left
Sleep, 500
Loop, 5
{
Send, ^c
Sleep, 500
Send, {PgDn}
}
OnClipboardChange:
If InStr( Clipboard, "Part3" )
SetTimer, PopupMsgBox, -1
Return
PopupMsgBox:
Msgbox, Part3 Found
Return
#Persistent
clip_search := "Part3"
MouseMove, 821, 700
Sleep, 500
MouseClick, Left
Sleep, 500
Loop, 5
{
Send, ^c
ClipWait
If InStr( Clipboard, clip_search )
{
MsgBox, % clip_search " Found."
Break
}
Sleep, 500
Send, {PgDn}
}

Unstoppable script Issue

I have a script wich uses several mousemoves and, when needed, I press F3 to stop the moves forcing a reload or ESC to stop the moves exiting the app. It works fine with no issues in the regular speed.
The problem is: when I decrease the mousespeed and increase the mousedelay, the script becomes unstoppable: I press the F2, F3 and ESC keys several times (trying to make it stops) but the script ignores it and continues running the mousemoves.
Here's a minimal example of my problem:
SendMode Input
$F1::
SetDefaultMouseSpeed, 50
SetMouseDelay, 30
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
Mousemove, 200, 200
Mousemove, 600, 600
SoundPlay, *48
return
$F2:: Pause
$F3:: Reload
$ESC:: ExitApp
Why does it happens and how can I fix it (how can I stop the script even with low speed+high delay)?
ps: F1 key starts the mousemoves sequence.
MouseMove with non-zero speed cannot be interrupted by another hotkey inside the same AHK script because Autohotkey is single-threaded internally (it just emulates thread-like behavior) and performs a blocking sleep for each mouse micromovement until it reaches the overall distance you specified.
Solutions:
Check whether a hotkey was pressed after each MouseMove, but it's non-instantaneous;
Implement your own MouseMove that checks GetKeyState after each 1px movement;
Use a master script with hotkeys that run/pause/stop the child:
Stopping: trivial, use Process Close
Running: the child should hide tray icon otherwise it'll stay after process close
Pausing: nontrivial but there are solutions (see also the underlying mechanics).

Resizing Google Hangouts app on Win 10 with Autohotkey

I need to resize Google Hangouts app in Win 10. through Autohotkey
Currently it is 260*460, and I need it to be 1150*750.
Here are the Window spy data:
>>>>>>>>>>( Window Title & Class )<<<<<<<<<<<
Hangouts
ahk_class Chrome_WidgetWin_1
>>>>>>>>>>>>( Mouse Position )<<<<<<<<<<<<<
On Screen: 901, 600 (less often used)
In Active Window: -759, 580
>>>>>>>>>( Now Under Mouse Cursor )<<<<<<<<
Color: 0xF0F0F0 (Blue=F0 Green=F0 Red=F0)
>>>>>>>>>>( Active Window Position )<<<<<<<<<<
left: 1660 top: 20 width: 260 height: 460
>>>>>>>>>>>( Status Bar Text )<<<<<<<<<<
>>>>>>>>>>>( Visible Window Text )<<<<<<<<<<<
Chrome Legacy Window
>>>>>>>>>>>( Hidden Window Text )<<<<<<<<<<<
>>>>( TitleMatchMode=slow Visible Text )<<<<
>>>>( TitleMatchMode=slow Hidden Text )<<<<
I tried something like the following, but it didn't work:
[code]
#Persistent
Loop
{
WinWaitActive, ahk_class Chrome_WidgetWin_1
WinMove, ahk_class Chrome_WidgetWin_1, , 1150, 750
}
Return
[/code]
The WinMove command requires those arguments:
WinMove, WinTitle, WinText, X, Y [, Width, Height, ExcludeTitle, ExcludeText]
The arguments WinText, X and Y can be ommited in which case you leave them empty, but you still have to use the commas to indicate them.
You only left the argument WinText empty and the arguments with value 1150 and 750 got interpreted as arguments X and Y.
The solution is to add those two unused arguments X and Y:
WinMove, ahk_class Chrome_WidgetWin_1, , , , 1150, 750
If for example you want to also move the window to the positions 200, 100, then use the X and Y arguments as well:
WinMove, ahk_class Chrome_WidgetWin_1, , 200, 100, 1150, 750
; WinMove, WinTitle (or) ahk_class WinClass, WinText, X, Y , Width, Height, ExcludeTitle, ExcludeText
WinMove, ahk_class Chrome_WidgetWin_1, , , , 1150, 750