I'm new to ffi.
Basically I'm trying to get a bool when the mouse left button is clicked.
I've done some research and found something called WM_LBUTTONDOWN
However I don't know how to put it in ffi.cdef then getting a bool.
This program polls the mouse button state once per 1 ms and exits when LMB is pressed
local ffi = require("ffi")
ffi.cdef[[
short GetAsyncKeyState(int vKey);
void Sleep(int ms);
]]
local function is_key_down(vKey)
return ffi.C.GetAsyncKeyState(vKey) < 0
end
local function sleep(ms)
ffi.C.Sleep(ms or 1)
end
local VK_LBUTTON = 0x01 -- Left mouse button
local VK_RBUTTON = 0x02 -- Right mouse button
local VK_MBUTTON = 0x04 -- Middle mouse button
local VK_XBUTTON1 = 0x05 -- X1 mouse button (Back)
local VK_XBUTTON2 = 0x06 -- X2 mouse button (Forward)
sleep(1000)
print"Waiting for Left Mouse Button pressed"
repeat
sleep()
until is_key_down(VK_LBUTTON)
print"Left Mouse Button is down now"
If you want to handle WM_LBUTTONDOWN message that would be a more complex solution.
Related
This is more of algorithms question. I have 3 buttons:
button1 button2 button3
They can each be in clicked or not-clicked state. When the first is clicked, it goes into clicked state, but if I click it again, it goes back into non-clicked state.
I want to keep a global variable that answers if ANY of the buttons is clicked.
Knowing when to set global variable to clicked is pretty easy:
When I click button1 I can set variable clicked to true.
When I click button2 I can set variable clicked to true.
When I click button3 I can set variable clicked to true.
Now the difficult part is to set global variable to non-clicked:
When I click button1 again it becomes non-clicked, but button2 or button3 can be still clicked, so I can't just set variable to non-clicked.
When I click button2 again it becomes non-clicked, but button1 or button3 can be still clicked, so I can't just set variable to non-clicked.
When I click button3 again it becomes non-clicked, but button1 or button2 can be still clicked, so I can't just set variable to non-clicked.
It's difficult to keep state of non-clicked global status of all buttons.
Any ideas how to solve this problem? Should I somehow use xor? Or some other logical operation?
Set and clear a different bit in the word per button. That way if the word is non-zero, one or more of the buttons is pressed, and you can detect which one(s) by examining the bits.
Hard to see the point.
I figured out answer to my own question.
The answer is to keep global variable with value 0 in it:
int button_counter = 0;
When any button is clicked the following operation is performed:
button_counter = button_counter + 1;
When any button is unclicked the following operation is performed:
button_counter = button_counter - 1;
Now if value of button_counter is 0, then all buttons are unclicked.
If value of button_counter is 1, 2 or 3, then either one, two or three buttons are clicked and they are not all unclicked.
Here's how to check if they're all unclicked:
if (button_counter == 0) {
// all buttons are unclicked
}
else {
// at least 1 button is clicked
}
Thank you all for help!
I want to handle action double click by clicking left_mouse 2 times.Between 2 click-time,I sleep 100ms
SendInput(LEFT_CLICK...); Sleep(100); SendInput(LEFT_CLICK...);
It works OK in my PC,but not works correctly in virtual machine
May be,There is a delay-time when machine do function "SendInput"Eventhough I remove "Sleep(100)",It just clicks 2 times and doesn't "double click" as I want.
How to handle double click exactly in this case
Please suggest me anyway to do it
Thanks,
Btw you should specify what environment you're working in and make your code a bit more detailed. Using SendInput is one option, I don't know what you're trying to do exactly, but I'll give you two more options to try for simulating clicks. Something like this would works fine (I code in python but it should be the same idea):
def leftClick(x=0, y=0):
win32api.SetCursorPos((x,y)) #set the cursor to where you wanna click
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0) #generate a mouse event
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
return True
def doubleClick(x=0, y=0):
leftClick(x,y)
leftClick(x,y)
You could sleep for 50 ms in between time.sleep(0.05) but it works for me without it and I've tested in a vm.
Another option if you want to perform silent clicks without having to move the cursor, you can send a message to the window where you want to click knowing the window handle (hwnd), here I assume you pass the handle as a parameter.
def leftClick(x=0, y=0, hwnd):
lParam = win32api.MAKELONG(x,y) # create a c long type to hold your click coordinates
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lparam) # send a message to the window that the mouse left button is down.
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0, lparam) # send a message to the window that the mouse left button is up.
return True
def doubleClick(x=0, y=0, hwnd):
leftClick(x,y, hwnd)
leftClick(x,y, hwnd)
or you can send the message WM_LBUTTONDBLCLK up to you.
I'm trying to create a Hotkey (Win+Shift+Q) that toggles on/off another Hotkey that changes the right Alt key to a left mouse click; however, I can't get it to work.
Expected Behavior:
Pressing Windows+Shift+Q will initially toggle the Right-Alt key to act as a left mouse click.
Pressing Windows+Shift+Q again will toggle the Right-Alt key back to acting as a Right-Alt key.
Pressing Windows+Shift+Q again will revert to the left-click behavior (see #1). And so on.
Here's the most current iteration of my code:
Hotkey, RAlt, MyClick, On
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
switch := !switch
MsgBox %switch%
Hotkey RAlt, % (switch ? "Off": "On")
Return
MyClick:
MouseClick
Return
When I run my script I get the following error after clicking OK on the MsgBox and the script quits:
Error: Nonexistent hotkey
Specifically: RAlt
Line#
141: Hotkey,RAlt,MyClick,On
143: switch:=!switch
144: MsgBox %switch%
-->145: Hotkey RAlt, % (switch ? "Off": "On")
146: Return
149: MouseClick
150: Return
The current thread will exit.
Most of the other posts that might relate (Can AutoHotKey toggle keymapping?, Autohotkey: Toggle a set of keybinds on and off) only deal with key to key mapping and not key to mouse mapping. I can't tell if that is the cause of my issues or not.
Previously I had this, but the Win+Shift+Q didn't toggle the behavior, RAlt always acted as a left-click so I commented it out:
#+Q:: ;Win+Shift+Q :: ::Right-Alt acts as a left mouse button click
RAlt::LButton
;Hotkey, RAlt, Toggle ;Does not work for some reason
int += 1
test := mod(int, 2) = 0
if (test) {
msgbox on
Hotkey, RAlt, On
}
else {
msgbox off
Hotkey, leftClick, Off
}
Return
I'll also add that I would like this behavior across Windows, not just a single application (which also seems to be a topic in other posts that allows for the #IfWinActive-type suggestions/solutions).
I tried your current iteration of code in AutoHotkey v1.1.13.01 Unicode 32-bit and I don't have any errors after pressing OK on the message box, the script works as advertised.
Try updating your AutoHotkey version here: http://ahkscript.org/download/ and see if the problem persists.
bState:=False
#If bState
RAlt::Click
#If
#+vk51:: ; win + shift + q
KeyWait, vk51
TrayTip, % "state of switch", % (bState:=!bState) ? "on":"off"
Return
Basically I have an issue where the middle mouse button when clicked does multiple very fast middle mouses. For example, if I open a link in a new tab with middle mouse it will open about 10 of that tab. I have tried all of the conventional methods to fix it, ie. driver fixes etc. What I want to try now is a bit of mouse debouncing with AHK (Auto Hot Key) for windows.
Essentially what I am thinking is to do this:
while (forever)
if( capture the middle mouse)
sleep 500 ms
mouse click
end
end
Can anyone give some advice with this approach?
Alternatively i thought about making a middle mouse hotkey:
$MButton::
Loop
{
sleep 500
if not GetKeyState("MButton", "P")
break ; Break out of the loop.
}
send {MButton}
return
Can anyone see any problems with this?
You can have a much simpler solution without a delay.
This will ignore middle click if the last click was 50 ms ago.
#Persistent
global pressed_g := 0
global delay_g := 50 ; delay in miliseconds, increase this value if your multiple click take longer than delay_g time
return
MButton::
if( pressed_g = 0 )
{
Send, {MButton}
tooltip,sent
pressed_g := 1
}
SetTimer, Countdown , Off
SetTimer, Countdown , -%delay_g%
return
Countdown:
pressed_g := 0
return
Could it be that you are looking for this? You press the MButton and while you keep the MButton pressed, the script will continue to fire MButton.
#Persistent
MButton::
while GetKeyState("MButton", "P") ; While the Middle Mouse button key is being held down
{
Send, {MButton}
}
return
I currently have an AHK script which switches the scrolling direction of my mouse.
WheelUp::
Send {WheelDown}
Return
WheelDown::
Send {WheelUp}
Return
My colleagues don't like this and use my computer sometimes.
How can I assign a shortkey to switch the scrolling direction?
What I want:
When I press win+z the scrolling direction is changed, when I pres win+z again, the scrolling direction is changed back.
So basically the scrolling direction can be changed when pressing win+z
Is that possible with AHK?
Yes you can modify your hotkeys to have more code.
You will have to use if statements and variables.
Example:
global direction := 1
^s:: ; ctrl + s will launch this code you can modify this to win + z
direction := Mod( direction + 1 , 2 ) ; alternates values of direction between 1 and 0
return
WheelUp::
if(direction)
Send {WheelDown}
else
Send {WheelUp}
Return
; and reverse for wheeldown