I have a C# application which sends keyboard and mouse events to a game. In the game there's a small UI portion which can change based on what we want to see (like GPS map, different actions to take etc). Sometimes in this portion of the UI we have to press 'Enter' (or another key depending on how the user configured the game's keys) to activate something (for example, press Enter to activate Rescue service).
Now , the problem: all the key events sent from the c# app are processed fine OUTSIDE of this UI, except this 'activate' thing. At first I thought there's a problem with the 'ENTER' (Return) key event, but after chaning it to another key that was working in-game, I noticed that key is also ignored.
I am not sure if it's a problem related to the way I send the messages (maybe it needs to have a specific parameter) and it can be fixed by modifying my app, or is some blockage in-game - and in this case there's nothing I can do.
Here's the code I use to send the key events:
public static void PressKey(short key)
{
INPUT[] inputs = new INPUT[]
{
new INPUT
{
type = INPUT_KEYBOARD,
u = new InputUnion
{
ki = new KEYBDINPUT
{
wVk = (ushort)0,
wScan = (ushort)key,
dwFlags = KEYEVENTF_SCANCODE,
dwExtraInfo = IntPtr.Zero,
}
}
},
new INPUT
{
type = INPUT_KEYBOARD,
u = new InputUnion
{
ki = new KEYBDINPUT
{
wVk = (ushort)0,
wScan = (ushort)key,
dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP,
dwExtraInfo = GetMessageExtraInfo(),
}
}
}
};
SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
}
But hoping its the 1st case, I would appreciate any help with this.
Added a screenshot in order to try to better explain the issue
(A) -> That is the UI window that requires "ENTER" to be pressed. Let's suppose that I modify the settings of the game to have "E" instead of "Enter" for the ACTIVATE action. Then the text "Call Assistance Service (ENTER)" will now show "Call Assistance Service (E)". By default, the "E" key is engine start in the game. And it works just fine (in the case (B)) . As soon as I change E to be 'Activate' , it's being completely ignored.
Another point which might (or might not) be relevant , is that the F-keys that can be at the bottom of the UI Window, also WORK just fine.
I hope this clears up the things a little bit more.
I have found what the issue was, and I'm pretty sure it's related to how the game handles the input (but since it's not me who coded the game I cannot guarantee it).
Anyway, to fix my issue, a delay needs to be added between the KEYDOWN and KEYUP events. For the time being I'm using a Timer with a callback for that, but probably there are other ways to do it also (better or not).
Hope this will help someone someday :)
Related
I'm making a program for differentiating functions and want to call a specific method as soon as "esc" is pressed.
So far I've tried finding an answer through Google, but I can't seem to find anything that works. Does anyone know if this is possible in a C# console application?
There is no event to listen for key presses. Only Console.ReadKey. But you can turn it into a callback using Tasks. Like so:
public static void RegisterKeyHandler(Action<ConsoleKeyInfo> handler)
{
Task.Run(() =>
{
while (true)
{
var key = Console.ReadKey();
handler(key);
}
});
}
This only receives keys while the console window is focused.
Is there any possible way to detect ALL key presses on the iOS on screen keyboard and/or on an external keyboard like these? I know the "accepted" way to catch typed text is to use an invisible textbox, but that seems to only catch the "text", not actual key presses (no Ctrl, Alts, Shift, etc.)
I can't find anything in the docs that suggests this is possible, though it seems pretty basic. Am I missing something, or can we really not achieve this in iOS?
Thanks!
You can override the keyCommands in ViewController to add the trigger action:
For example:
//MyViewController
override var keyCommands: [UIKeyCommand]?{
//Get UIKeyCommand
var keys = [UIKeyCommand]()
//Add triggle for Num only
for num in "123456789".characters {
keys.append(
UIKeyCommand(input:String(num),modifierFlags:
UIKeyModifierFlags(rawValue: 0), action:
#selector(MyViewController.keyCommand(_:)), discoverabilityTitle:
NSLocalizedString("keydiscover_number",
comment: "KeyDiscover Number")))
}
}
//The Triggle
func keyCommand(_ sender: UIKeyCommand) {
print("Number Clicked");
}
https://developer.apple.com/documentation/uikit/uiresponder/1621141-keycommands
Hello i have a line of code that should quit the game upon pressing the three hardware button on the bottom like Menu, Home, Back
it seems that the back and the home only is working but the menu is not working
I have a Xiaomi Redmi Note 4X phone, how am i suppose to fix this issue?
Is it the same "Menu" as the other phone where when you press it, it'll show list of the opened app
here's the code:
if (Input.GetKey (KeyCode.Home) || Input.GetKey (KeyCode.Escape) || Input.GetKey (KeyCode.Menu))
{
Save ();
System.Diagnostics.Process.GetCurrentProcess ().Kill ();
}
Is it the same "Menu" as the other phone where when you press it,
it'll show list of the opened ap
Yes.
I have a Xiaomi Redmi Note 4X phone, how am i suppose to fix this
issue?
It should work otherwise it is a bug and you should file for a bug request. Before you file for abug request, use the script below to make that the Menu key is not mapped to another key.
public class KeyCodeFinder : MonoBehaviour
{
public Text text;
Array allKeyCodes;
void Start()
{
allKeyCodes = System.Enum.GetValues(typeof(KeyCode));
}
void Update()
{
foreach (KeyCode tempKey in allKeyCodes)
{
if (Input.GetKeyDown(tempKey))
{
text.text = "Pressed: KeyCode." + tempKey;
Debug.Log("Pressed: KeyCode." + tempKey);
}
}
}
}
Meanwhile, you can make a Java plugin that calls your C# function when the Menu keycode is pressed. That's another option you have.
Those buttons are OS related, you don't really control what happens with those. Well, you can track them and kill your app but this is going against what every single application does. That is, if you press the back or home or quit, it gets back to the main OS page, but your app is still on the stack ready to get back.
If you want to save when the user quits, maybe you want to look into
https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnApplicationPause.html
This will make your app behave in a more common way.
On a side note, I would even assume this kind of attempt to over control the app would be rejected for AppStore (iOS) as it would not comply with their generic requirements.
It is allways possible to map a custom KeyCode that is not mapped so far.
First find out what keycode the key has
Event e = Event.current;
if (e.isKey)
{
Debug.Log("Detected key code: " + e.keyCode);
}
Let's say this gives you 10 as keycode (a one that is not mapped in Unities KeyCode so far)
You can than simply define a new one like
KeyCode MY_HOME_BUTTON = (KeyCode) 10;
and than use it like
if(Input.MY_HOME_BUTTON)
{
...
}
If it is completely possible to catch the home button depends on the OS (most of the time those buttons cannot be catched by an app but are handled by the OS first)
How can I detect if any keyboard key is currently being pressed? I'm not interested in what the key is, I just want to know if any key is still pressed down.
if (Keyboard.IsKeyDown(Key.ANYKEY??)
{
}
public static IEnumerable<Key> KeysDown()
{
foreach (Key key in Enum.GetValues(typeof(Key)))
{
if (Keyboard.IsKeyDown(key))
yield return key;
}
}
you could then do:
if(KeysDown().Any()) //...
If you want to detect key pressed only in our application (when your WPF window is activated) add KeyDown like below:
public MainWindow()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler(MainWindow_KeyDown);
}
void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("You pressed a keyboard key.");
}
If you want to detect when a key is pressed even your WPF window is not active is a little harder but posibile. I recomend RegisterHotKey (Defines a system-wide hot key) and UnregisterHotKey from Windows API. Try using these in C# from pinvoke.net or these tutorials:
Global Hotkeys: Register a hotkey that is triggered even when form isn't focused.
Simple steps to enable Hotkey and ShortcutInput user control
Thse is a sample in Microsoft Forums.
You will use Virtual-Key Codes.
I Hope that I was clear and you will understand my answer.
Iterate over the System.Windows.Input.Key enum values.
public static bool IsAnyKeyDown()
{
var values = Enum.GetValues(typeof(Key));
foreach (var v in values)
if (((Key)v) != Key.None && Keyboard.IsKeyDown((Key)v)
return true;
return false;
}
Good answer here...get the set of all the keystates at once using GetKeyboardState():
Detect if any key is pressed in C# (not A, B, but any)
The above is checking the live state of the keyboard.
If you rely on hooking events up to the KeyDown/KeyUp events to track the state of the keyboard...then this may not be so accurate.
That's becuase you are relying on the message pumping to process and dispatch those KeyDown/KeyUp messages....they may be delivered after the real keyboard state has changed again.
Also because when your bit of code that is interested in the keyboard state is running (usually on the UI thread)...the KeyDown or KeyUp can't interrupt you...as they are dispatched on the UI thread too....that's why using GetKeyBoardState() or the Keyboard.IsKeyDown should be used.
(the above is assuming you want and care about the live state)
I am aiding in the development for a custom made application for the Motorola MC75. It is well tuned except for a random bug with the barcode reader. Periodically, the barcode reader will only activate (start a read) if the right shoulder button is pressed. The middle and left shoulder buttons somehow become disabled. This is a unique bug in that it happens randomly and only effects 2 of the three buttons. The EMDK enables all buttons simultaneously so I am clueless as to where this is coming from (Internal or code related). If anyone has any input or advice please let me know and thank you beforehand.
Thanks,
Zach
I've worked with the Motorola EMDK before on the MC55. I'm not sure why the buttons are being disabled, and since you posted this in June you probably don't need the answer anymore, but here's a possible workaround:
Instead of letting the EMDK handle the triggers on its own, you can capture all triggers by setting up an event:
// Create a trigger device to handle all trigger events of stage 2 (pressed) or RELEASED
var device = new TriggerDevice(TriggerID.ALL_TRIGGERS, new[] { TriggerState.RELEASED, TriggerState.STAGE2 });
var trigger = new Trigger(device);
trigger.Stage2Notify += OnTrigger;
Then, in your OnTrigger method, you can handle the trigger and perform the appropriate action. For example, you can activate your barcode reader when any trigger is pressed:
private void OnTrigger(object sender, TriggerEventArgs e)
{
if (e.NewState == e.PreviousState)
return;
// Pseudocode
if (e.NewState == TriggerState.RELEASED)
{
myBarcodeReader.Actions.ToggleSoftTrigger();
myBarcodeReader.Actions.Flush();
myBarcodeReader.Actions.Disable();
}
else if (e.NewState == TriggerState.STAGE2)
{
// Prepare the barcode reader for scanning
// This initializes various objects but does not actually enable the scanner device
// The scanner device would still need to be triggered either via hardware or software
myBarcodeReader.Actions.Enable();
myBarcodeReader.Actions.Read(data);
// Finally, turn on the scanner via software
myBarcodeReader.Actions.ToggleSoftTrigger();
}
}