Mouse hook with C# - c#

I am trying to emulate "hardware" mouse clicks as it appears that some software blocks input from PostMessage for instance. I know there's SendInput, but that's not an option as I need this to be compatible in background windows as well. The solution seems to be a low-level mouse hook but I've searched around and couldn't find anything other than just the loggers, no manipulation of moving mouse, clicking etc. I'd like this to happen without having to write some sort of C++/C wrapper to use as a fake mouse driver.
http://support.microsoft.com/kb/318804, I found this but it doesn't seem to be of any further help.
Any help appreciated :)

Not sure what 'some software' might be, but sure, UAC stops you from poking messages into the windows of elevated programs. It is called UIPI, User Interface Privilege Isolation.
In general, faking input with PostMessage doesn't work well at all. It is especially a problem for keyboard input but mouse input has trouble too. There is no good way to alter the keyboard state for another process. That matters when the program checks the state of the Shift, Ctrl and Alt keys when it processes the input message. Many do.
The only real solution is to emulate input with SendInput(). Now you got a focus problem to solve.

mouse_event or SendInput used to inject mouse input. But just like a real mouse it's global input and can't work on hidden windows.
A low-level-mouse-hook is global too, but it is used to intercept and manipulate mouse-input, not to inject input.
When targeting a specific window you'll need to use SendMessage, but as you noted it doesn't work for everything.
You can also use dll hooking(for example an IAT hook) to intercept calls to APIs which return the gobal cursor position or the state of the mousebuttons. But for that you need to inject a dll into the target application, and that dll shouldn't use .net.

When I have to simulate mouse input I first try with SendMessage but sometimes some control or the application could eat the message.
In that situations I use spy++ to intercept messages of the window that holds the control, I do exactly what I want to simulate and then, I just use:
GetWindowLong(hwnd, GWL_WNDPROC);
to get window proc and then call the wnd proc(process) directly with:
CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Sending exactly those messages that I saw using Spy++. That always work because the window proc is called immediately instead of queued in the message loop.

Take a look at this library http://globalmousekeyhook.codeplex.com/.
It is 100% managed c# code to install global mouse and keyboard hooks.

Related

Capture touch input on the screen in windows device

Is there any way to capture touch input on the screen (outside application frame) in windows device?
I'm working on a WPF application and can retrieve the touch input if it only occurs within the application frame. Also, is there a way to register the touch input even when the application is minimized?
There's no built-in method of the WPF framework that lets you listen for input outside of the application. If you want to do that, you'll have to get into p/invoke territory.
Specifically you'll need to create a hook. You'll want to look at the SetWindowsHookEx method and either the WH_MOUSE or WH_MOUSE_LL hooks.
Since you're dealing with touch inputs, this answer might have some useful information for you:
The lParam argument of your hookProc callback is a pointer to an MSLLHOOKSTRUCT. It contains a very poorly documented dwExtraInfo variable, which tells you whether it was generated from a touch.
If all of the bits in 0xFF515700 are set in dwExtraInfo, then the callback was invoked in response to a touch.

Perform Ctrl-C on specific window without focusing it

I have an application to which I want to send the Ctrl-C keys combination. I am trying with SendMesssage, but I know that the application checks for Ctrl-C combination using GetKeyState and GetAsyncKeyState so SendMessage is pretty useless... How can I send the Ctrl-C combination to this window without calling SetForegroundWindow(hWnd)? I need a solution which works without focusing/bringing to front the window.
I am temporarily using this code (but requires focus):
SetForegroundWindow(hWnd);
SendKeys.SendWait("^(c)");
I am using C#, but C++ code is ok.
A long time ago, back when I was doing Sys Admin automation.. I used AutoIT. It's been a long time, but if you don't mind picking up their .dll...
This is the method I'd use.. it mentions you can send directly to a window/control without focus.. in some cases you can't..
AutoIT ControlSend Method

SendInput to minimized window

