Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

WoW Multiboxing - send click


  • Please log in to reply
6 replies to this topic
Thundervolt
  • Guests
  • Last active:
  • Joined: --
Hi all,
I've been struggling a bit with this.
I've been trying to send a click to multiple instances of World of Warcraft, and the following snippet works well for that but I don't feel its very elegant, and let me explain the problem.
Essentially you call the following snippet with the code of the Mouse button you pressed and it performs the click on the same coords of both instances of the game.
The problem is I couldn't find a way to send the click to an inactive window, so I need to activate each window, move the mouse to the coordinates, send the click and return to the previous active window

And hence the question, is it possible to send the click to those coordinates without making the window active?

ClonesClickPush(strKeys)
{
	global WowWinId1
	global WowWinId2
	IfWinNotActive, ahk_id %WowWinId1%
	{
		Click, %strKeys%
		CoordMode, Mouse, Rel
		MouseGetPos, xpos, ypos
		WinActivate, ahk_id %WowWinId2%
		MouseMove, %xpos%, %ypos%
		Click, %strKeys%
		WinActivate, ahk_id %WowWinId1%
		MouseMove, %xpos%, %ypos%
	}
	IfWinNotActive, ahk_id %WowWinId2%
	{
		Click, %strKeys%
		CoordMode, Mouse, Rel
		MouseGetPos, xpos, ypos
		WinActivate, ahk_id %WowWinId2%
		MouseMove, %xpos%, %ypos%
		Click, %strKeys%
		WinActivate, ahk_id %WowWinId1%
		MouseMove, %xpos%, %ypos%
	}
}


Thundervolt
  • Guests
  • Last active:
  • Joined: --
sorry, there was a mistake in the script I posted, it wasn't sending the click from the second window to the first.

ClonesClickPush(strKeys)
{
   global WowWinId1
   global WowWinId2
   IfWinNotActive, ahk_id %WowWinId1%
   {
      Click, %strKeys%
      CoordMode, Mouse, Rel
      MouseGetPos, xpos, ypos
      WinActivate, ahk_id %WowWinId1%
      MouseMove, %xpos%, %ypos%
      Click, %strKeys%
      WinActivate, ahk_id %WowWinId2%
      MouseMove, %xpos%, %ypos%
   }
   IfWinNotActive, ahk_id %WowWinId2%
   {
      Click, %strKeys%
      CoordMode, Mouse, Rel
      MouseGetPos, xpos, ypos
      WinActivate, ahk_id %WowWinId2%
      MouseMove, %xpos%, %ypos%
      Click, %strKeys%
      WinActivate, ahk_id %WowWinId1%
      MouseMove, %xpos%, %ypos%
   }
}


girlgamer
  • Moderators
  • 3263 posts
  • Last active: Feb 01 2015 09:49 AM
  • Joined: 04 Jun 2010
