Home > Net >  simulating "!" with keybd_event (or anything) in c (windows.h)
simulating "!" with keybd_event (or anything) in c (windows.h)

Time:12-16

! does not exist in the virtual key codes of Win32. Is there a way I could use keybd_event(), or anything else, to simulate a keyboard entry leading to !?

It's my first time making a bot to spam in a Discord casino (private).

CodePudding user response:

Since keybd_event has been superseded by SendInput, I suggest that you use that instead.

With SendInput you send a number of INPUT structures. You can send mouse input, keyboard input and hardware input. I'll show how to send keyboard input.

Keyboard input can be sent using scan codes - or Unicode characters. I'll use Unicode. Finding the unicode character for something you don't know is usually as easy as: https://www.google.com/search?q=unicode exclamation mark and you'll get the answer (U 0021 for !).

I'll start by inheriting the INPUT structure to make it simpler to instantiate it.

#include <Windows.h>

#include <iostream>
#include <vector>

struct mINPUT : INPUT {
    mINPUT() : INPUT{} {}    // make sure it's clean if default constructed.

    // this constructor prepares the structure for different kinds of input:
    mINPUT(DWORD type) : INPUT{type} {
        switch (type) {
        case INPUT_MOUSE:
            // use mi.
            break;
        case INPUT_KEYBOARD:
            // use ki.
            ki.dwFlags = KEYEVENTF_UNICODE;  // we'll use unicode
            break;
        case INPUT_HARDWARE:
            // use hi.
            break;
        }
    }
};
// two helper functions to create `mINPUT` structures from unicode values:
mINPUT key_down(char16_t unicode_char) {
    mINPUT rv{INPUT_KEYBOARD};
    rv.ki.wScan = unicode_char;
    return rv;
}

mINPUT key_up(char16_t unicode_char) {
    mINPUT rv{INPUT_KEYBOARD};
    rv.ki.dwFlags |= KEYEVENTF_KEYUP;
    rv.ki.wScan = unicode_char;
    return rv;
}
// A helper structure to prepare a sequence of events and functions to
// iteract with it
struct Inputs {
    UINT cInputs() const { return static_cast<UINT>(inputs.size()); }
    LPINPUT pInputs() { return inputs.data(); }
    int cbSize() const { return static_cast<int>(sizeof(INPUT)); }

    // A helper function to add both a key down and a key up event:
    void add_key_down_up(char16_t unicode_char) {
        inputs.push_back(key_down(unicode_char));
        inputs.push_back(key_up(unicode_char));
    }

    // A helper function to add down up events for a string:
    void add_string(const char16_t* str) {
        for (; *str;   str) {
            add_key_down_up(*str);
        }
    }

    UINT Send() {            // Send the stored events
        return SendInput(
            cInputs(),
            pInputs(),
            cbSize()        
        );
    }

    std::vector<mINPUT> inputs;
};
int main() {
    std::cout << "Switch to Notepad or some other app taking input" << std::endl;
    Sleep(5000);  // in 5 seconds, you should see the input

    // Put some events in an `Inputs` container at construction:
    Inputs x{{
        key_down(0x0021),
        key_up(0x0021),
    }};

    // Use the helper function to add key down   key up for `A`:
    x.add_key_down_up(u'A');

    // Add events for a full string
    x.add_string(u"Hello world");

    // Send the events:
    UINT rv = x.Send();
    
    std::cout << "Sent " << rv << " events\n";
}

If everything goes according to plan, it will send 26 events. WM_KEYDOWN for ! and WM_KEYUP for !, the same for A and all the characters in Hello world.


Note: For keys you have on your keyboard you can simplify the building of the event sequence:

    Inputs x{{
        key_down(u'!'),
        key_up(u'!'),
    }};

CodePudding user response:

use the ascii code of ! which is 33

  • Related