GetAsyncKeyState Explanation required - c#

I wanted to make a little keylogger using the console application and I stumbled across this source code on the web and I have trouble understanding it.
while(true)
{
Thread.Sleep(10);
for (int i = 0; i < 255; i++)
{
int keyState = GetAsyncKeyState(i);
if (keyState == -32767)
{
Console.WriteLine((Keys)i);
}
}
}
So from what I understand, keystate is basically a function which tells if a key is currently being pressed. Since we want to check if any of the 255 keyboard keys are being checked we need a for cycle. Correct me if I am wrong.
So if the key we are currently pressing is well... pressed, it will return some Value (Would like to know what value this is...maybe the keycode value? Correct me because I am sure I am wrong).
But the IF is the part where I have totally lost it. If my understanding is correct, then the write line will only happen if we get -32767 which is who knows what? And that is what I would like to know. Why is it -32767? How come it works even if we never get -32767, LMB is 1 for example...?

If my understanding is correct, then the write line will only happen if we get -32767 which is who knows what?
The value of -32767 (0x8001) is an important value. GetAsyncKeyState returns a short, which means it is the least significant bit (0) of the 16bit return value.
According to the docs:
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
That means it is looking for a key press between calls.

Related

Check keypress after another keypress in console application (GetAsyncKeyState C#)

I would like to check if the user will make a kepress again after the first one to implement a pause function in a while cycle. The console window is not on focus so I can't use Console.Read()
while (true)
{
if (GetAsyncKeyState(0x21) != 0)
break; //work just fine, if ESC press it exit while
if (GetAsyncKeyState(0x05) != 0)
{
sw.Start();
while (sw.ElapsedMilliseconds < 2000)
{
// if side mouse button is press, it wait 2sec, work just fine
}
sw.Reset();
}
if (GetAsyncKeyState(0x42) != 0)
{
while (GetAsyncKeyState(0x42) == 0)
{
// wait the second B pressing to resume but it dosen't work
}
}
main_function();
}
This code seems to not work, I check GetAsyncKeyState with writeline and it seems that it get the keypressed state for few ms so the pause cicle will end.
I seems that in console c# I can't use ad hoc functions that c# have for forms to check it.
Thanks!
The solution is:
// if pressed the first time
if (GetAsyncKeyState('B'))
{
//if previously detected and still held down
while (!((GetAsyncKeyState('B')) & 0b1000'0000'0001))
{
//wait in here
}
//if key not pressed
while (!GetAsyncKeyState('B'))
{
//wait in here
}
//if you get here, B was pressed, released and pressed again
}
I don't recommend using GetASyncKeyState for anything but quick and simple Proof of Concepts due to the remarks you will read below.
From MSDN:
Return value
Type: SHORT
If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.
Important remarks:
Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon.

How to use GetKeyDown() to efficiently detect when any key is being released

I will begin by saying that I'm very new to C# and Unity, so apologies in advance if I am lacking what would be considered common knowledge. Also, I have checked other questions on here and have not found any answers that particularly solved my specific issue. If there is one however, I would appreciate being pointed towards it.
Anyway, I am trying to write some code that will play a sound when a key is held down and will stop playing when the key is released. Different keys will play different sounds, so the GetKeyUp() function should apply to whatever key is currently being pressed.
I have declared a string for inputKey, and inputKey is assigned whatever key is being pressed, and is then passed through to an if statement containing the GetKeyUp() function. I have tried numerous small variations of this method but the one I am currently using has been the only way that hasn't yielded an error message (although the code still doesn't work)
public string inputKey;
else if (Input.GetKeyDown(KeyCode.S))
{
freq = 293.66;
gain = volume;
}
inputKey = (Input.inputString).ToUpper();
if (Input.GetKeyUp(KeyCode.inputKey));
{
gain = 0;
}
So in the example above, when the key S is pressed, the sound is played. The inputKey is being displayed as 'S' so I would expect 'Input.GetKeyUp(KeyCode.inputKey)' to be the equivalent of 'Input.GetKeyUp(KeyCode.S' and the sound to stop playing, yet this is not the case and the sound continues to play.
Any help or advice would be greatly appreciated, thanks.
I would use Input.GetKey() instead.
Rather than checking "is S down? start playing the S sound. Is A down? start playing the A sound. Did any key get released? What key was it? stop playing that sound" I would simply check each key's current state and start or stop the sound based on that state.
E.g.
soundOnS.gain = Input.GetKey(KeyCode.S) ? volume : 0;
Your current approach can not, and never could, adequately handle what happens if someone presses down on multiple keys at the same time: when they lift up one finger, releasing one key (but not the other!) what sound should be playing?

