DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

Author Topic: IDEA: Long left click as Right Click  (Read 13,014 times)

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
IDEA: Long left click as Right Click
« on: February 25, 2015, 02:34 PM »
I think this may be my first request. :-)

I am trying to make an app that will allow me to long left click (time needs to be adjustable) and have it preform a right click (while the left button is still down, not when it is released). It also should only happen when the cursor is in the same place when it was first clicked (or within a pixel tolerance that should be adjustable also) so it doesn't happen while dragging.

I have created a AutoHotkey script that kind of works but not all the time and not everywhere.

Code
~LButton::
MouseGetPos, x0, y0
SetTimer, check, -500
;MsgBox %xysum%
return

check:
MouseGetPos, x, y
if (x0 = x || y0 = y)
{
	if GetKeyState("Lbutton", "P")
	{
		Click Right
		;SendEvent, {Blind}{RButton Down}
		;SendEvent, {Blind}{RButton Up}
		;SendEvent, {Blind}{LButton Up}
		return
	}
}
return

If someone could modify this script or write one that works better that would be great!!

Thank you!!
« Last Edit: February 25, 2015, 06:15 PM by c.gingerich »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #1 on: February 27, 2015, 09:28 PM »
Hmm... no one has an idea to get this to work or a better way to do it?

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #2 on: February 27, 2015, 10:33 PM »
I was going to do a quick check in AutoIt as it has some MouseEvent UDFs that let you hook into what the mouse is doing but unfortunately other things are currently getting in the way of doing anything useful  :-\

Next week I should be able to see if it can be done in AutoIt.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #3 on: March 02, 2015, 05:17 AM »
OK, see if this works, (or formats your drive or something).

LMB2R - Left Mouse Button -> Right

Two files, an executable and a ini where you can specify the time delay and pixel tolerance.

Copy the files anywhere, rename them to anything you like.  Since it uses primary and secondary mouse buttons it'll also work if you've swapped buttons in the mouse config, (ie. you're a southpaw), in which case you might want to rename it to RMB2L  ;)

LMB2R.ini
Code: (generic)
[Settings]
Time=500
Zone=5
[Windows]
Window1=CabinetWClass|Edit
Window2=IEFrame|Edit
Window3=Chrome_WidgetWin_1|Chrome_WidgetWin_1

Time = delay in milliseconds
Zone = pixel tolerance, (applies to both x and y direction - can separate that if you like)

It doesn't require the ini file to work, if the file doesn't exist it will default to values of 500ms and 5 pixels.

You can exit the program either by the tray icon menu or the hotkey Control+Alt+Shift+x, (the hotkey was purely for a "Get out of jail" in case the mouse started going weird - it can be removed when proven not necessary).

I'll post the code once I know it works :)

Addendum: Not really a bug but if you use it on a SysTray icon so that its menu opens and then LMB click on the Taskbar, you'll get the Taskbar menu.  Seems to be the only area in which this happens, I could probably get around it by area exclusion but it doesn't seem to cause any problems so I'm kind of reluctant to implement something to try to stop this behaviour.

UPDATE: v0.0.0.5
Add: Add Window/Control classname specific handling.
Add: Classnames.exe to help you get the above.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: March 05, 2015, 08:54 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #4 on: March 02, 2015, 01:43 PM »
Thanks! Going to try it in a little while.

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #5 on: March 02, 2015, 01:56 PM »
Works great apart from one thing. It doesn't work on the address bar of chrome, IE, or a windows explorer window. After I highlight text and long left click, when it does the right click, it just deselected the text. Anyway to fix that? If not, that's fine it seems to work great everywhere else!!

EDIT: Doesn't seem to work on the desktop all the time. It worked once (i think) and now does not.

Thanks!
« Last Edit: March 02, 2015, 02:57 PM by c.gingerich »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #6 on: March 02, 2015, 11:17 PM »
It doesn't work on the address bar of chrome, IE, or a windows explorer window. After I highlight text and long left click, when it does the right click, it just deselected the text. Anyway to fix that? If not, that's fine it seems to work great everywhere else!!

I have an idea about how to get around the problem, it means interrupting Windows mouse button handling completely and only passing through clicks and not holds, where that's going to be a problem is things like dragging windows around.  Unless I start putting in some form handling dependent on window class.

I'll see what kind of kludge I can mangle in - not sure how successful that'll be as they seem to use their own custom handlers for that area these days.  Pale Moon seems to work OK even though the text get deselected the primary click seems to be delayed just enough that it works.

Quote
EDIT: Doesn't seem to work on the desktop all the time. It worked once (i think) and now does not.

Interesting, I can't get it to not work on the Desktop - if I'm a little slow in drag selecting, (anywhere), I get the context menu instead.

I think this is also going to be dependent on your mouse settings in Control Panel, eg. ClickLock won't work anymore probably unless I find out some way of determining whether it's enabled or not.  Not even sure what'll happen if you have Single click to open enabled.

Maybe I should just post the code and let you figure it all out  ;) ;D
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #7 on: March 03, 2015, 01:14 PM »
Ok thanks for making it! I'll take a look and see if I can figure it out.... I am also running Stardock Fences so not sure if that would mess with it also.

