Script modification(drag and drop) - autohotkey

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

Related

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 do I convert string to interger in AHK

I have this code below and I would like to get a string like "0,0" convert to integer and sum boths variable putting it on a new variable.
I was looking for solution in internet but without sucess.
code:
MouseMove, 238,282
MouseClickDrag, Left, 238,282, 238,282
Sleep, 200
Send, {CTRLDOWN}c{CTRLUP}
CLIPWAIT, 0.5
SaldoContabil = %ClipBoard% ; here is getting 0,0
Sleep, 400
MouseMove, 602,283
MouseClickDrag, Left, 602,283, 602,283
Sleep, 500
Send, {CTRLDOWN}c{CTRLUP}
CLIPWAIT, 0.5
ArredAcumulado = %ClipBoard% ; here is getting 0,0
Sleep, 400
baixa = %ArredAcumulado% - %SaldoContabil%
Add the following lines before the final calculation.
StrReplace just replaces the , with a . so from 0,0 you get 0.0, no further conversion is necessary.
SaldoContabil := StrReplace(SaldoContabil,",",".")
ArredAcumulado := StrReplace(ArredAcumulado ,",",".")

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

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

Changing AHK Response, Everytime I move my mouse :(

Here's my sample script
$f2::
loop, 1
while GetKeyState("f2", "P")
{
setkeydelay, 1
send, {f2}
click
}
return
I have 3 delays Normal, Fast, Faster everytime I move my mouse it changes its delay.What should I add in the script to make the response consistent?
ListLines, Off
CoordMode, Mouse
cnt:=1, arr:=[50 ; normal
, 25 ; fast
, 0] ; faster
$F2::
;~ TrayTip,, % "delay is: "arr[cnt]
MouseGetPos, xPos, yPos
xPosPrev:=xPos, yPosPrev:=yPos
While, GetKeyState("F2", "P")
{
MouseGetPos, xPos, yPos
If (xPosPrev!=xPos Or yPosPrev!=yPos)
{
`(cnt=3) ? cnt:=1:cnt++, xPosPrev:=xPos, yPosPrev:=yPos, bool:=False
;~ TrayTip,, % "delay changed to: "arr[cnt]
While, !bool
{
MouseGetPos, xPos, yPos
bool:=(xPosPrev=xPos And yPosPrev=yPos) And A_Index>50 ? True:False
Sleep, GetKeyState("F2", "P") ? 25:-1
xPosPrev:=xPos, yPosPrev:=yPos
}
}
SetKeyDelay, arr[cnt]
Send, {F2}{Click}
Sleep, GetKeyState("F2", "P") ? 25:-1
}
Return

click and drag one pixel per keystroke from variable point

I want to create a set of mouse movements assigned to the four arrow keys where a keystroke will click and drag one pixel left, right, up, or down. The starting point will be variable. I have no idea how to accomplish this. I gave it a sort of good faith try before asking, but I really need to ask somebody to show me how to do it.
Thanks,
Ellen
Ellen, here we go:
#Persistent
^NumPadUp::
Send, {LButton Down}
MouseMove, 0, -1, 1, R ;Move the mouse one pixel Up
Send, {LButton Up}
Return
^NumPadDown::
Send, {LButton Down}
MouseMove, 0, 1, 1, R ;Move the mouse one pixel Down
Send, {LButton Up}
Return
^NumPadRight::
Send, {LButton Down}
MouseMove, 1, 0, 1, R ;Move the mouse one pixel to the right
Send, {LButton Up}
Return
^NumPadLeft::
Send, {LButton Down}
MouseMove, -1, 0, 1, R ;Move the mouse one pixel to the left
Send, {LButton Up}
Return