Creating Calculator App in Windows Store

I am creating a Calculator in Windows Store Application. I have successfully created the app in the store.
Now there is a problem in my app, after getting the result from performing any operation whenever I press on any numeric value, that value got append in the existing value.
In the following snapshot: I have added two numbers (1,1):
Now I am entering another value to perform some other option, but the new value got append in the existing value. I am entering 1 here:
What is the code for removing the existing value, if any numeric values pressed?
you could declare a bool value which is false and when you have your calculation done you switch it to true. Then you write a method that checks if the calculation is done or not and if it's done you simply clear the (i guess you use a textblock / box?) output. That would be my way in this situation - maybe there is a better solution for you. I hope it helps you to get a clearer way in mind.
As the author of the Windows Calculator that shipped from Windows 3.0 through Windows Vista, I agree with user3645029's response. You need to work out the input model for the app, so you understand clearly when you begin entering a new number and when you append to the one showing. I suspect that your app logic isn't making this distinction.
Let me be more specific:
If the key pressed is a number and the last key pressed was a number, then you add that new digit, which effectively means multiplying the current value by 10 and then adding the new key.
If the key pressed is a number and the last key pressed was an operator, =, or similar keys, then you're starting a new number input and your current value should be reset to 0 first.
In short, writing a calculator app requires an internal state machines that understands how to proceed from one input to the next. From what you describe, it sounds like you're missing the logic for the = key. Generally speaking, hand-held calculators with an = sign effectively clear the current value if you start entering a new number after =. Only if you press an operator does that value persist, and in that case you're also starting a new current value and keeping the "2" in your case as the first operand.

System.Windows.Forms.Keys - Lower or Uppercase?

I have been searching around for an answer to this but I can't seem to find anything. Does anyone know if you can determine the letter casing in Keys?
For example:
if (System.Windows.Forms.Keys.A.ToString() == "A")
{
// Upper or Lower?
}
Thanks.
There is no casing, it represents a physical key on your keyboard. Do you see an 'a' and an 'A' on your keyboard?
You can check and see if a Shift key is depressed.
System.Windows.Forms.Keys.A represents the physical key A on your keyboard. It does not have a case. Thus, your question does not make sense.
If you want to check whether the user holds the Shift key on the keybord, there's also System.Windows.Forms.Keys.Shift.
There is no simple mapping between keys and characters. Keyboard layouts can work differently. One example are dead keys. And once you get to IMEs it gets even more complicated. Do not try to duplicate a keyboard layout manually in your application.
If you want to get what character a user entered, handle WM_CHAR, not WM_KEY_DOWN/UP. It's exposed as Control.KeyPress event in winforms.

WM_KEYDOWN : how to use it?

I'm trying to send a key stroke to one application, through PostMessage. I am using too Spy++ to try to understand how to send the message, as I do not fully understand its inner workings.
In this picture, the first item(selected item) was made with an actual key stroke made by myself. The one with a red elipse around it(below) was made with the following code:
WinApi.PostMessage(InsideLobbyHandle, WinApi.WM_KEYDOWN, (int)WinApi.VK_UP, 1);
I guess it must have something to do with the last PostMessage() parameter, but I can't figure out how it really works. I can see in the original key stroke the ScanCode = 48, and in mine its 0, and also fExtended is 1 and in mine is 0. How can I make it look the same?
In http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx I cannot understand the last parameter's working.
Simulate keyboard input using SendInput, not PostMessage.
You can't simulate keyboard input with PostMessage.
There are still some caveats with respect to keyboard state/async-state:
The SendInput function does not reset
the keyboard's current state.
Therefore, if the user has any keys
pressed when you call this function,
they might interfere with the events
that this function generates. If you
are concerned about possible
interference, check the keyboard's
state with the GetAsyncKeyState
function and correct as necessary.
The lParam for the WM_KEYDOWN Notification is specified in terms of the bits of the field:
The first 16 bits are the repeat count
The next 8 bits are the scan code
The next bit is 1 for extended key, 0 otherwise
The next 4 bits are reserved and must be 0
The next bit is always 0 (for WM_KEYDOWN)
The next bit is the previous key state
The last bit is always 0 (for WM_KEYDOWN)
A warning: Any solution you build based around PostMessage is going to be very brittle.
Take a look at http://inputsimulator.codeplex.com, it wraps the SendInput method mentioned by Kevin
In Spy++ if you right click on the highlighted (logged message) entry and look at its properties, You can see the exact value of the lParam. You can then use that as your lParam to ensure that the PostMessage leads to similar effects, as the manual action did.

Categories

Resources