C# how to get key input in background? - c#

I want to get key input in c#.net in console application but the console will be invisible like freeconsole in c# and it will get what you type and set it to a string named like idk input then messagebox.show(input); then everytime you type a key it messagees it in the background,
i want to learn to make games so yeah and i want it to work in background.

The way Windows works is that when a key on the keyboard is hit, Windows sends a message (actually, several) to the Window which currently has the focus. If your Console app is in the background, then by definition it will not have the focus.
All is not lost, though. You can setup what's called a global keyboard hook. This does mean that you'll get ALL keyboard hits, though.
And as #AaronM.Eshbach says, this is a keylogger and generally not a good thing...

Related

Change EnableDesktopModeAutoInvoke registry value and make TabTip.exe to accept change

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.

Robust SendKeys solution required

I'm trying to write an application that can reliably send key presses to another application.
The second app has a text field which opens when 9 is pressed.
Text can then be typed and then the text field is closed when Enter is pressed.
If I use SendKeys to try to do this the field does not open if I send 9, but if the field is already open my tool can send text ok, but then it does not close if I send an Enter.
I'm guessing this is because a lower-level interaction with the keyboard driver or similar is being used.
Is there a reliable way I can simulate actual keyboard input to the application from another C# app?
I have found a few potential solutions online but these are generally incomplete with either missing references etc. or missing code elsewhere.
I will continue to search and I will post the solution here if I find it!
is it an option to invoke on screen keyboard provided by os. your app, calling app will loose or cant track the key events, however if you open your second application and invove osk.exe, then the purpose of robust keyboard sending keys to an app could be fullfilled.
I explained this here
EDIT: ignoring on screen keyboard
You can try using RegisterHotKey to open the textpad on a specific sequence of key(s) and persist the handle in a instance variable. On the sequence of second hot key(s) you can close the textpad (you already know the handle)
there is a video explaining this

Reading characters in a background application

Hi I'm trying to make a simple program that read keys from keyboard even if my application is running in the background.
Situation
I want make a timer to help me in a game. I already have the program with the timer, the problem is I can not start the timer without switching of the game window to my app window. So I configured the game keyboard to release the keys F11, F12. Now in game this keys do nothing.
Problem
I built a windows forms containing a listener for keydown event and a conditional for F11. But when I trigger another window (eg the game window) my application no longer hears the keyboard, cuz it's in the background.
Question
How can I build a app that hears the keyboard, even if it's not active window?
You need to install a global, low-level keyboard hook using the SetWindowHookEx API call. Using the WH_KEYBOARD_LL hook will set your application up to intercept keyboard events at all times, even when your application is not active.
This post on MSDN shows an example of how to achieve something close to what you want from C#.

How can I prevent RegisterHotKey from stopping the default key action?

I'm using the Window's API RegisterHotKey function to run a macro when the F2 key is pressed while a specific application is open and focused.
The problem is, this is stopping the F2 key from working for other applications, such as Excel.
How can I prevent RegisterHotKey from stopping the default action?
I have a system tray application that uses the HotKeyManager class from this answer to register hotkeys. When a specific key is pressed (for example, F2), I use the Windows API to check if a closed-source application is open and focused, and if so send it a series of SendKeys.
From what I understand, you want your global hotkey to work only when one or more selected apps are focused. Can't you simply SendKeys the intercepted strokes if you determine that an incompatible app is in the foreground?
For example,
if (IsSpecificWindowFocused())
{
// Do work
}
else
{
// Resend the key to whatever window is current
SendKeys.Send("{F2}");
}
RegisterHotKey is global, so it is going to trap all of those keystrokes (in other words, I don't believe it is possible to do exactly what you ask).
However, this thread
Global Keyboard Hooks (C#)
talks about creating a keyboard message filter, which is (I believe) more like what you are going for.
To clarify:
RegisterHotKey is going to be best for things like tray apps and anywhere else where you want an OS wide keyboard short cut that doesn't rely on the app being in focus.
Application.AddMessageFilter() is what you want when you want consistent handling of a particular keystroke, but only when your app already has focus.
A way to do what you're describing and still stay in .NET would be to monitor what processes are running on the OS and only enable the global hook when your app is running.

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