Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Using multiple mice to control one computer.


  • Please log in to reply
10 replies to this topic
rabbitboy
  • Guests
  • Last active:
  • Joined: --
Problem:

When you have two mice hooked up to your computer, Windows XP will recognize all the mice as the same mouse. Any left click event from any of the mice will send a left click event to whatever window the cursor is on. There isn't a native way to distinguish between one mouse and another under windows XP, so it's difficult to set each mouse to do different things with its buttons.

Solution:

By using Michael Simon's package that allows control of a remote control device, we can obtain enough information from the HID messages that each mouse is sending in order to differentiate between one mouse and another, and create events specific for each mouse.

There are a few caveats to doing this though. First of all, all your mice have to be HID compliant. If you're using Windows XP, this is almost assuredly the case. Second of all, you need to download the package that Michael Simon provides that has his DLL which allows you to program remote control buttons. You can get it here: https://ahknet.autoh...Autohotkey.html Lastly, you have to disable all the buttons across the system. This is easy to do because Windows XP thinks that all the mice are the same mouse, so all you have to do is set up a basic mouse hotkey that disables the mouse buttons.

LButton::return
RButton::return
Etc., etc.

When you have these commands in a script, they will disable the buttons on all of your mice at the same time, because Windows XP "sees" those mice all as the same mouse. Then, we use Michael Simon's DLL to obtain the HID messages, which contain what buttons have been pressed and which mouse those buttons are attached to. Then it's a simple matter of sending an event in response to specific buttons being pressed by specific mice.

In my situation, I have a PS2 mouse for my left hand and a trackball for my right hand. I have to wear a carpal tunnel brace on my right-hand, which causes me to hit the buttons on the trackball accidentally. In this script, I have disabled the buttons on the second mouse, which in this case is the trackball, and allowed the first mouse, which is the PS2 mouse, to perform left click, right-click, and other mouse events. I've used a piece of tape over the PS2 mouse's "eye" to prevent it from moving the cursor while I'm holding it.

Here's the script I have come up with:

;
;
;	MultiMice
;	Author:		[email protected] (See note below)
;	Language:	English
;	Platform:	WinXP
;	Prerequisites:
;		Michael Simon's "AutoHotkeyRemoteControlDLL" scripts and DLL's, which can be
;		Obtained from https://ahknet.autohotkey.com/~Micha/HIDsupport/Autohotkey.html
;
;	Note:	Portions of this script are taken directly from Michael Simon's
;		script "AutoHotkeyRemoteControlDLL.ahk", included in the package
;		that can be obtained at the above URL.
;	

;
; Load the RemoteControl dll and register the "Mouse" input device, which will register
; all connected mice at once, so we can begin obtaining WM_INPUT data and use it to determine
; which mouse's buttons are up and down, and what to do as a result
;

HomePath=AutohotkeyRemoteControl.dll
hModule := DllCall("LoadLibrary", "str", HomePath)  ; Avoids the need for DllCall() in 
OnMessage(0x00FF, "InputMsg")
OnExit cleanup
DetectHiddenWindows, on
Gui, Show, x0 y0 h0 w0, Autohotkey HID-Support
HWND := WinExist("Autohotkey HID-Support")
nRC := DllCall("AutohotkeyRemoteControl\RegisterDevice", INT, 2, INT, 1, INT, HWND, "Cdecl UInt")
if (errorlevel <> 0) || (nRC == -1)
{
	MsgBox RegisterDevice error. Errorcode: %errorlevel%
	goto cleanup
}
Winhide, Autohotkey HID-Support
return


;
; The InputMsg function is called anytime a mouse sends an hid WM_INPUT message (sent during button or 
; mouse movement), and is where we evaluate which mouse sent the message, which button is pressed
; or released when the message is sent, and what to do in response, if anything.
;