EDIT: It was Fences that was causing it not to work on the desktop. Uninstalled it and it works great now.
« Last Edit: March 03, 2015, 02:28 PM by c.gingerich »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #8 on: March 03, 2015, 11:25 PM »
The more I thought about the more it would seem like you'd need to practically install another handler which would cater for all conditions, (ClickLock, other program handlers, etc) ... and my brain can't cope with that :)

However, the Chrome, IE, and Explorer should be doable by checking for the window class under the mouse at the time of clicking and subverting the normal mouse handling for the timeout period.
ie. Instead of allowing the click to happen immediately the button is pressed, delay it until the button is released for periods less than the timeout.  For periods longer than the timeout, block the primary click and send a secondary click.

You could probably make it window configurable by adding window class entries to the ini.

The current code (which includes lots of comments, something that's totally against my normal modus operandi :) ):

See above.

Archive contains everything required to build, (except MouseOnEvent UDF) - download from here MouseOnEvent UDF.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: March 05, 2015, 08:58 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #9 on: March 04, 2015, 04:19 PM »
Cool thanks a lot for the help and code! I'll be taking a look to see if I can tweak it a a bit, but works great for the most part.

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #10 on: March 05, 2015, 06:53 AM »
I've fiddled with the code a bit and I've got it working for IE, Explorer and Dragon, (Comodo' version of Chrome - so it should work with Chrome).

Basically, I did what I mentioned above - if the window and control classes match an entry in the ini file on a PMB down action, the default processing is blocked.

If the PMB up action occurs within the timeout period, then a MouseClick("primary") is sent.  If a timeout occurs before a PMB up happens, then a MouseClick("secondary") is sent.

Code: (autoit)
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=favicon.ico
#AutoIt3Wrapper_Res_Description=Causes a Secondary Mouse Button click when Primary Mouse Button is held down for a predetermined time
#AutoIt3Wrapper_Res_Fileversion=0.0.0.5
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=Nobody
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#cs ----------------------------------------------------------------------------
	Uses MouseOnEvent UDF by MrCreatoR
	http://www.autoitscript.com/forum/topic/64738-mouseonevent-udf/

	Icon by Martin Berube (http://www.how-to-draw-funny-cartoons.com/)
	http://www.iconarchive.com/show/animal-icons-by-martin-berube/mouse-icon.html

	LMB2R - Causes a SMB click after holding down the PMB for a secified time.

	In comments: PMB = Primary Mouse Button
	SMB = Secondary Mouse Button
#ce ----------------------------------------------------------------------------

#include <WinAPI.au3>
#include <Array.au3>
#include "MouseOnEvent.au3" ; MouseOnEvent UDF

HotKeySet("^+!x", "_Exit") ; Emergency Exit hotkey (Ctrl+Alt+Shift+x)
OnAutoItExitRegister(_Exit) ; Call the _Exit routine when the program is terminated somehow

; Set up the tray menu
Opt("TrayMenuMode", 3)
Opt("TrayOnEventMode", 1)
TrayCreateItem('Exit', -1, -1, 0)
TrayItemSetOnEvent(-1, '_Exit')
TraySetToolTip(StringLeft(@ScriptName, StringLen(@ScriptName) - 4))

; Set the .ini filename
$sIniFile = StringLeft(@ScriptFullPath, StringLen(@ScriptFullPath) - 3) & "ini"
; Time PMB should be held down before interpreting as a SMB click (milliseconds)
Global $iTime = IniRead($sIniFile, "Settings", "Time", "500")
; Max distance mouse can move while waiting for the above (pixels)
Global $iZone = IniRead($sIniFile, "Settings", "Zone", "5")
; List of Window Classes to delay PMB action on
Global $aWinClass = IniReadSection($sIniFile, "Windows")

Global $aMpos, $iStart = 0, $bBlocked = False

; Hook into the PMB events
_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_PrimaryDown")
_MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT, "_PrimaryUp")

While 1 ; Thumb twiddling loop
	Sleep(10)
	; If the PMB was pressed, check to see how long for
	If $iStart > 0 And TimerDiff($iStart) >= $iTime Then
		$aDeltaMPos = MouseGetPos()
		; Check to see if mouse has moved outside defined limit
		If Abs($aDeltaMPos[1] - $aMpos[1]) <= $iZone And _
				Abs($aDeltaMPos[0] - $aMpos[0]) <= $iZone Then
			; All OK then do a SMB click and reset the timer
			MouseClick("secondary")
			$iStart = 0
			; Clear flag, (from cancelled PMB), so that if we cancel context menu by
			; clicking elsewhere we don't get something weird happening from extra PMB click
			$bBlocked = False
		Else
			; Mouse moved too far so just reset the timer
			$iStart = 0
		EndIf
	EndIf
WEnd

Func _Exit()
	; Release the event hooks and Exit
	_MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
	_MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT)
	Exit
EndFunc   ;==>_Exit

Func _PrimaryDown() ; PMB pressed
	$aMpos = MouseGetPos() ; Get current mouse position
	$iStart = TimerInit() ; Initialise the timer
	Local $tPoint = _WinAPI_GetMousePos() ; Pointers to mouse position
	Local $hWnd = _WinAPI_WindowFromPoint($tPoint) ; Get handle of control under mouse using coords
	Local $ClassName = _WinAPI_GetClassName($hWnd) ; Get Control classname
	Local $hParent = _WinAPI_GetAncestor($hWnd, $GA_ROOT) ; Get handle of the root window for the control
	Local $sParent = _WinAPI_GetClassName($hParent) ; Get root window classname

	; Search in array for matching window classname
	Local $iIndex = _ArraySearch($aWinClass, $sParent, 1, 0, 0, 1, 1, 1)
	Switch $iIndex
		Case 0, -1 ; No matching Window class found
			Return 0 ; Do not Block the default processing
		Case Else ; Matching Window class found
			; Search in string for matching control classname
			Local $temp = StringInStr($aWinClass[$iIndex][1], "|" & $ClassName)
			Switch $temp
				Case 0, -1 ; No matching Control class found
					Return 0 ; Do not Block the default processing
				Case Else ; Matching Control class found
					$bBlocked = True ; Set a flag for when the button is released
					Return 1 ; Block the default processing
			EndSwitch
	EndSwitch
EndFunc   ;==>_PrimaryDown

Func _PrimaryUp() ; PMB released
	; If the timer is less than the timeout reset it otherwise it accumulates
	; If it's longer than the timeout the Thumb Twiddling Loop will take care of it
	If TimerDiff($iStart) < $iTime Then
		$iStart = 0
		If $bBlocked Then ; If PMB down was previously blocked, send PMB and clear flag
			MouseClick("primary")
			$bBlocked = False
		EndIf
	EndIf
	Return 0 ; Do not Block the default processing
EndFunc   ;==>_PrimaryUp

.ini now contains Window and Control classnames for recalcitrant windows.

Code: (generic)
[Settings]
Time=500
Zone=5
[Windows]
Window1=CabinetWClass|Edit
Window2=IEFrame|Edit
Window3=Chrome_WidgetWin_1|Chrome_WidgetWin_1

For any other windows just add a line:
Window(x)=<window classname>|<control classname>       where (x) is the next number in the sequence (it actually doesn't matter what the key name is as only the value is used).

To help you get the Window & Control classname there's a small program called Classnames.exe, (source included), that will display the classname of the Window & Control class under the pointer, eg.

2015-03-05 19_44_02.jpg

Exit it using the tray menu.

Modified my original post above.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903
« Last Edit: March 05, 2015, 09:03 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • Participated in NANY Challenge Six Times
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #11 on: March 05, 2015, 01:46 PM »
EDIT: Well, after using it for a bit, it seems to stop working after a little. I have to close and re-open it for it to work again. Any ideas as to why?


Very cool!! Works great!!  :Thmbsup:

Thanks so much!
« Last Edit: March 05, 2015, 02:10 PM by c.gingerich »

4wd

  • Pedantic Old Bastard
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,652
    • Coding Snacks
Re: IDEA: Long left click as Right Click
« Reply #12 on: March 05, 2015, 11:03 PM »
EDIT: Well, after using it for a bit, it seems to stop working after a little. I have to close and re-open it for it to work again. Any ideas as to why?

Not really, TBH the blocking of the mouse event over specific controls is probably a bit of a hack so I'm not sure what the long term effects of doing it might be.

Do you have more info regarding this, eg. mainly working in which windows before it stops, etc. ?

The previous version without the Window/Control class workaround seemed to go quite well when I was testing just using Pale Moon, Desktop, & DOpus but it's a bit hard to test every combination.
"I will not follow where the path may lead, but I will go where there is no path, and I will leave a trail." - Muriel Strode, 1903

Original address: https://www.donationcoder.com/forum/index.php?topic=40286.0