Trying to write a simple demo program where keyboard input into the console gets translated to key presses on a target window belonging to some other application process. So if I type the character "w" on my keyboard into the console, it translates to appropriate messages sent to the message queue of a target thread that has the application believe that the "w" key was pressed while it's window was in focus.
This is what I've tried:
int main()
{
// setting up window handle etc...
println("Enter W, A, S, D or SPACE:");
while (true)
{
int posted_key = NULL;
int key_char = _getch();
if (key_char==27) break;
switch(key_char)
{
case 119: posted_key = 0x57; break;
case 97: posted_key = 0x41; break;
case 115: posted_key = 0x53; break;
case 100: posted_key = 0x44; break;
case 32: posted_key = VK_SPACE; break;
}
if (posted_key == NULL) continue; // Key isn't W, A, S, D or SPACE
if (!PostMessage(hndl, WM_KEYDOWN, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC))) print("Error while posting WM_KEYDOWN"); break;
if (!PostMessage(hndl, WM_CHAR, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC))) print("Error while posting WM_CHAR"); break;
Sleep(100);
if (!PostMessage(hndl, WM_KEYUP, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC))) print("Error while posting WM_KEYUP"); break;
}
return 0;
}
However, only the WM_KEYDOWN
and WM_CHAR
messages (1 each) end up actually posting to the queue, and not the WM_KEYUP
message, resulting in the application behaving as if the key is being pressed down indefinitely. From using Spy++ on various applications it seems that a quick keypress usually comes in 3s: WM_KEYDOWN
, WM_CHAR
and then WM_KEYUP
a fraction of a second later. So this is what I tried to emulate in my code, but it clearly did not work.
What's more is that my program instantly exits with a return code 0 when I press W, A, S, D or SPACE, and my error messages did not print. So either my program crashed or one of my invocations of PostMessage
returned a nonzero value. The latter is probably unlikely since my error messages did not print.
What am I doing wrong? I cannot use SendInput
or SendKeys
for what I'm trying to do as I need this to work even while the application window is in not in focus.
-- EDIT --
I've misformatted my if
conditions in the original.
int main()
{
// setting up window handle etc...
println("Enter W, A, S, D or SPACE:");
while (true)
{
int posted_key = NULL;
int key_char = _getch();
if (key_char==27) break;
switch(key_char)
{
case 119: posted_key = 0x57; break;
case 97: posted_key = 0x41; break;
case 115: posted_key = 0x53; break;
case 100: posted_key = 0x44; break;
case 32: posted_key = VK_SPACE; break;
}
if (posted_key == NULL) continue; // Key isn't W, A, S, D or SPACE
if (!PostMessage(hndl, WM_KEYDOWN, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC)))
{
print("Error while posting WM_KEYDOWN");
break;
}
if (!PostMessage(hndl, WM_CHAR, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC)))
{
print("Error while posting WM_CHAR");
break;
}
Sleep(100);
if (!PostMessage(hndl, WM_KEYUP, posted_key, MapVirtualKey(posted_key, MAPVK_VK_TO_VSC)))
{
print("Error while posting WM_KEYUP");
break;
}
}
return 0;
}
Now the messages posted are of a different pattern as you can see here. There seems to be a WM_CHAR
message of character code '83' posted in between the 3 expected messages for a character code of '119'. And then an extra '119' char code message after the WM_KEYUP
message.
As for my program behaviour, it does not exit abruptly anymore indicating that PostMessage
is returning a nonzero value.
The target application is however still behaving as if the key is being pressed down indefinitely.