How to get notified of mouse/keyboard activity without a global hook? - c++

I have a transparent window (WS_EX_TRANSPARENT) floating topmost.
Whenever there is a mouse move (anywhere on the screen) or keyboard stroke, it needs to display the related info (e.g. mouse position).
Is it possible to capture mouse/keyboard activities without using a global hook? Anti-virus software almost always triggers false alarms for the use of global
hooks.
Any idea greatly appreciated.

I guess, GetAsyncKeyState and GetCursorPos might help. You probably can have a thread calling these functions every 300-500 msec, and posting a message to your main thread.

You could register for receiving raw input messages via RegisterRawInputDevices. Have a look over here, there are some links in the accepted answer of RRUZ, one points to a C# implementation. This works with window messages, no hooks involved.
(With this method you also get information about the specific device the input came from, so you could distinguish between multiple keyboards. That's where most questions having "use RegisterRawInputDevices" as answer are heading. But you can also use it to just capture the input, not caring about the source.)

You can get notified of keyboard/mouse activity (GetLastInputInfo), and I am fairly certain you can get the cursor position (GetMouseMovePointsEx). If you do not need the actual keyboard strokes, then that should do it. If you do, I do not think it can be done...

LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
UInt32 lastInputTick = lastInputInfo.dwTime;
return Environment.TickCount - (Int32)lastInputInfo.dwTime
This code (C#) return the inactivity time (keyboard and mouse both). So you can have the time since the user is inactive.

Related

Missing mouse movement messages in Win32

I'm writing a Win32 OpenGL application for painting where it is critical that all mouse movement is handled. As it happens, sometimes the painting operation in my program is not able to perform in real time -- which is fine for me, as long as all mouse events are queued and can be handled later. Now I would have thought that this would simply be a matter of calling PeekMessage making sure to process all events, but when I do this, it is apparent that the mouse movements my application receives are not of the same fidelity that as those being displayed by Windows.
Is this a feature of Windows? Are mouse event dropped when the application is labor intensive? Or am I missing something? In either case, what can I do to remedy this situation? I would like to avoid multi-threading, part of the reason being that, as I understand, Win32 requires the message callback to be in the main thread and I'm not sure about separating the OpenGL-stuff to a different context.
And as for code example, I am essentially using the template code in the link below. The message I'm checking for is WM_MOUSEMOVE.
http://nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/13001/
Is this a feature of Windows? Are mouse event dropped when the application is labor intensive?
Yes, this is a feature. WM_MOUSEMOVE messages are not dropped, they are synthesized. In other words, they are not actually posted to the message queue. That wouldn't work very well in practice, a user could generate a great many mouse moves in a second and rapidly fill the message queue to capacity when your program is busy.
You get a WM_MOUSEMOVE message when the mouse was moved since the last time you called GetMessage(). And you get the last known position. So the rate at which you get them, and the number of pixels between them, depend directly on how often you call GetMessage().
An alternative is to use raw input.
WM_MOUSEMOVE is special in that it isn't queued; it's automatically generated as needed when the message queue is empty. (WM_PAINT and WM_TIMER behave the same way.)
Raymond Chen suggests using GetMouseMovePointsEx if you need additional mouse input data.
Additional reading:
Why do I get spurious WM_MOUSEMOVE messages?
Paint messages will come in as fast as you let them

how to find where a mouse event come from?

Is there any way to figure out where did a mouse event come from?
I mean, if I code a C/C++ program on Windows, and get a mouse click event on it, how can I find if this event come from a mouse driver, a touchpad, or if it was send by an application (mouse event simulation by sending appropriate message like WM_LBUTTONDOWN).
Thanks for any help :)
This is not possible for an application in user mode - mouse events generally don't provide documented info on event source. There is the way to obtain some message extra info by Win32 API function GetMessageExtraInfo but there is no safe way to interpret this data. It is very device specific, undocumented and never guaranteed to ever present.
To solve this task you need to develop your own Mouse Filter driver basing on Windows DDK sample.
Its callback has input parameter MOUSE_INPUT_DATA - structure containing mouse event info. There is the field UnitId:
UnitId Specifies the unit number of the mouse device. A mouse device name has the format \Device\PointerPortN, where the suffix N is the unit number of the device. For example, a device, whose name is \Device\PointerPort0, has a unit number of zero, and a device, whose name is \Device\PointerPort1, has a unit number of one.
GetAsyncKeyState function can be used to check if the button was pressed, and unfortunately SendInput cannot trick this function.
So you can simulate a mouse click, but the program can check if the button was really pressed.
So creating your own mouse driver is better.
I needed a safe way so simulate mouse/keyboard behavior for my bot, and I wrote a detailled article on my blog http://poker-botting.blogspot.fr/2012/11/how-to-simulate-mouse-and-keyboard.html

How to detect if mouse click is legit or automated?

How to know if a mouse click is simulated or not? When mouse click send by a program or real mouse device
... I'm programming a system detection for a game to avoid bots, autoclicks,etc that only accept legit mouse clicks
This depends a bit on the kind of application you are writing, but if you can, I would watch the cursor movement, not the clicks.
Human mouse movement has non-uniform speeds, reaction times, imprecisions (clicks on different coordinates of your buttons, etc...).
Also, you can defend a gui against bots by randomly requiring an interaction that is hard to script. For example: If scripts depend upon buttons being always in the same position, I would make sure that, while trying to remain intuitive, the dialog should pop up in slightly different positions every time.
Otherwise: There is no way to detect if the mouse is a real one or a really well simulated one. The Windows HID/MacOS/Linux driver layer abstracts away the distinction between Mice, TrackPens, TrackBalls, draw-pads, touch screens... and of course script-mice...
Although the blog post itself is about a different issue, I refer you to Raymond Chen's excellent Old New Thing. In this specific blog post he talks about the validity of message parameters going into an application, but also makes the point that:
There's no point discussing the possibility that the sender of the message is playing tricks and lying to you because (1) your program should just go along with the ruse and respond to fake menu messages as if they were real menu messages, because (2) there's no way to tell that you're being lied to anyway. To detect lying, you'd have to be able to read into the mindset of the programmer who sent you the message.
Essentially the argument is that you should respond to mouse clicks as mouse clicks, regardless of how those clicks were generated.
Is mouse keys simulated mouse input or legit? The point of simulating mouse input is to make them look exactly like real mouse input. If the simulation is doing its job, then your job is impossible. Sorry, that's the blessing & curse of software for you. Here are some more imperfect ideas:
Use GetKeyboardState and verify that the button states are correct. If the message faker is using PostMessage, they will likely not be setting keyboard state and this would indicate fakery.
If you are targeting known applications that are doing the input simulation, detect them and complain. This is not perfect at all for many reasons.
Fuzzy logic, as many other people have suggested.
You need to be creative and figure out the difference between a simulated event and a real one to you, as there is no generalized answer.
It can't be done (reliably (with software alone anyway))
I've used WIN32API calls to read pixels/manipulate the mouse/send keystrokes to automate large portions of video games and other repetitive tasks. You could write a lot of code to analyze the input, but equally smart developers are just going to modify their code to match.
When I first try to automate a mouse click, that's all I'll do. Send a mouse click. And most of the time it works. You might have code that tracks the mouse movement and the entire stack of mouse events that would fire along with a legitimate click and say, 'That wasn't real - we ignore it' but nothing stops the developer from also implementing mouse movements.
The mouse events are more complex than keypresses; but it's essentially the same idea. If you write code that monitors the time between keypresses and determine that I'm sending the '2' key to your application in EXACTLY 250ms intervals, you might decide I'm a bot. But, all I'll do is modify my code to send the keystroke in 250ms + a random value between -25 and 25 ms.
It's a never-ending game of cat and mouse. The best solution is to make tasks non-trivial so simple forms of automation aren't applicable.
The question is a bit thin on details.
Events can be sent directly to controls without moving the mouse so find out where the mouse is when you get the click event and see if it's on the control. Keyboard input requires control focus, so check that too.
For situations where the mouse moves, you won't be able to tell if the mouse movement is recorded and played back. If its scripted then perhaps you could monitor the mouse behavior in the parent panel(s) of the control and use those events and movements to ascertain whether it is real or not. An automated click might appear from nowhere and cause an flurry of unlikely hover, focus events.
Only way it would be possible is with some specialist hardware and software on the mouse itself that sends evidence of the actual mechanical click. Via software this is not possible.
Although in my other answer I mention that you should ideally just respond to clicks as clicks, there is one possibility that could work, depending on how a "programmatic" click is generated.
I am assuming a Windows platform, due to the "vb.net" tag:
With the WinAPI you can send a message to any window in order to simulate, for example, a WM_LBUTTONDOWN event. In this message you would include the X and Y location of the mouse at the time the button was pressed - or where the receiving program expects it to be. When you handle the message you could use the GetCursorPos call to get the actual cursor position. Verify that the current position is close to that in the message, and handle it as a click, otherwise ignore it.
Bear in mind however that the nature of the message queue is such that it could take some time to handle the event, and the mouse can move a long way in a short space of time.
This solution would only work if the "click" is generated by a simple Send/PostMessage. If the application that is generating the click simulates the movement of the mouse also, then you should probably see the other answers :)
You can check the mouse event flags LLMHF_INJECTED and LLMHF_LOWER_IL_INJECTED or utilize input hooks to monitor mouse input data, where malformed data may indicated that input was injected.
https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msllhookstruct
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
I'm not sure there is a way to determine with perfect accuracy whether a mouse click is automated or not. I mean, you could write your own USB driver that sits in between the native mouse driver and the OS and relays only "real" clicks to you. However, even that can be defeated by plugging in a USB device (like a smartphone) that's programmed to send USB packets to host computer.
What are you trying to accomplish that requires you to distinguish between real mouse clicks and fake ones?
Create a statistical learning solution by logging the past X mouse events in your program. When the user clicks on the control, determine the probability based on the last X actions that it's a real click.
Train your solution using real clicks and a large variety of automated scenarios.
This is obviously not a guaranteed-to-work solution and is more for fun than anything else.
It is much more harder than what you think because input macro programs produce legit mouse and keyboard input messages to your game. I don't think there is a way to check if the input message is actually triggered by a physical hardware input (like mouse or keyboard) unless OS provides you with accessibility of input-driver-level.
Since this is specifically for a game, you can see how other games handle this situation. Some of the common methods are,
Check frequency of mouse clicks. (human beings cannot click as fast as programs.)
At random points or when it doubts, use CAPTCHA to verify. (Read this: http://www.threadmeters.com/v-1Vvd/CAPTCHA_The_Obvious_AntiBot_Solution/ )
Use outside monitoring tools to inspect all processes running in a machine to find out programs known for cheating purpose. Steam does this. Check Valve Anti-Cheat System Blizzard's WoW also does the same thing with Warden.
My own advice would be "Use your gameplay system". Since every game has its own rules and gameplay styles, it wouldn't be too hard to detect whether a player is cheating or not. This approach won't be a general solution and it could be silly but if it works for your game, why not? :)
There are two ways you could work around this problem.
Make a new Button with a Text proving that the user isn't AFK and if the user doesn't press the button, kick him or her out. Generate the button in random locations.
If the user isn't moving for a while, (for example, 10 mins) kick him or her out.

