Reputation: 567
I'm trying to make a "keylogger"... well, it's not entirely a keylogger because it only displays the keystrokes and doesn't log them to a file. I was planning to use it on my Google+ Hangouts, so I can still show my keystrokes without having to use it with video recording software.
private void OnKeyDown(object sender, KeyEventArgs e)
{
lblText.Text = "";
lblText.Visible = false;
boxSpKey.Image = null;
boxSpKey.Visible = false;
boxCtrl.Visible = e.Control;
boxAlt.Visible = e.Alt;
boxWin.Visible = false;
boxShift.Visible = e.Shift;
Keys pKey = e.KeyData;
if (btnIcons.ContainsKey(pKey))
{
boxSpKey.Visible = true;
boxSpKey.Image = btnIcons[pKey];
}
// this part I haven't figured out either, but is irrelevant to my question.
}
private void OnKeyPress(object sender, KeyPressEventArgs e)
{
lblText.Visible = true;
lblText.Text = ((char)e.KeyChar).ToString();
}
[Context: lblText
is a label containing the key text, boxSpKey
is a PictureBox
for special keys such as ESC, for which I've made each one an icon. boxCtrl
, boxAlt
, boxWin
and boxShift
are also PictureBox
es are quite self-explanatory.]
Questions:
It seems that the values of e.Control
, e.Alt
and e.Shift
are always False, so the respective PictureBox
es wouldn't show up.
How do I check for the status of the Win
key? I would prefer not to use low-level VK_*
constants.
When OnKeyPress
handles the events, mostly with the use of the modifier keys, I get random characters... How exactly do I get the original key strokes from them? i.e. I want to get Ctrl+Shift+B
instead of ┐
.
UPDATE: I've decided to go low-level with the modifier keys, so I used P/Invoke:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte[] lpKeyState);
public static byte code(Keys key)
{
return (byte)((int)key & 0xFF);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
var array = new byte[256];
GetKeyboardState(array);
// ...
if ((array[code(Keys.ControlKey)] & 0x80) != 0)
boxCtrl.Visible = true;
if ((array[code(Keys.LMenu)] & 0x80) != 0 || (array[code(Keys.RMenu)] & 0x80) != 0)
boxAlt.Visible = true;
if ((array[code(Keys.LWin)] & 0x80) != 0 || (array[code(Keys.RWin)] & 0x80) != 0)
boxWin.Visible = true;
if ((array[code(Keys.ShiftKey)] & 0x80) != 0)
boxShift.Visible = true;
// ...
}
The good news is that I got the Ctrl
, Win
and Shift
keys working, but not Alt
; unless Alt
≠ LMenu
and RMenu
. What gives?
Upvotes: 2
Views: 7399
Reputation: 795
Pressing Ctrl, Alt, or Shift individually caused Control
, Alt
, and Shift
to return true
in my KeyDown
event handler. Pressing each one of those keys individually resulted in false
being returned in my KeyUp
event handler. Are you sure you're not handling the KeyUp
event?
As @sean woodward said, should map to either Keys.LWin
or Keys.RWin
The KeyPress
event is only raised when one of the character keys is pressed and will return the character that results from the pressed key or combination of pressed keys. Ctrl+Shift+B
is not a character so you can't use KeyChar
alone to get that information. Try using the KeyDown
or KeyUp
event and looking at the Modifiers
property to get a comma delimited string of which modifier keys are being pressed. If order matters you'll need to track that as Modifiers
always returns the keys in the same order, i.e. Shift, Control, Alt
even if that's not how they were pressed.
Here is the code I used, you can try playing around with it:
KeyDown += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyDown => CODE: " + ea.KeyCode +
", DATA: " + ea.KeyData +
", VALUE: " + ea.KeyValue +
", MODIFIERS: " + ea.Modifiers +
", CONTROL: " + ea.Control +
", ALT: " + ea.Alt +
", SHIFT: " + ea.Shift);
};
KeyUp += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyUp => CODE: " + ea.KeyCode +
", DATA: " + ea.KeyData +
", VALUE: " + ea.KeyValue +
", MODIFIERS: " + ea.Modifiers +
", CONTROL: " + ea.Control +
", ALT: " + ea.Alt +
", SHIFT: " + ea.Shift);
};
KeyPress += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyPress => CHAR: " + ea.KeyChar);
};
Upvotes: 2