Is it possible to utilize the sendInput function on windows that currently do not have focus, and maybe through the use of multithreading, sendinput to multiple minimized windows at the same time, or send input to one window while you're working on another window?
I'd like to do something like this in c#
thanks in advance.
You can only use SendInput to send input to the HWND with keyboard focus. Furthermore the window must be attached to the calling thread's message queue, so one cannot simply SetFocus either.
You'll need to get the window's thread id with GetProcessIdOfThread.
When you have the thread id you can use the AttachThreadInput function to attach your thread to the other threads input processing.
After all this you can probably use SetFocus and SendInput.
You'll probably want to detach your thread when you've sent your input.
To get access to these method you'll have to use P/Invoke for C# or C++/CLI. PInvoke.net is very handy as a reference. It will be a small chore importing all those functions, but when you are done you should be able to send input to whatever "window" you want.
Also as a side note, I'm not sure if you are aware of this, but in pure Win32 everything is regarded as a window, even a button. If you are unlucky you may have to send the input to the handle of the text control belonging to the notepad application.
That is not possible with SendInput. What you probably want to do is find the messages that were sent to the window by the OS when that particular event was performed then emulate them. You can use Spy++ to attach to the target window and perform your event. Then use SendMessage() and PostMessage() to reproduce the messages that were generated by your event. This will work fine for notepad.
If you do use this method, note that you need to send messages to notepad's child window which you can find with FindWindowEx() with a classname of "edit". For example to type text you could try WM_KEYDOWN. You should note that this method is not necessarily reliable:
http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx

Create an On-screen Keyboard

I use PostMessage to simulate keystrokes in a program that is in the background. It work fine except for characters that need shift on the physical keyboard. How do I simulate shift? "
The code I use is roughly:
VK vk = VkKeyScanEx (c, GetKeyboardLayout (0));
AttachThreadInput (_attachedThredId, _attachedProcessId, true);
PostMessage (_window, WM_KEYDOWN, vk.key, 0x1);
PostMessage (_window, WM_KEYUP, vk.key, 0xC0010001);
AttachThreadInput (_attachedThredId, _attachedProcessId, false);
How should I handle Extended part of VK?
Edit
I'm trying to create an on-screen keyboard. Each button on the on-screen keyboard simulates a sequence of keystrokes. The receiver is an old program that performs different tasks depending on the keyboard sequence that is performed.
Keyboard sequences is as follows
{ESC}NN{ESC}NN
{ESC}NN
½NN
§NN
where {ESC} simulate pressing the Esc key, NN are hex values and §/½ get the program to listen.
Normally we have special physical keyboard to control the program, but they are expensive. So in a test environment where we do not always have the physical keyboards, we have to enter these codes manually
You must compromise:
If you want to simulate keyboard input, then you must use SendInput, which means being at the mercy of which window currently has focus. SendInput is like hitting the keys on your physical keyboard. The only way you can send your keystrokes to a specific window using your keyboard is to ALT+TAB to the right window.
If you want to send keystrokes to a specific window, then you incur funky behavior:
Applications handle input differently. And simple WM_KEYDOWN / WM_KEYUP messages are not the only way to detect keyboard input. For example there is also the keyboard state (GetKeyboardState()) which you will have a harder time simulating. This is most likely what you're experiencing.
Applications may RELY on the standard behavior of having focus while receiving keyboard input messages. By posting messages to these applications, you invoke strange out-of-order behavior that may crash them.
Now multiple windows on the system can be receiving keyboard input at the same time. This might also cause strange behavior.
(etc...) Hooks won't be called for this input, your keyboard / input drivers won't see it, it won't be recognized by things like DirectInput... basically it's a never-ending patchwork of issues by doing something the bad-bear way.
There is no way around those side-effects; it's the consequence of doing shady stuff.
A solution for your purposes, because you're targeting a single specific application, may be to use PostMessage in conjunction with SetKeyboardState to simulate the keyboard state including shift positions.
Okay, I think you're in for a mess here, PostMessage() is notorious for not working well with shift states, and hooks won't get called either. Microsoft recommends SendInput() instead, and so do I. I suggest that you either post a new question, or update this one, where you detail what you are trying to achieve, and maybe we can better recommend a different solution.
As for the extended part, it has nothing to do with this at all, and won't help you.
What you could try, is sending a WM_KEYDOWN message that says the shift key was pressed, and then send another message with your desired key, before sending a WM_KEYUP shift message. I doubt this will work, but you can always try.
Personally i would use SendKey.Send( ) for this purpose.
MSDN page

Emulate Key Presses On an App that takes no Win Messages

I want to send an Application Key Presses, To Automate some stuff that has to be done repeatedly and So I don't always have to cramp my fingers.
In C#, it's nice to use SendKeys.Send(), but this won't work because the Application doesn't take Windows Messages. SendKeys.SendWait() does nothing at all.
How would I STILL Simulate the Keyboard events?
Come To Think of It, I was going to use some P/Invoke to simulate Mouse Events too, but If it takes no messages, How Can I get around that?
EDIT - I can use mouse and keyboard to interact with the program, I just cannot manipulate it with Windows Messages sent from my own Code.
Have you tried AutoIt?
Is it a console app? If so, maybe you should be SendKeys'ing to the command shell instance it is running in.

Categories

Resources