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
Related
I have an application where I have multiple keyboards connected through USB.
I need to hook a specific keyboard to get the keypress directly into the software, even if this one is not on the foreground. This so far works based on this project. The other keyboards shall work as normal.
Although it seems by using Direct Input, it is not possible to stop propagation (we don't want other apps to get that particular keyboard input).
Concerning Global Hook, it can block the keypress system-wise, but it is impossible, as far as I know, to identify the source of the keystroke (which keyboard it is from) and thus to selectively block them.
There is another project, here, that combines the two, but it is quite messy and heavy.
Is there a better way to achieve this? I am surprised that simple task is so complex.
If you are going to make the app windows only, you should look into Windows raw input api
It isn't that complicated.
I would like to disable, with run-time configurability, various keyboard combinations (Alt+Tab, Ctrl+F, etc.) from the primary keyboard on Windows.
I'd still like to be able to emulate these key combinations through software-based means, such as the approach shown at https://inputsimulator.codeplex.com/.
Every example I've found disables the key combinations completely, but I only want to disable the key combinations if they come from the main keyboard.
Any thoughts on the feasibility of this? My current prototype is a .NET service that is written in C#.
What you're asking for is not possible. Windows discards the device ID early in keyboard processing; by the time it reaches user mode (a low-level keyboard hook, say) the device ID is gone. Raw Input lets you track the device-specific input, but doesn't let you block it.
My app (in C#) need to interface with a USB bar-code scanner, which is basically working like a keyboard. It inputs the bar-code with an enter key at the end.
The app need to be work even when it's at background, so I am using low level keyboard hook to get and filter the bar-code out in the global key events. This part is already working.
Here is my problem: I don't want other apps to get the keyboard(scanner) inputs if it is a bar-code. And the normal key events should not be interfered. In one word, block the key events selectively. Is this possible?
My app is in C#, but I have no problem with C++ or more native solutions as long as it's easy to integrate in C#.
Thanks.
Additional Information:
The whole idea is working at background, even when it's not active. It watches the global key events stream and spot the bar-code sequence (already implemented with Hook). And most importantly, it do NOT interfere with normal keyboard events nor other applications' operation. That's why I cannot block all the key events or make it top-most.
I already can get the bar-code. I need to prevent other applications from getting the bar-code.
At the end of your keyboard hook you would call CallNextHookEx to execute next hook in the chain.
I would suggest that put some unique signature as a preamble for your barcode so that your keyboard hook procedure can detect it as a valid barcode input from your scanner. Now, when you get this data, just skip the call to 'CallNextHookEx' so that the chain will be discontinued and other programs won't get your barcode. Otherwise - call 'CallNextHookEx' so the chain can continue.
Note: This is my theory, I have never tried the exact same thing myself. I have however, written hooks in C++ and C#.
Check this project out
http://globalmousekeyhook.codeplex.com/
It is in C# as well so will make your coding easier. Sounds like all you need is to hook up the global key press event and suppress it by setting the Handled value or something similar.
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.
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.