InputMsg(wParam, lParam, msg, hwnd)
{
;
; Each MX variable below is set to the device number as returned by the AutoHotkeyRemoteControlDLL
; script, while each MXLD (Mouse "X", Left Down, etc) variable is set to the cooresponding
; BtnFlag value that's returned when each button is pressed down or lifted up on.
;
; Be warned, the device number for these mice may change anytime you unplug/plugin an HID piece of
; hardware, or move your mice to different USB ports/etc, so you may end up editing this often if you
; screw around with your USB devices a lot.
;

M1 = 11
M1LD = 1
M1LU = 2
M1RD = 4
M1RU = 8
M1MD = 16
M1MU = 32
;M1X1D
;M1X1U
;M1X2D
;M1X2U

;M2 = 0
;M2LD
;M2LU
;M2RD
;M2RU
;M2MD
;M2MU
;M2X1D
;M2X1U
;M2X2D
;M2X2U

;M3 = 0
;M3LD
;M3LU
;M3RD
;M3RU
;M3MD
;M3MU
;M3X1D
;M3X1U
;M3X2D
;M3X2U

	nHandle := DllCall("AutohotkeyRemoteControl\GetWM_INPUTMOUSEData", UINT, wParam, UINT, lParam, "UINT *" , pusFlags, "UINT *", pusBtnFlg 
		, "UINT *" , pusBtnData, "UINT *", pulRawBtn, "UINT *" , px, "UINT *", py, "UINT *", pextraInfo, "Cdecl UInt")    
	if (errorlevel <> 0) || (nHandle == -1) 
	{
		MsgBox GetWM_INPUTHIDData error. Errorcode: %errorlevel%
		goto cleanup
	}

	DeviceNumber := DllCall("AutohotkeyRemoteControl\GetNumberFromHandle", INT, nHandle, "Cdecl Int")  
	DeviceNumber := DeviceNumber +1 ;Index 0 

;
; DeviceNumber is the mouse with the event, pusBtnFlg is the code for the button state, either pressed or released.
;
	if DeviceNumber = %M1%
		goto Mouse1Control
;	else if DeviceNumber = %M2%
;		goto Mouse2Control
;	else if DeviceNumber = %M3%
;		goto Mouse3Control
	else return

;
; Each MouseXControl section evaluates the contents of pusBtnFlg to determine which button went
; up or down, and based on that, you can have whatever event you wish occur.
;

Mouse1Control:
if pusBtnFlg = %M1LD%
{
	Click down Right
;
}
else if pusBtnFlg = %M1LU%
{
	Click up Right
;
}
else if pusBtnFlg = %M1RD%
{
	Click down
;
}
else if pusBtnFlg = %M1RU%
{
	Click up
;
}
else if pusBtnFlg = %M1MD%
{
	Click down Middle
;
}
else if pusBtnFlg = %M1MU%
{
	Click up Middle
;
}
;else if pusBtnFlg = %M1X1D%
;{
;	Click down X1
;;
;}
;else if pusBtnFlg = %M1X1U%
;{
;	Click up X1
;;
;}
;else if pusBtnFlg = %M1X2D%
;{
;	Click down X2
;;
;}
;else if pusBtnFlg = %M1X2U%
;{
;	Click up X2
;;
;}
else return

;Mouse2Control:
;if pusBtnFlg = %M2LD%
;{
;	Click down
;;
;}
;else if pusBtnFlg = %M2LU%
;{
;	Click up
;;
;}
;else if pusBtnFlg = %M2RD%
;{
;	Click down Right
;;
;}
;else if pusBtnFlg = %M2RU%
;{
;	Click up Right
;;
;}
;else if pusBtnFlg = %M2MD%
;{
;	Click down Middle
;;
;}
;else if pusBtnFlg = %M2MU%
;{
;	Click up Middle
;;
;}
;else if pusBtnFlg = %M2X1D%
;{
;	Click down X1
;;
;}
;else if pusBtnFlg = %M2X1U%
;{
;	Click up X1
;;
;}
;else if pusBtnFlg = %M2X2D%
;{
;	Click down X2
;;
;}
;else if pusBtnFlg = %M2X2U%
;{
;	Click up X2
;;
;}
;else return

;Mouse3Control:
;if pusBtnFlg = %M3LD%
;{
;	Click down
;;
;}
;else if pusBtnFlg = %M3LU%
;{
;	Click up
;;
;}
;else if pusBtnFlg = %M3RD%
;{
;	Click down Right
;;
;}
;else if pusBtnFlg = %M3RU%
;{
;	Click up Right
;;
;}
;else if pusBtnFlg = %M3MD%
;{
;	Click down Middle
;;
;}
;else if pusBtnFlg = %M3MU%
;{
;	Click up Middle
;;
;}
;else if pusBtnFlg = %M3X1D%
;{
;	Click down X1
;;
;}
;else if pusBtnFlg = %M3X1U%
;{
;	Click up X1
;;
;}
;else if pusBtnFlg = %M3X2D%
;{
;	Click down X2
;;
;}
;else if pusBtnFlg = %M3X2U%
;{
;	Click up X2
;;
;}
;else return
}