Change speed of keystroke C++

Basically, when one types, a keydown event happens. If the key is held for more than a certain time (~1 sec) then the key is repeatedly pressed until keyup hapens. I would like to change the time it takes for the key to be automatically repressed in my c++ application. How can this be done?
Thanks
The speed at which a keypress becomes automatically recurring is controlled by Windows.
If you want to manipulate automatic recurrences of key-presses, it might be more advantageous to poll for the state of the key rather than waiting for the keydown event. It depends on how responsive you need your application to be.
This article may help you in figuring out how to query for key states: link
You can use the SystemParametersInfo function to change the keyboard delay and refresh rate, as described in this newsgroup thread.
A simple way to handle this is to establish a buffer of time around the OnKeyDown event. Setup a timer that determines whether control passes to a secondary event handler. If the timer has expired, then it is OK to pass control. If the timer hasn't expired, then you should return and leave the event unhandled. Start the timer right before passing control to your secondary event handler.
void KeyDownHandler(...)
{
// ...
if (TimeLeft() <= 0)
{
StartTimer();
handleKeyDown();
}
}
A timer is better than counting duplicate events because you can't assume that a given system will have the same repeat rate set as yours.
I agree with Stuart that polling for the state of the key might work better. It depends upon what you are trying to accomplish.
Also note that this type of behavior might be highly annoying to your user - why do you need to ignore duplicates?
You might be able to tap into a Windows API but this might be controlled by the OS. Not sure...
You might need to manually draw a command such as to simulate a key press multiple times after a set number of seconds after the key has been pressed.
Use SetKeySpeed api (Kernel)