for background windows (ones that aren't active) you need ControlClick or ControlSend. (which also works on the active window too, btw).
; prototypes are :ControlClick [, Control-or-Pos, WinTitle, WinText, WhichButton, ClickCount, Options, ExcludeTitle, ExcludeText]
;and
;ControlSend [, Control, Keys, WinTitle, WinText, ExcludeTitle, ExcludeText]

; examples
ControlClick , x%xcoord% y%ycoord%, ahk_id %WowWinID1%, , Left, 1

;lets say you want to send a keys 1 3 and 5 to both windows at the same time .. you might do 
; something like this...
KeysToSend = 135
ControlSend, , %KeysToSend%, ahk_id %WowWinID1%
ControlSend, , %KeysToSend%, ahk_Id %WowWinID2%

the nice thing about this method is that you can trigger every window at the same time (within reason of course -- there'll still be a time differential) with a single keystroke. regardless of which of your windows are active.
1:: 
SendAll(1)
Return
2::
SendAll(2)
Return

; send keys to game chars on windows 1 and 2
SendAll(Keys)
{   Global, WowWinID1
    Global, WowWinID2
ControlSend, , %Keys%, ahk_id %WowWinID1%
    ControlSend, , %Keys%, ahk_Id %WowWinID2%
}

; send clicks to game chars on windows 1 and 2
ClickOn(locx, locy, button=L, clickcount=1)
{   Global, WowWinID1
    Global, WowWinID2
    CoordMode Mouse, Relative
    ControlClick , x%locx% y%locy%, ahk_id %WowWinID1%, , %button%, %clickcount%
    ControlClick , x%locx% y%locy%, ahk_id %WowWinID2%, , %button%, %clickcount%
}
you may have to play with these to get them to work the way you want...

The universe is a wondrous place! The faster you create unbreakable code, the faster the universe creates people that can break it. All scripting follows the rule Rule Of Twos -- 1) Good, 2) Fast 3) Cheap -- pick any Two.
I guarantee absolutely nothing about any code I provide except that it works in my machine. ‚óŹ
MMO Fighter   KeyLooperDemo   Key Spammer   TinyClickRecorder  GGs Password Generator.ahk
For the newest version of AutoHotkey and some killer scripts go here.
Rock-on%20kitten.gif


Thundervolt
  • Guests
  • Last active:
  • Joined: --
amazing, thanks for the quick answer.
I was actually using a very similar function for the keys already with ControlSend.
But I didn't had the insight on ControlClick (attempted MouseClick and Click though).

Thanks for the help, I will try with the tips you gave me in the afternoon. :)

Thundervolt
  • Guests
  • Last active:
  • Joined: --
Posting my solution which is currently working.

I dont know why, but i had a ton of problems trying to use the ControlClick, from my experimentation it would appear it is not affected by CoordMode and it resulted in just doing the click wherever the mouse last exited that window regarless of coordenades, even if using optional flags like NA or pos or both.

I added some additional functions since I also wanted to do partial clicks so I can move the direction a character is facing on another instance.

In general the code is not optimized or pretty, but it works for dualboxing, some tweaking would be needed for using more instances of the game though.