;
; Disable all buttons on all connected mice. If we don't do this, then the left button on all the mice
; will always send a left click, etc etc. Once all buttons are disabled, we use this script to simulate
; the normal operation of the mice, only we do so for each particular mouse we wish to enable it with,
; thereby giving us custom control of each mouse individually.
;
; Also, set up a keyboard shortcut that will kill the program gracefully with a {RWin} & q keyboard
; combination (Right Windows Key and "q" key at the same time).
;

>#q::
	MsgBox Application Quit!
	goto cleanup
return

LButton::return
RButton::return
MButton::return
XButton1::return
xButton2::return


cleanup:
DllCall("FreeLibrary", "UInt", hModule)  ; It is best to unload the DLL after using it (or before the script exits).
ExitApp

I did some searching on the forum looking for information on how to use multiple mice with the computer, and while I found a lot of people saying that it was possible, especially with Michael Simon's DLL, I didn't find anyone who had successfully created a script to do so. So I wrote this one, and thought I would post it here in case it helps anyone else in the future.

This is a pretty simple script, and I've only done a little bit of testing with it. But this should serve the purpose most people are looking for that want to use two or more mice at the same time. Whether you're actively going to use both mice to control the cursor, or if you simply want to use the second mouse to do specific hotkeys or shortcut functions, this script should do the trick.

If anybody spots something in it that could be improved or done in a better way, please let me know. I really don't do much programming anymore, and I've never done programming for Windows. This is probably the most complicated script I've done in years, and most of it I just stole from Michael Simon. >;)

rabbitboy
  • Guests
  • Last active:
  • Joined: --
Whoops...

Okay, it does work, but not really the way it should work. Now that I look at it, it's sending continuous mouse down/up messages when the buttons are down and dragged, which I don't think it should do. It should just send down when it goes down and up when it goes up. If there's no change in state it should just return right away.

Like I said, haven't programmed in a while. :oops:

Working on an improvement right now (and encorporating my Wacom tablet into it... remember when I said it'd disable all mice? That includes tablets...)

VxE
  • Moderators
  • 3622 posts
  • Last active: Dec 24 2015 02:21 AM
  • Joined: 07 Oct 2006
Looks fascinating...

but here's the real kicker... code a way for AHK to distinguish between two keyboards...

... then....

....you....

....will...

....be....

....a....

....GOD.


but yeah, If I had two mice hooked up I'd definately use something like this while doing 3D work by having one mouse dedicated to adjusting the camera and the other for everything else.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
A while back I tried a similar approach for keyboards, but I found that disabling the keys via the keyboard hook (hotkeys) actually prevented the HID messages from being sent. Apparently mouse input works differently. :shock:

FYI, Micha's DLL is unnecessary since you can call the Raw Input API directly from AutoHotkey. It takes a bit more figuring out, though. :)

SoLong&Thx4AllTheFish
  • Members
  • 4999 posts
  • Last active:
  • Joined: 27 May 2007
@[VxE], have you seen this?
keyboard filter
<!-- m -->http://www.autohotke...topic10416.html<!-- m -->

This is not very useful in itself, but I gave it a try to connect both a USB keyboard, and also a PS/2 keyboard to my computer. These two keyboards have different drivers. If I replace the driver for the PS/2 keyboard with the filter-driver, then whenever I press a key on that keyboard, it will always be accompanied by shift+alt (right-shift and left-alt to be more precise).

This key combination can be intercepted and modified by autohotkey, and turned into some kind of macro, eg with the following script line: "!+a::Send map_A"



rabbitboy
  • Guests
  • Last active:
  • Joined: --

...disabling the keys via the keyboard hook (hotkeys) actually prevented the HID messages from being sent. Apparently mouse input works differently.


Maybe not. I ran into that same problem... that disabling all the mouse buttons with the mouse hook (LButton1::return, etc) prevented all HID messages.

Then on nothing but a stupid hunch, I put the hotkeys that disabled the mouse buttons as nearly the last thing in the script (instead of one of the first things that happened), after all the HID reading stuff. And for whatever reason, it worked. The buttons were disabled, but the HID messages were still coming through.

Micha's DLL isn't necessary, no. But it does make things easier, and doesn't require delving deeply into the mysteries of driver messages being sent by a device. I don't really want to learn the secret codes my hardware uses... I just want it to work.

Now, in practice... I'm not sure this is really a perfect solution. I re-did my script to account for some other things, encorporated my tablet, and did some streamlining in how it determines when a button event happens. In most average situations, it's working fine. But sometimes I'm finding that something gets a hiccup, especially with my tablet. The cursor gets stuck in button down mode, and it takes some time and off-window clicking to get it to right itself. I'm betting there's a way to script it to prevent that from happening, it'll just take some time staring at my script for a while.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I ran into that same problem... that disabling all the mouse buttons with the mouse hook (LButton1::return, etc) prevented all HID messages.

Strange. I tried registering all keyboards and mice with Micha's script, then running this:
RCtrl::
LButton::
return
RCtrl could not be detected, but LButton could.

The cursor gets stuck in button down mode, and it takes some time and off-window clicking to get it to right itself.

This may help:

If a message arrives while its function is still running due to a previous arrival of the same message, the function will not be called again (except if MaxThreads is greater than 1); instead, the message will be treated as unmonitored. ... a message less than 0x312 cannot be buffered by Critical or Thread Interrupt (however, in v1.0.46+, Critical may help because it checks messages less often, which gives the function more time to finish). The only way to guarantee that no such messages are missed is to ensure the function finishes in under 6 milliseconds (though this limit can be raised via Critical 30). One way to do this is to have it queue up a future thread by posting to its own script a monitored message number higher than 0x312. That message's function should use Critical as its first line to ensure that its messages are buffered.



rabbitboy
  • Guests
  • Last active:
  • Joined: --

RCtrl could not be detected, but LButton could.


I wish I could explain it, but I just don't know enough about how the system works to really begin to guess. I haven't noticed this because I'm not trying to affect the keyboard with anything more than basic hotkeys, it's just the mice I've been concentrating on.

... The only way to guarantee that no such messages are missed is to ensure the function finishes in under 6 milliseconds (though this limit can be raised via Critical 30)...


I won't claim to understand all of that, but I do understand the less than 6 millisecond part. And I wish I'd thought of that before.

Rather than one large function to do all the work each time a message is received, use one tiny function that does nothing but listen for messages with button events on them. Then that function calls another function (maybe via a sent message higher than 0x312) that has the "Critical" keyword in it, thereby putting it in the buffer. Then that function would do the actual checking of the buttons and doing of the clicking/keying. And since the first, smaller function can be queuing all the button events it receives in a buffer, you'd end up missing very few events.

I'll have to do some script tweaking again, maybe this weekend.

Chase
  • Guests
  • Last active:
  • Joined: --
I'm interested to see if you've gained any progress here. I'm looking to use my mouse in a similar fashion. One mouse for regular control and a second as a media player remote.

So far I haven't been able to figure out how to get one mouse to work separately from another, though.

How's the functionality of this script so far? Is it usable for my purpose, or are you still running into issues with it?

Let me know.

happytodd
  • Members
  • 142 posts
  • Last active: Sep 25 2010 04:21 AM
  • Joined: 12 Nov 2007
Im sure it would be almost impossible too do. However if there was a chance wouldn't it be easier to have one PS/2 mouse and the other mouse a usb one?
Posted Image
Posted Image

darkeyez
  • Members
  • 8 posts
  • Last active: Jun 08 2011 05:15 AM
  • Joined: 03 Jun 2011

RCtrl could not be detected, but LButton could.


I wish I could explain it, but I just don't know enough about how the system works to really begin to guess. I haven't noticed this because I'm not trying to affect the keyboard with anything more than basic hotkeys, it's just the mice I've been concentrating on.

... The only way to guarantee that no such messages are missed is to ensure the function finishes in under 6 milliseconds (though this limit can be raised via Critical 30)...


I won't claim to understand all of that, but I do understand the less than 6 millisecond part. And I wish I'd thought of that before.

Rather than one large function to do all the work each time a message is received, use one tiny function that does nothing but listen for messages with button events on them. Then that function calls another function (maybe via a sent message higher than 0x312) that has the "Critical" keyword in it, thereby putting it in the buffer. Then that function would do the actual checking of the buttons and doing of the clicking/keying. And since the first, smaller function can be queuing all the button events it receives in a buffer, you'd end up missing very few events.

I'll have to do some script tweaking again, maybe this weekend.


Using your code, this is what I tried to do to remap my keyboard's integrated mouse (I.D.'d as Mouse 2 by HIDMacros).

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

