-3

WM_KEYUP in PostMessage and SendMessage doesn't work

I tried change ASCII code from 0x57 to 0x005701, because my friend says it should work, but it doesn't.

#include <iostream>
#include <windows.h>

using namespace std;

int KEY_DOWN = 0x57;

int main()
{
    HWND hwnd;
    if (!(hwnd = FindWindow(L"AAAA", NULL))) {
        cout << "Couldn't find window";
    }
    else {
        Sleep(5000);
        PostMessage(hwnd, WM_SETFOCUS, NULL, NULL);
        PostMessage(hwnd, WM_KEYDOWN, KEY_DOWN, NULL);
    }
}

I want to make application that will send WM_KEYDOWN, and WM_KEYUP to application with PostMessage or SendMessage but WM_KEYUP doesn't work

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    You didn't show any code that is trying to post `WM_KEYUP`. Read the documentation for [WM_KEYDOWN](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-keydown) and [WM_KEYUP](https://learn.microsoft.com/en-us/windows/win32/inputdev/wm-keyup), there is more involved than just the key code. However, [You can't simulate keyboard input with PostMessage](https://devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513), consider using UI Automation APIs instead. What are you ultimately trying to accomplish? – Remy Lebeau Aug 01 '19 at 17:34
  • Oh... I forgot to add this to code... ```PostMessage(hwnd, WM_KEYUP, 0x57, NULL);``` – FreshyCfelu Aug 01 '19 at 18:02
  • 2
    What would you expect to happen, and what evidence do you have that your expectation is correct? – David Heffernan Aug 01 '19 at 18:08
  • I expect it will click w up and down – FreshyCfelu Aug 01 '19 at 20:06
  • There's no reason for you to expect that to happen. If you want to fake input, SendInput is the API to use. – David Heffernan Aug 01 '19 at 20:11

1 Answers1

0

As @David Heffernan said that, SendInput can do this.

This is the least code.

#include <iostream>
#include <Windows.h>

using namespace std;

int main()
{
    HWND hwnd;
    INPUT input[2];
    memset(input, 0, sizeof(input));
    if (!(hwnd = FindWindow(L"AAAA", NULL)))
    {
        cout << "Couldn't find window";
    }
    else
    {
        Sleep(5000);
        input[0].type = input[1].type = INPUT_KEYBOARD;

        SetForegroundWindow(hwnd);

        input[0].ki.wVk = 'W';
        input[0].ki.dwFlags = 0;
        input[1].ki.wVk = 'W';
        input[1].ki.dwFlags = KEYEVENTF_KEYUP;
        SendInput(2, input, sizeof(INPUT));
    }

    return 0;
}

Put the key down and key up events into an array of length 2 and send them as a single atomic unit.

Set the value of ki.dwFlags to control up and down states of the key.

Strive Sun
  • 5,988
  • 1
  • 9
  • 26
  • Almost certainly a mistake to call SendInput for keyboard input with the first argument equal to 1. Build an array of input and send it as an atomic unit. – David Heffernan Aug 02 '19 at 04:53
  • @DavidHeffernan I modify. – Strive Sun Aug 02 '19 at 06:48
  • Nope. An array with both down and up events. As I said, first arg of 1 is almost always a mistake. Should be an even number. – David Heffernan Aug 02 '19 at 06:51
  • @DavidHeffernan I'm sorry. But I've seen some [information](https://stackoverflow.com/questions/18647053/sendinput-not-equal-to-pressing-key-manually-on-keyboard-in-c). Just reset ki. dwFlags = KEYEVENTF_KEYUP and send keystrokes again to achieve the upward effect. – Strive Sun Aug 02 '19 at 06:58
  • That is bad advice. Consider reading the official Microsoft documentation. Heck, you linked to it in the answer. The key word there is "interspersed". – David Heffernan Aug 02 '19 at 07:03
  • @DavidHeffernan What is "interspersed" ? I did some tests with `GetAsyncKeyState`, and the result shows that the upward effect exists. – Strive Sun Aug 02 '19 at 07:41
  • "interspersed" is a word whose meaning is described in every decent English dictionary. The only conclusion I draw from your testing is that your test cases are insufficient. You have not tested cases where interspersion occurs. Consider what happens when another program calls `SendInput` while your `Sleep(5000)` is happening. – David Heffernan Aug 02 '19 at 07:43
  • Also, consider what happens if the second input event that you faked is processed before you call `GetAsyncKeyState`. All in all this answer contains any number of bad practises and is not to be commended. – David Heffernan Aug 02 '19 at 07:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/197375/discussion-between-strive-sun-msft-and-david-heffernan). – Strive Sun Aug 02 '19 at 07:52
  • @Strive Sun - MSFT Can you explain me this code, because I can't understend? And how to do key_down using sendinput? – FreshyCfelu Aug 02 '19 at 21:14
  • @FreshyCfelu The first parameter of SendInput is the operand you want to perform, because you only need two operations, key_down and key_up, so you only need two Input arrays. The second parameter is the event to insert the keyboard or mouse input stream, because you need to simulate the keyboard input, so input [0]. type = input [1]. type = INPUT_KEYBOARD, then set the relevant structure parameters in the keyboard event, set input [1]. ki. wVk ='W', which means the virtual key set is'W', followed by input [1]. ki. D. WFlags = KEYEVENT_KEYUP means that the second operation is key_up. – Strive Sun Aug 03 '19 at 03:01
  • @Strive Sun - MSFT thank you very much! – FreshyCfelu Aug 03 '19 at 07:45