ClonesClickPush(mKeys)
{
	global WowWinId1
	global WowWinId2
	global WowWinHeightId1
	global WowWinHeightId2
	global WowWinWidthId1
	global WowWinWidthId2
	olddelay := A_MouseDelay
	oldspeed := A_DefaultMouseSpeed
	CoordMode, Mouse, Rel
	MouseGetPos, xpos, ypos, ,1
; *** Every click will be sent to both instances, we just want to know if this window was active 
; *** Because I havent been able to send clicks to inactive windows, so we will cicle through all 
; *** of the boxes to send the click and then return to the originating window
; *** If using more than two instances, this might need to be changed for a loop
; *** But im unsure of the delay of moving the cursor and making multiple windows active if using a higher number
	IfWinNotActive, ahk_id %WowWinId1%
		if ((xpos < WowWinWidthId2 && ypos < WowWinHeightId2)&& (xpos > 0 && ypos > 0) )
			flow1 := 0
	IfWinNotActive, ahk_id %WowWinId2%
		if ((xpos < WowWinWidthId1 && ypos < WowWinHeightId1) && (xpos > 0 && ypos > 0) )
			flow1 := 1
	if(flow1 == 0)
	{
		WinActivate, ahk_id %WowWinId1%
		CoordMode, Mouse, Rel
; *** this is just to make an offset so the click happens at aprox the same place in both windows 
; *** even if the sizes of the windows is different, they have to be the same aspect ratio though
		finalX := xpos * (WowWinWidthId1/WowWinWidthId2)
		finalY := ypos * (WowWinHeightId1/WowWinHeightId2)
		SetMouseDelay, -1
		SetDefaultMouseSpeed, 0
		MouseMove, %finalX%, %finalY%
		Click, %finalX%, %finalY%, %mKeys%
		WinActivate, ahk_id %WowWinId2%
		Click, %xpos%, %ypos%, %mKeys%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
	if(flow1 == 1)	
	{
		WinActivate, ahk_id %WowWinId2%
		CoordMode, Mouse, Rel
		finalX := xpos * (WowWinWidthId2/WowWinWidthId1)
		finalY := ypos * (WowWinHeightId2/WowWinHeightId1)
		SetMouseDelay, -1
		SetDefaultMouseSpeed, 0
		MouseMove, %finalX%, %finalY%
		Click, %finalX%, %finalY%, %mKeys%
		WinActivate, ahk_id %WowWinId1%
		Click, %xpos%, %ypos%, %mKeys%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
}

ClickDragPush(mKeys)
{
	global WowWinId1
	global WowWinId2
	global WowWinHeightId1
	global WowWinHeightId2
	global WowWinWidthId1
	global WowWinWidthId2
	olddelay := A_MouseDelay
	oldspeed := A_DefaultMouseSpeed
	CoordMode, Mouse, Rel
	MouseGetPos, xpos, ypos, ,1
	IfWinNotActive, ahk_id %WowWinId1%
		if ((xpos < WowWinWidthId2 && ypos < WowWinHeightId2)&& (xpos > 0 && ypos > 0) )
			flow1 := 0
	IfWinNotActive, ahk_id %WowWinId2%
		if ((xpos < WowWinWidthId1 && ypos < WowWinHeightId1) && (xpos > 0 && ypos > 0) )
			flow1 := 1
	if(flow1 == 0)
	{
		WinActivate, ahk_id %WowWinId1%
		CoordMode, Mouse, Rel
		finalX := xpos * (WowWinWidthId1/WowWinWidthId2)
		finalY := ypos * (WowWinHeightId1/WowWinHeightId2)
		SetMouseDelay, -1
		SetDefaultMouseSpeed, 0
		MouseMove, %finalX%, %finalY%
		Click, %finalX%, %finalY%, %mKeys%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
	if(flow1 == 1)	
	{
		WinActivate, ahk_id %WowWinId2%
		CoordMode, Mouse, Rel
		finalX := xpos * (WowWinWidthId2/WowWinWidthId1)
		finalY := ypos * (WowWinHeightId2/WowWinHeightId1)
		SetMouseDelay, -1
		SetDefaultMouseSpeed, 0
		MouseMove, %finalX%, %finalY%
		Click, %finalX%, %finalY%, %mKeys%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
}

ClickDragRelease(mKeys)
{
	global WowWinId1
	global WowWinId2
	global WowWinHeightId1
	global WowWinHeightId2
	global WowWinWidthId1
	global WowWinWidthId2
	olddelay := A_MouseDelay
	oldspeed := A_DefaultMouseSpeed
	CoordMode, Mouse, Rel
	MouseGetPos, xpos, ypos, ,1
	SetMouseDelay, -1
	SetDefaultMouseSpeed, 0
	Click, %xpos%, %ypos%, %mKeys%
	IfWinNotActive, ahk_id %WowWinId1%
		if ((xpos < WowWinWidthId2 && ypos < WowWinHeightId2)&& (xpos > 0 && ypos > 0) )
			flow1 := 0
	IfWinNotActive, ahk_id %WowWinId2%
		if ((xpos < WowWinWidthId1 && ypos < WowWinHeightId1) && (xpos > 0 && ypos > 0) )
			flow1 := 1
	if(flow1 == 0)
	{
		WinActivate, ahk_id %WowWinId1%
		CoordMode, Mouse, Rel
		finalX := xpos * (WowWinWidthId1/WowWinWidthId2)
		finalY := ypos * (WowWinHeightId1/WowWinHeightId2)
		MouseMove, %finalX%, %finalY%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
	if(flow1 == 1)	
	{
		WinActivate, ahk_id %WowWinId2%
		CoordMode, Mouse, Rel
		finalX := xpos * (WowWinWidthId2/WowWinWidthId1)
		finalY := ypos * (WowWinHeightId2/WowWinHeightId1)
		MouseMove, %finalX%, %finalY%
		SetMouseDelay, %olddelay%
		SetDefaultMouseSpeed, %oldspeed%
	}
}

; *** Grab unique window ID's ***
WinGet, WowWinId, List, World of Warcraft
WinGetPos, , , WowWinWidthId1, WowWinHeightId1, ahk_id %WowWinId1%
WinGetPos, , , WowWinWidthId2, WowWinHeightId2, ahk_id %WowWinId2%

; *******************************
; *** Only if WoW is in focus ***
; *******************************
#IfWinActive, World of Warcraft
; *** Mouse clicks ***
XButton1::ClonesClickPush("XButton1")
XButton2::ClonesClickPush("XButton2")
; *** This allows you to control the direction a character in the other account is facing.
MButton::ClickDragPush("down Right")
MButton Up::ClickDragRelease("up Right")



Thundervolt
  • Guests
  • Last active:
  • Joined: --
Hi,
I kept on trying and finally figured out that ControlClick does indeed send a click and the window doesnt need to be active.
However for the click to go to the WoW account i had to do 2 clicks.

There are still some problems though, and i dont know why exactly is that.
I know this is an extensive post, just wanted to shed some light on what I've worked on to see if you could give me a few ideas on what might be wrong.
TLDR: I see two problems.
First, ControlClick ignores my coordinades, and ive tried several optional parameters with no luck (detailed below)
Second, ControlClick doesnt find windows when passed ahk_id parameters (even though ControlSend can find them)

;; this works, but makes window active
\::
   MouseClick, left,  561,  489    
return
;; this works without making window active
\::
    CoordMode Mouse, Relative
    ControlClick , , World of Warcraft, , , 2
return

Now the problem is that even though i pass coordenades to the ControlClick it seems to ignore them

;; this sends a click, but at the last know position of the mouse in the window'
;; instead of the coordinades requested.
\::
    CoordMode Mouse, Relative
    ControlClick , x561 y489, World of Warcraft, , , 2
return

;; this sends a click, but at the last know position of the mouse in the window'
;; instead of the coordinades requested.
\::
    CoordMode Mouse, Relative
    ControlClick , x561 y489, World of Warcraft, , , 2, pos
return

;; this sends a click, but at the last know position of the mouse in the window'
;; instead of the coordinades requested.
\::
    CoordMode Mouse, Relative
    ControlClick , x561 y489, World of Warcraft, , , 2, NA pos
return

;; this sends a click, but at the last know position of the mouse in the window'
;; instead of the coordinades requested.
\::
    CoordMode Mouse, Relative
    ControlClick , x561 y489, World of Warcraft, , , 2, pos x561 y489
return

Furthermore I cant seem to be able to send the click when using ahk_id the same way I do with ControlSend

\::
;MouseClick, left,  561,  489
	global WowWinID1
	global WowWinID2
    CoordMode Mouse, Relative
	ControlClick , , ahk_id %WowWinID1%, , , 2
	ControlClick , , ahk_id %WowWinID2%, , , 2
return

ClonesPush(strKeys)
{
	global WowWinID1
	global WowWinID2
	IfWinNotActive, ahk_id %WowWinID1%
		ControlSend, , %strKeys%, ahk_id %WowWinID1%
	IfWinNotActive, ahk_id %WowWinID2%
		ControlSend, , %strKeys%, ahk_id %WowWinID2%
}
; *** Grab unique window ID's ***
WinGet, WowWinID, List, World of Warcraft

~1::ClonesPush("{1 down}{1 up}")


hamncheese
  • Members
  • 48 posts
  • Last active: Jan 16 2017 12:17 AM
  • Joined: 23 May 2012

please excuse me for ressurecting a very old thread, but i have the exact same problem with the exact same game haha

does nayone have any solution to this i have tried the same variation the OP says

i have tried looking everywhere in forum ( to the best of my abilities at searching) but cant find any solution for :

Sending Mouse Clicks to background Window, specifically Word of Warcraft game window