KeyboardProc returning TRUE causes performance drops

I'm developing an interface for an add-on to a game. I can't use the game API (for several reasons including the fact that the code must be game-agnostic) and I need to get keyboard input from the user so I've decided to use a keyboard hook (WH_KEYBOARD) to process user input when certain conditions are met.
The problem is that while I can receive and process the input correctly, when my hook returns TRUE instead of CallNextHookEx the system seems to take up a lot of time (well over 800ms) before letting things go on as expected and that's not acceptable because it doesn't even allow for a fluid typing experience.
What I have to achieve is preventing the key press message to reach the WndProc, so the question is: what can I do to achieve my target without hurting the game performance so much that the result will be unacceptable?
EDIT: due to specific requirements (games using anticheats which might create problems with my code despite it's not cheating-related) subclassing the active wndproc is not an option.
First you need your DLL to be injected into the target process, either by hooks, or by any other way.
Find the window handle of interest.
Obtain the current window procedure of that window, by calling GetWindowLongPtr(wnd, GWLP_WNDPROC), and save it.
Sub-class the window, by calling SetWindowLongPtr( wnd, GWLP_WNDPROC, &NewWndProc ) where NewWndProc is your DLL-implemented message procedure.
Inside NewWndProc you'll want to process keyboard messages (there're a dozen of them, type "keyboard input" in MSDN index, I can't post more then 1 link). For the rest of windows messages call the original window procedure you've saved during (3), and return the value it returned. Don't call it directly, use CallWindowProc instead.
This way is not very reliable, some antivirus and anti-bot (e.g. "warden client") software might not like it, and debugging may be challenging.
However it should work.
A keyboard hook should not make things that slow. There's probably something else going on that causes the 800ms delay. Is it still slow if your hook does nothing and simply returns TRUE?
If you want to prevent from message to arrive to the WndProc then you need to subclass using SetWindowLong, this way you will be able to catch all messages and decide if to continue their route.
As much as I don't like answering my own question I've found the cause of the delay. The message pump of the games I've tested my code against was implemented with a while(PeekMessage) { GetMessage... } and removing the keyboard input message somehow caused GetMessage to block for sometime. Using PostMessage and WM_NULL helped preventing GetMessage from blocking.