;
;
;   MultiMice
;   Author:      [email protected] (See note below)
;   Language:   English
;   Platform:   WinXP
;   Prerequisites:
;      Michael Simon's "AutoHotkeyRemoteControlDLL" scripts and DLL's, which can be
;      Obtained from https://ahknet.autohotkey.com/~Micha/HIDsupport/Autohotkey.html
;
;   Note:   Portions of this script are taken directly from Michael Simon's
;      script "AutoHotkeyRemoteControlDLL.ahk", included in the package
;      that can be obtained at the above URL.
;   

;
; Load the RemoteControl dll and register the "Mouse" input device, which will register
; all connected mice at once, so we can begin obtaining WM_INPUT data and use it to determine
; which mouse's buttons are up and down, and what to do as a result
;

HomePath=AutohotkeyRemoteControl.dll
hModule := DllCall("LoadLibrary", "str", HomePath)  ; Avoids the need for DllCall() in 
OnMessage(0x00FF, "InputMsg")
OnExit cleanup
DetectHiddenWindows, on
Gui, Show, x0 y0 h0 w0, Autohotkey HID-Support
HWND := WinExist("Autohotkey HID-Support")
nRC := DllCall("AutohotkeyRemoteControl\RegisterDevice", INT, 2, INT, 1, INT, HWND, "Cdecl UInt")
if (errorlevel <> 0) || (nRC == -1)
{
   MsgBox RegisterDevice error. Errorcode: %errorlevel%
   goto cleanup
}
Winhide, Autohotkey HID-Support
return


;
; The InputMsg function is called anytime a mouse sends an hid WM_INPUT message (sent during button or 
; mouse movement), and is where we evaluate which mouse sent the message, which button is pressed
; or released when the message is sent, and what to do in response, if anything.
;

