I have an extended keyboard and I want to simulate the key press of a special key that switches the keyboard mode. For that I think I need to find out key code, but can't figure out how can I get it. It's an extra key on my keyboard, not part of the ConsoleKey enum, and the only functions I've found to catch keys work with this enum.
If the key does something like change the keyboard color, this will depend on whether or not there is software on the computer which can do so as well. If not, this is probably just a local switch to the keyboard and that key isn't on the keymap for the keyboard itself, ether.
If it changes something else, it will depend on if there is driver software for the device or if it uses a default Windows driver.
If it takes installed software, it's probably a custom event (like some joysticks have) and would only be found if you use a reference to a library distributed by the keyboard manufacturer.
If it does not, then the switching mode is probably a "remap" mode tied to the keyboard firmware, and just changes which KeyDown event the affected keys send. If this is true, there is no way for Windows to even see what setting the keyboard is on.
I would say the logic for the function key changes is on the keyboard itself. For instance, the Fn key on my laptop does not cast any keyboard events by itself, but when combined with certain other keys, a key code is sent to the OS with a key code that triggers certain functionality.
For instance, in my keyboard Fn + Left lowers the volume, but the virtual key sent to the OS is VK_VOLUME_DOWN (see this for a list of virtual keys.)
Good news is, you can test the keys individually to see which key codes get sent to the OS! To accomplish this, you might want to set up a low-level keyboard hook) using P/Invokes.
There's a tutorial on CodeProject that may be useful to you.
Related
Windows 10 has setting "Show the touch keyboard when not in tablet mode and there's no keyboard attached", which allows Windows to show touch keyboard whenever you touch text box.
As Windows handles this logic rather poorly (it is easily broken in WPF applications), I would like to turn off this option for my application, which I'm trying to do by changing registry value EnableDesktopModeAutoInvoke, corresponding to this option (simple Registry.SetValue method). But there is an issue - touch keyboard application TabTip.exe for some reason doesn't really "hook up" changes in registry, and keeps showing touch keyboard until it is restarted. And vice versa - once I'm restoring registry value, I need to restart application to apply change.
And this is where main issue of such approach appears - with auto-invoke option enabled, once TabTip process starts, it immediately shows keyboard. Obviously I would not like such visual side-effects for my application logic.
Another point is that while changing this setting in usual way, via Windows Settings application, TabTip or any related applications or services are not restarted. Which means Settings application somehow manages to update TabTip process. I would really like to figure how it does this, and if I can reproduce same behavior in C#, but I have no idea how.
So, my question is - how can I programmatically change either EnableDesktopModeAutoInvoke registry value or "Show the touch keyboard when not in tablet mode and there's no keyboard attached" Windows option, and make TabTip application to accept this change, without any possible visual side-effects?
UPD:
I know that it is possible to make keyboard to ignore text box by creating custom text box with specific automation peer, but this would require to replace all text boxes in entire application, and always keep in mind that we need to use new text boxes, so this is not viable solution. I've tried to remove possibility to get automation peers for children of main window as well, but that doesn't work.
So I looked at lot of different implementations of the same
https://github.com/maximcus/WPFTabTip/blob/65b58e1900d3c21c9ea684e9f882088fe821586b/WPFTabTip/TabTip.cs
https://github.com/zhangtx2812/NewClient/blob/851f6dd8bc9c6389b70c7b5cd9384617a62a274e/Client.Helpers/Utils/KeyboardHelper.cs
https://github.com/Anneliese1989/Examintion/blob/2f974312d1ce0452a018bcaecf7bda753c818d9e/WPFTabTip/TabTip.cs
https://github.com/TransposonY/GestureSign/blob/11395ba6f18ea39b86f8e0a586b10a43f3c27568/GestureSign.CorePlugins/TouchKeyboard/TouchKeyboardUI.xaml.cs
https://github.com/microdee/mp.essentials/blob/d5832dee693839d55157d287d2459760b90b1d05/windows/WindowsLaunchOSKNode.cs
and most case one kills the process using
foreach (Process tabTipProcess in Process.GetProcessesByName(TabTipProcessName))
tabTipProcess.Kill();
or close the keyboard using
void closeKeyboard()
{
uint WM_SYSCOMMAND = 274;
uint SC_CLOSE = 61536;
IntPtr KeyboardWnd = FindWindow("IPTip_Main_Window", null);
PostMessage(KeyboardWnd.ToInt32(), WM_SYSCOMMAND, (int)SC_CLOSE, 0);
}
So, I think what you have already are the best choices known
I have a shot in the dark for you...
Here's one way that it is possible TabTip is notified of registry changes by Windows Settings but not by you: If TabTip is using something like the WMI RegistryKeyChangeEvent class internally, it's possible that the TabTip application is only monitoring the parent registry key and not monitoring the key value you're actually changing (which is why TapTip not updated when you change the value). But, the Windows Settings application could be setting the whole key (and it's corresponding valueName and value) via something like SetExpandedStringValue, which would trigger the key change that TabTip could be watching.
The way to test for this would be to set the key, valueName, and value all at once programmatically, instead of just setting the value.
Not a great solution, but you could attempt to hook up to the showing event https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane
And immediately call a TryHide in the event of a show event to suppress it.
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.
Method SendKeys.Send does not allow the press Fn key, which exists on laptop's keyboards. How can I simulate pressing this key from C#?
You can't, and you don't need to. The Fn key only exists as a key as far as the keyboard circuit is concerned.
When the key code is sent to the operating system, it looks just as if the function keys were regular keys as on a regular keyboard. The operating system doesn't even know that the Fn key exists, that is taken care of by the special keyboard circuit in the laptop.
To make a function key press on a laptop, just send the regular key code for a function key as on a regular keyboard.
If there are any other key combinations where the Fn key is used, they either have their own key codes, or they are simply not possible to send because they are handled by the laptop, not by the operating system.
I have never tried it, but I think you can do it with another way. Create a keydown event on a textbox and press fn key at runtime and then check what code or what keyValue it returns. Then use that value in your SendKeys.Send method.
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 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