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.
Related
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.
I've found the function SetDoubleClickTime which sets the double-click time for the mouse.
this means: the maximum number of milliseconds that may occur between the first and second clicks of a double-click.
But I would like to set in the OS the opposite thing, the minimum interval to consider that the user made a double-click.
This is possible to do?
EDIT: Just I would like to know if I have more alternatives than hooking the mouse and setting a timer or something else to compare the times.
UPDATE
My initial intention was to think in ways to translate this AutoHotkey snippet to .NET code:
LButton:: If ( A_TimeSincePriorHotkey < 50 )
SendInput, {Lbutton Down}
return
Lbutton Up::SendInput, {Lbutton Up}
MButton:: If ( A_TimeSincePriorHotkey < 50 )
SendInput, {MButton Down}
return
Mbutton Up::SendInput, {MButton Up}
RButton:: If ( A_TimeSincePriorHotkey < 50 )
Sendinput, {Rbutton Down}
return
Rbutton Up::SendInput, {Rbutton Up}
I just supposed that maybe I could save all the time for writting a code by using a native function from Windows API.
The SystemParametersInfo function reads and writes all the double-click parameters.
There are three. SPI_SETDOUBLECLICKTIME is the same parameter set by SetDoubleClickTime; SPI_SETDOUBLECLKHEIGHT and SPI_SETDOUBLECLKWIDTH define the size of the rectangle the second click must fall within.
There isn't a parameter for the minimum double-click time.
Of course, I can't prove there isn't an undocumented parameter, but if there was a documented parameter it would almost certainly be documented in SystemParametersInfo.
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.
So, basically what i'm doing is using JNA to set a LowLevelKeyboardProc Keyboard hook, everything works perfectly fine, i can get the values exactly like i want them in java, but the problem i get is when trying to convert to chars, it becomes extremely ennoying handling caps locks, SHIFT keys and tons of other things like everything thats not a-z 0-9 on the keyboard, i was wondering if there is a easier way to do the conversion?
heres the details of what I'm getting from the hook every time a key is pressed
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=VS.85).aspx
, i Figured it might be best to find a way to manually generate a KeyEvent(Not char, since i need something to handle things like F keys, caps lock button, CTRL button etc etc).
Any help i can get is highly appriciated!.
The Abbot project (http://abbot.sf.net) has a system for mapping keycodes to keychars, using predefined keyboard mappings (it generates a wide variety of keystrokes and records the resulting character output). However, Java does not provide a way for "predicting" the resulting character output given a particular key code.
There may be something within the MS libraries.
I have a string of values, and I want to simulate key press events in a window for each character.
I plan on sending WM_KEYDOWN, WM_CHAR, and WM_KEYUP events to the window (as that is what seems to happen whan a key is manually pressed).
Those messages require an int be sent in the wParam based on a table of virtual key codes. I can loop through the string and get each character, but how do I take that character and convert it to a value that corresponds to the virtual key code? Convert.ToInt32() does not work.
VkKeyScanEx anyone? According to MSDN it:
"Translates a character to the corresponding virtual-key code and shift state."
(You could possibly also use VkKeyScan but beware that it has been superseded by VkKeyScanEx.)
Sending WM_KEYDOWN/UP is troublesome. The application itself already translates the WM_KEYDOWN message into WM_CHAR, using the state of the modifier keys (Shift, Alt, Ctrl) and the keyboard layout. Neither of which you can control, you'll get the wrong character, randomly.
Just send WM_CHAR messages, set the wparam to the character code. No need to worry about lparam, few apps ever use it.
It looks like it takes the ASCII character and turns it into hex. For example, 'A' in hex is 41. According to your chart, A is 0x41, which is right (the 0x detonates hex).
Generally speaking, instead of sending WM_KEYDOWN, WM_CHAR and WM_KEYUP messages directly, you should use SendInput (preferred) or possibly keybd_event (deprecated).
You can use Input Simulator library which provides a high level api for simulating key presses and handles all the low level stuff.
System.Windows.Forms.SendKeys is a WinForms class with static methods for simulating keyboard input on the active window.
The catch is that .NET has no way of focusing windows in another application (the SendKeys docs talk about how to get around that).
The general solution is to use the SendMessage WinAPI function. This link describes SendMessage's signature and provides a sample import.
Oh and, to map VK codes you should use MapVirtualKey - its best to assume the mapping is arbitrary and not logical.