InputMsg(wParam, lParam, msg, hwnd)
{
;
; Each MX variable below is set to the device number as returned by the AutoHotkeyRemoteControlDLL
; script, while each MXLD (Mouse "X", Left Down, etc) variable is set to the cooresponding
; BtnFlag value that's returned when each button is pressed down or lifted up on.
;
; Be warned, the device number for these mice may change anytime you unplug/plugin an HID piece of
; hardware, or move your mice to different USB ports/etc, so you may end up editing this often if you
; screw around with your USB devices a lot.
;

;M1 = 11
;M1LD = 1
;M1LU = 2
;M1RD = 4
;M1RU = 8
;M1MD = 16
;M1MU = 32
;M1X1D
;M1X1U
;M1X2D
;M1X2U

M2 = 0
M2LD = 1
M2LU = 2
M2RD = 4
M2RU = 8
;M2MD
;M2MU
;M2X1D
;M2X1U
;M2X2D
;M2X2U

;M3 = 0
;M3LD
;M3LU
;M3RD
;M3RU
;M3MD
;M3MU
;M3X1D
;M3X1U
;M3X2D
;M3X2U

   nHandle := DllCall("AutohotkeyRemoteControl\GetWM_INPUTMOUSEData", UINT, wParam, UINT, lParam, "UINT *" , pusFlags, "UINT *", pusBtnFlg 
      , "UINT *" , pusBtnData, "UINT *", pulRawBtn, "UINT *" , px, "UINT *", py, "UINT *", pextraInfo, "Cdecl UInt")    
   if (errorlevel <> 0) || (nHandle == -1) 
   {
      MsgBox GetWM_INPUTHIDData error. Errorcode: %errorlevel%
      gosub cleanup
	return
   }

   DeviceNumber := DllCall("AutohotkeyRemoteControl\GetNumberFromHandle", INT, nHandle, "Cdecl Int")  
   DeviceNumber := DeviceNumber +1 ;Index 0 

;
; DeviceNumber is the mouse with the event, pusBtnFlg is the code for the button state, either pressed or released.
;
   if DeviceNumber = %M2%
      goto Mouse2Control
;   else if DeviceNumber = %M2%
;      goto Mouse2Control
;   else if DeviceNumber = %M3%
;      goto Mouse3Control
   else return

;
; Each MouseXControl section evaluates the contents of pusBtnFlg to determine which button went
; up or down, and based on that, you can have whatever event you wish occur.
;

[b]Mouse2Control:
if pusBtnFlg = %M2LD%
{
   SetKeyDelay -1

Send {"Blind"} {"LWin DownTemp"}

Return[/b]


;
}
else if pusBtnFlg = %M2LU%
{
   SetKeyDelay -1

Send {"Blind"} {"LWin Up"}

Return
;
}
else if pusBtnFlg = %M2RD%
{
   Click down Right
;
}
else if pusBtnFlg = %M2RU%
{
   Click up Right
;
}
else if pusBtnFlg = %M2MD%
{
   Click down Middle
;
}
else if pusBtnFlg = %M2MU%
{
   Click up Middle
;
}
;else if pusBtnFlg = %M1X1D%
;{
;   Click down X1
;;
;}
;else if pusBtnFlg = %M1X1U%
;{
;   Click up X1
;;
;}
;else if pusBtnFlg = %M1X2D%
;{
;   Click down X2
;;
;}
;else if pusBtnFlg = %M1X2U%
;{
;   Click up X2
;;
;}
else return

;Mouse2Control:
;if pusBtnFlg = %M2LD%
;{
;   Click down
;;
;}
;else if pusBtnFlg = %M2LU%
;{
;   Click up
;;
;}
;else if pusBtnFlg = %M2RD%
;{
;   Click down Right
;;
;}
;else if pusBtnFlg = %M2RU%
;{
;   Click up Right
;;
;}
;else if pusBtnFlg = %M2MD%
;{
;   Click down Middle
;;
;}
;else if pusBtnFlg = %M2MU%
;{
;   Click up Middle
;;
;}
;else if pusBtnFlg = %M2X1D%
;{
;   Click down X1
;;
;}
;else if pusBtnFlg = %M2X1U%
;{
;   Click up X1
;;
;}
;else if pusBtnFlg = %M2X2D%
;{
;   Click down X2
;;
;}
;else if pusBtnFlg = %M2X2U%
;{
;   Click up X2
;;
;}
;else return

;Mouse3Control:
;if pusBtnFlg = %M3LD%
;{
;   Click down
;;
;}
;else if pusBtnFlg = %M3LU%
;{
;   Click up
;;
;}
;else if pusBtnFlg = %M3RD%
;{
;   Click down Right
;;
;}
;else if pusBtnFlg = %M3RU%
;{
;   Click up Right
;;
;}
;else if pusBtnFlg = %M3MD%
;{
;   Click down Middle
;;
;}
;else if pusBtnFlg = %M3MU%
;{
;   Click up Middle
;;
;}
;else if pusBtnFlg = %M3X1D%
;{
;   Click down X1
;;
;}
;else if pusBtnFlg = %M3X1U%
;{
;   Click up X1
;;
;}
;else if pusBtnFlg = %M3X2D%
;{
;   Click down X2
;;
;}
;else if pusBtnFlg = %M3X2U%
;{
;   Click up X2
;;
;}
;else return
}

;
; Disable all buttons on all connected mice. If we don't do this, then the left button on all the mice
; will always send a left click, etc etc. Once all buttons are disabled, we use this script to simulate
; the normal operation of the mice, only we do so for each particular mouse we wish to enable it with,
; thereby giving us custom control of each mouse individually.
;
; Also, set up a keyboard shortcut that will kill the program gracefully with a {RWin} & q keyboard
; combination (Right Windows Key and "q" key at the same time).
;

>#q::
   MsgBox Application Quit!
   goto cleanup
return



cleanup:
DllCall("FreeLibrary", "UInt", hModule)  ; It is best to unload the DLL after using it (or before the script exits).
ExitApp

I wasn't really able to use "AutoHotKeyRemoteControl.dll.ahk" properly for some reason but I figured I could pull the same info from HIDMacros and AHKHID.

I really just need to remap the left mouse key in my keyboard without affecting my main mouse. It won't let me use the simple "LButton::LWin" in that space (which I'm guessing from your tutorial is where it's supposed to go) without getting an error. So I figured I had to write the code behind that function into it which I got from an error window from another AHK script that used it.

I've been through the help file and wikis and tried to put together my own codes. The ones that are accepted without an error (like the example above) just simply don't work, no affect whatsoever.

Sorry to bump up such an old forum but my original post hasn't been answered. Maybe someone would be willing to help me here where there's some context.

Thanks.