topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday March 28, 2024, 3:08 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: IDEA: Long left click as Right Click  (Read 9378 times)

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
IDEA: Long left click as Right Click
« on: February 25, 2015, 08:34 AM »
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.

~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, 12:15 PM by c.gingerich »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #1 on: February 27, 2015, 03:28 PM »
Hmm... no one has an idea to get this to work or a better way to do it?

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #2 on: February 27, 2015, 04: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.

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #3 on: March 01, 2015, 11:17 PM »
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: Text [Select]
  1. [Settings]
  2. Time=500
  3. Zone=5
  4. [Windows]
  5. Window1=CabinetWClass|Edit
  6. Window2=IEFrame|Edit
  7. 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.
« Last Edit: March 05, 2015, 02:54 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #4 on: March 02, 2015, 07:43 AM »
Thanks! Going to try it in a little while.

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #5 on: March 02, 2015, 07:56 AM »
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, 08:57 AM by c.gingerich »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #6 on: March 02, 2015, 05: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.

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

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #7 on: March 03, 2015, 07:14 AM »
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, 08:28 AM by c.gingerich »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #8 on: March 03, 2015, 05: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.
« Last Edit: March 05, 2015, 02:58 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #9 on: March 04, 2015, 10:19 AM »
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

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #10 on: March 05, 2015, 12: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 [Select]
  1. #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
  2. #AutoIt3Wrapper_Icon=favicon.ico
  3. #AutoIt3Wrapper_Res_Description=Causes a Secondary Mouse Button click when Primary Mouse Button is held down for a predetermined time
  4. #AutoIt3Wrapper_Res_Fileversion=0.0.0.5
  5. #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
  6. #AutoIt3Wrapper_Res_LegalCopyright=Nobody
  7. #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
  8. #cs ----------------------------------------------------------------------------
  9.         Uses MouseOnEvent UDF by MrCreatoR
  10.         http://www.autoitscript.com/forum/topic/64738-mouseonevent-udf/
  11.  
  12.         Icon by Martin Berube (http://www.how-to-draw-funny-cartoons.com/)
  13.         http://www.iconarchive.com/show/animal-icons-by-martin-berube/mouse-icon.html
  14.  
  15.         LMB2R - Causes a SMB click after holding down the PMB for a secified time.
  16.  
  17.         In comments: PMB = Primary Mouse Button
  18.         SMB = Secondary Mouse Button
  19. #ce ----------------------------------------------------------------------------
  20.  
  21. #include <WinAPI.au3>
  22. #include <Array.au3>
  23. #include "MouseOnEvent.au3" ; MouseOnEvent UDF
  24.  
  25. HotKeySet("^+!x", "_Exit") ; Emergency Exit hotkey (Ctrl+Alt+Shift+x)
  26. OnAutoItExitRegister(_Exit) ; Call the _Exit routine when the program is terminated somehow
  27.  
  28. ; Set up the tray menu
  29. Opt("TrayMenuMode", 3)
  30. Opt("TrayOnEventMode", 1)
  31. TrayCreateItem('Exit', -1, -1, 0)
  32. TrayItemSetOnEvent(-1, '_Exit')
  33.  
  34. ; Set the .ini filename
  35. ; Time PMB should be held down before interpreting as a SMB click (milliseconds)
  36. Global $iTime = IniRead($sIniFile, "Settings", "Time", "500")
  37. ; Max distance mouse can move while waiting for the above (pixels)
  38. Global $iZone = IniRead($sIniFile, "Settings", "Zone", "5")
  39. ; List of Window Classes to delay PMB action on
  40. Global $aWinClass = IniReadSection($sIniFile, "Windows")
  41.  
  42. Global $aMpos, $iStart = 0, $bBlocked = False
  43.  
  44. ; Hook into the PMB events
  45. _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "_PrimaryDown")
  46. _MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT, "_PrimaryUp")
  47.  
  48. While 1 ; Thumb twiddling loop
  49.         Sleep(10)
  50.         ; If the PMB was pressed, check to see how long for
  51.         If $iStart > 0 And TimerDiff($iStart) >= $iTime Then
  52.                 $aDeltaMPos = MouseGetPos()
  53.                 ; Check to see if mouse has moved outside defined limit
  54.                 If Abs($aDeltaMPos[1] - $aMpos[1]) <= $iZone And _
  55.                                 Abs($aDeltaMPos[0] - $aMpos[0]) <= $iZone Then
  56.                         ; All OK then do a SMB click and reset the timer
  57.                         MouseClick("secondary")
  58.                         $iStart = 0
  59.                         ; Clear flag, (from cancelled PMB), so that if we cancel context menu by
  60.                         ; clicking elsewhere we don't get something weird happening from extra PMB click
  61.                         $bBlocked = False
  62.                 Else
  63.                         ; Mouse moved too far so just reset the timer
  64.                         $iStart = 0
  65.                 EndIf
  66.         EndIf
  67.  
  68. Func _Exit()
  69.         ; Release the event hooks and Exit
  70.         _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT)
  71.         _MouseSetOnEvent($MOUSE_PRIMARYUP_EVENT)
  72.         Exit
  73. EndFunc   ;==>_Exit
  74.  
  75. Func _PrimaryDown() ; PMB pressed
  76.         $aMpos = MouseGetPos() ; Get current mouse position
  77.         $iStart = TimerInit() ; Initialise the timer
  78.         Local $tPoint = _WinAPI_GetMousePos() ; Pointers to mouse position
  79.         Local $hWnd = _WinAPI_WindowFromPoint($tPoint) ; Get handle of control under mouse using coords
  80.         Local $ClassName = _WinAPI_GetClassName($hWnd) ; Get Control classname
  81.         Local $hParent = _WinAPI_GetAncestor($hWnd, $GA_ROOT) ; Get handle of the root window for the control
  82.         Local $sParent = _WinAPI_GetClassName($hParent) ; Get root window classname
  83.  
  84.         ; Search in array for matching window classname
  85.         Local $iIndex = _ArraySearch($aWinClass, $sParent, 1, 0, 0, 1, 1, 1)
  86.         Switch $iIndex
  87.                 Case 0, -1 ; No matching Window class found
  88.                         Return 0 ; Do not Block the default processing
  89.                 Case Else ; Matching Window class found
  90.                         ; Search in string for matching control classname
  91.                         Local $temp = StringInStr($aWinClass[$iIndex][1], "|" & $ClassName)
  92.                         Switch $temp
  93.                                 Case 0, -1 ; No matching Control class found
  94.                                         Return 0 ; Do not Block the default processing
  95.                                 Case Else ; Matching Control class found
  96.                                         $bBlocked = True ; Set a flag for when the button is released
  97.                                         Return 1 ; Block the default processing
  98.                         EndSwitch
  99.         EndSwitch
  100. EndFunc   ;==>_PrimaryDown
  101.  
  102. Func _PrimaryUp() ; PMB released
  103.         ; If the timer is less than the timeout reset it otherwise it accumulates
  104.         ; If it's longer than the timeout the Thumb Twiddling Loop will take care of it
  105.         If TimerDiff($iStart) < $iTime Then
  106.                 $iStart = 0
  107.                 If $bBlocked Then ; If PMB down was previously blocked, send PMB and clear flag
  108.                         MouseClick("primary")
  109.                         $bBlocked = False
  110.                 EndIf
  111.         EndIf
  112.         Return 0 ; Do not Block the default processing
  113. EndFunc   ;==>_PrimaryUp

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

Code: Text [Select]
  1. [Settings]
  2. Time=500
  3. Zone=5
  4. [Windows]
  5. Window1=CabinetWClass|Edit
  6. Window2=IEFrame|Edit
  7. 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.
« Last Edit: March 05, 2015, 03:03 AM by 4wd »

c.gingerich

  • Supporting Member
  • Joined in 2011
  • **
  • Posts: 748
    • View Profile
    • The Blind House
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #11 on: March 05, 2015, 07:46 AM »
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, 08:10 AM by c.gingerich »

4wd

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 5,641
    • View Profile
    • Donate to Member
Re: IDEA: Long left click as Right Click
« Reply #12 on: March 05, 2015, 05: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.