+ Reply to Thread
Results 1 to 4 of 4

Thread: [C++] Keyboard/Mouse emulation

  1. #1
    Learning Programmer Muted is on a distinguished road Muted's Avatar
    Join Date
    Jan 2009
    Location
    USA, Texas, Smithville (boonies)
    Posts
    51

    Arrow [C++] Keyboard/Mouse emulation

    Hello whomever!

    I've noticed there aren't alot of posts via Classes and Code Snippets, the ones that are here seem to be a little boring and rather useless (with the exception of the mouse emulation), so I've decided to post a few examples of how you could go about emulating key/mouse presses using C++. There'll be a very short list of links to a very useful and resourceful site after the examples are posted.

    I'll assume some of you are Blizzard fans, which can make this practical (StarCraft for ASCII art, Diablo II for Baal/Diablo runs, World of WarCraft, etc) usage for you, if you really put thought into it and not just copy & paste somebody elses code (I'm all for open-source code, but not learning is like watching TV without watching the commercials!).

    NOTE: These examples are compiled on the Windows Operating System using Dev-C++ 4.9.9.2

    First example - SendInput:
    Small note: This will work in channels on Battle.net

    Code:
    #include <iostream>
    #include <windows.h>
    #include <winable.h> /* Dev-C++ specific */
    using namespace std;
    
    /* HWND = "Window Handle" */
    HWND GameWindow = FindWindow(0, "Brood War");
    
    /* This is a function to simplify usage of sending keys */
    void GenerateKey(int vk, BOOL bExtended) {
    
        KEYBDINPUT  kb = {0};
        INPUT       Input = {0};
    
        /* Generate a "key down" */
        if (bExtended) { kb.dwFlags  = KEYEVENTF_EXTENDEDKEY; }
        kb.wVk  = vk;
        Input.type  = INPUT_KEYBOARD;
        Input.ki  = kb;
        SendInput(1, &Input, sizeof(Input));
    
        /* Generate a "key up" */
        ZeroMemory(&kb, sizeof(KEYBDINPUT));
        ZeroMemory(&Input, sizeof(INPUT));
        kb.dwFlags  =  KEYEVENTF_KEYUP;
        if (bExtended) { kb.dwFlags |= KEYEVENTF_EXTENDEDKEY; }
        kb.wVk = vk;
        Input.type = INPUT_KEYBOARD;
        Input.ki = kb;
        SendInput(1, &Input, sizeof(Input));
    
        return;
    }
    
    int main() {
    
        /*
           SetForegroundWindow will give the window focus for the
           keyboard/mouse! In other words, you don't have to have
           the game opened upfront in order to emulate key/mouse
           presses, it's very helpful if it's a game that runs
           in fullscreen mode, like StarCraft: Brood War does
        */
    
        SetForegroundWindow(GameWindow);
    
        GenerateKey(VK_CAPITAL, TRUE);
        GenerateKey('I', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey(VK_CAPITAL, TRUE);
        GenerateKey('A', FALSE);
        GenerateKey('M', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey('C', FALSE);
        GenerateKey('O', FALSE);
        GenerateKey('O', FALSE);
        GenerateKey('L', FALSE);
        GenerateKey('E', FALSE);
        GenerateKey('R', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey('T', FALSE);
        GenerateKey('H', FALSE);
        GenerateKey('A', FALSE);
        GenerateKey('N', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey('Y', FALSE);
        GenerateKey('O', FALSE);
        GenerateKey('U', FALSE);
        GenerateKey(' ', FALSE);
        
        GenerateKey('W', FALSE);
        GenerateKey('I', FALSE);
        GenerateKey('L', FALSE);
        GenerateKey('L', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey('E', FALSE);
        GenerateKey('V', FALSE);
        GenerateKey('E', FALSE);
        GenerateKey('R', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey('B', FALSE);
        GenerateKey('E', FALSE);
        GenerateKey('n', FALSE);
        GenerateKey(' ', FALSE);
    
        GenerateKey(0x3A, FALSE); /* period key */
        GenerateKey(0x0D, FALSE); /* enter key */
    
        return 0;
    }
    Second example - varation of SendInput:
    Small note: This will work in channels on Battle.net

    Code:
    #include <windows.h>
    #include <winable.h> /* Dev-C++ specific */
    using namespace std;
    
    /* HWND = "Window Handle" */
    HWND hWnd = FindWindow(0, "Brood War");
    
    void GenerateKey(BYTE vk) {
    
        INPUT Input;
        ZeroMemory(&Input, sizeof(Input));
        Input.type = INPUT_KEYBOARD;
        Input.ki.dwFlags = KEYEVENTF_EXTENDEDKEY;
        Input.ki.wVk = vk;
        SendInput(1, &Input, sizeof(INPUT));
    
        return;
    }
    
    int main() {
    
        SetForegroundWindow(hWnd);
    
        GenerateKey((UCHAR)VkKeyScan('C'));
        GenerateKey((UCHAR)VkKeyScan('o'));
        GenerateKey((UCHAR)VkKeyScan('d'));
        GenerateKey((UCHAR)VkKeyScan('i'));
        GenerateKey((UCHAR)VkKeyScan('n'));
        GenerateKey((UCHAR)VkKeyScan('g'));
        GenerateKey((UCHAR)VkKeyScan(' '));
        
        GenerateKey((UCHAR)VkKeyScan('i'));
        GenerateKey((UCHAR)VkKeyScan('s'));
        GenerateKey((UCHAR)VkKeyScan(' '));
        
        GenerateKey((UCHAR)VkKeyScan('f'));
        GenerateKey((UCHAR)VkKeyScan('u'));
        GenerateKey((UCHAR)VkKeyScan('n'));
        GenerateKey((UCHAR)VkKeyScan('.'));
        GenerateKey((UCHAR)VkKeyScan('\n')); /* enter key */
    
        return 0;
    }
    Third example - SendMessage (heavily unreliable and unpredictable):
    Small note: This will work not in channels on Battle.net, but will in games

    Code:
    #include <windows.h>
    #include <iostream>
    using namespace std;
    
    /* HWND = "Window handle" */
    HWND hwnd = FindWindow(0, "Brood War");
    
    void PressButton(HWND hwnd, BYTE vk)  {
    
        SendMessage(hwnd, vk, WM_KEYDOWN, 0);
    
        /* Due to Blizzard's latest patch, I had to change this to PostMessage */
        PostMessage(hwnd, WM_CHAR, vk, 0);
        SendMessage(hwnd, vk, WM_KEYUP, 0);
    }
    
    void TypeText(HWND hwnd, char String[]) {
    
        /* You could filter text in here if you wanted :) */
        for (int x = 0; String[x] != 0; x++) { PressButton(hwnd, String[x]); }
    }
    
    void DrawBox() {
    
        TypeText(hwnd, "\n      /-----\\     \n");
        Sleep(25);
        TypeText(hwnd, "\n      |     |     \n");
        Sleep(25);
        TypeText(hwnd, "\n      \\-----/     \n");
    
        return;
    }
    
    int main() {
    
        TypeText(hwnd, "\nThis is a really cool example! :)\n");
        Sleep(25); /* You must pause to give StarCraft time to respond */
        TypeText(hwnd, "\nUnfortuantly with Brood War, it only works while in-game... :(\n");
    
        Sleep(10000); /* Paused for a while so you can alt + tab to SC: BW and watch it be drawn */
    
        /* Here's an ideal ASCII art! */
        DrawBox();
    
        return 0;
    }
    SendInput can emulate not only keyboard input but also mouse input!
    Which I shall now demonstrate with a few examples... But before I do.
    This is a nifty little application to help find coordinates:

    Code:
    #include <iostream>
    #include <windows.h>
    
    int main () {
    
        POINT pos;
    
        while (true) {
            if (GetAsyncKeyState(VK_HOME)) {
                GetCursorPos(&pos);
                printf("%i - %i\n", pos.x, pos.y);
                Sleep(50);
                }
    
            if (GetAsyncKeyState(VK_END)) { break; }
        }
    
        return 0;
    }
    First example - SetCursorPos:
    Small note: This is just for pure fun, but can be used in conjunction with other stuff

    Code:
    #include <windows.h>
    
    int main () {
    
        /* A crazy mouse gone wild!! */
        while (true) {
            Sleep(rand() % 100);
            SetCursorPos(rand() % 500, rand() % 500);
        }
    
        return 0;
    }
    Second example - SendMessage (heavily unreliable and unpredictable):
    Small note: This is a very unreliable method, might/might not work with games/applications

    Code:
    #include <iostream>
    #include <windows.h>
    
    int main () {
    
        HWND hwnd = FindWindow(0, "Dev-C++ 4.9.9.2");
    
        /* This will NOT close Dev-C++, because Dev-C++ does not respond to the message */
        SetCursorPos(1269, 8);
        SendMessage(hwnd, WM_LBUTTONDOWN, 1269, 8);
        Sleep(25);
        SendMessage(hwnd, WM_LBUTTONUP, 1269, 8);
    
        return 0;
    }
    Third example - SendInput:
    Small note: This will work with any application
    Code:
    #include <iostream>
    #include <windows.h>
    #include <winable.h> /* Dev-C++ specific */
    using namespace std;
    
    int main() {
    
        /* This WILL close Dev-C++ with a resolution size of: 1280x1024 */
        SetCursorPos(1296, 8);
    
        INPUT Input[2];
        ZeroMemory(Input, sizeof(INPUT) * 2);
        Input[0].type = INPUT_MOUSE;
        Input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    
        Input[1].type = INPUT_MOUSE;
        Input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
        SendInput(2, Input, sizeof(INPUT));
    
        return 0;
    }
    Fourth example - SendInput:
    Small note: This will work with any application
    Code:
    #include <iostream>
    #include <windows.h>
    #include <winable.h> /* Dev-C++ specific */
    using namespace std;
    
    void Click(const int X, const int Y) {
    
        SetCursorPos(X, Y);
    
        INPUT Input[2];
        ZeroMemory(Input, sizeof(INPUT) * 2);
        Input[0].type = INPUT_MOUSE;
        Input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    
        Input[1].type = INPUT_MOUSE;
        Input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
        SendInput(2, Input, sizeof(INPUT));
        
        return;
    }
    
    int main() {
    
        HWND GameWindow = FindWindow(0, "Brood War");
        ShowWindow(GameWindow, SW_RESTORE);
    
        Sleep(2000);
        Click(49, 275);
        Sleep(2000);
        Click(488, 454);
        Sleep(2000);
        Click(514, 388);
    
        return 0;
    }
    That's all the examples I can possibly think of right now (they could be improved, but I'll leave that up to the readers (that's you!)).

    I hope this was helpful to somebody, and as I promised, here's a list of useful links:
    - Sleep: Sleep Function (Windows)
    - SendMessage: SendMessage Function ()
    - PostMessage: PostMessage Function ()

    - FindWindow: FindWindow Function ()
    - ShowWindow:ShowWindow Function ()
    - SetForegroundWindow: SetForegroundWindow Function ()

    - User Input branch: User Input
    - INPUT structure: INPUT Structure ()
    - KEYBDINPUT struct: KEYBDINPUT Structure ()
    - POINT struct: POINT Structure

    - SendInput: SendInput Function ()
    - VkKeyScan: VkKeyScan Function ()
    - GetAsyncKeyState: GetAsyncKeyState Function ()
    - ZeroMemory: ZeroMemory Macro (Windows)
    - GetCursorPos: GetCursorPos Function ()
    - SetCursorPos: SetCursorPos Function ()
    - List of Virtual Keys: List of Virtual Key Codes
    I don't like you, I don't have to.
    I'm here to learn, not please you.

  2. #2
    Newbie nicomorales is an unknown quantity at this point
    Join Date
    Feb 2009
    Posts
    1

    Re: [C++] Keyboard/Mouse emulation

    It was absolutely great and works fine for me!
    Let me ask you a question, I'm interested in using this kind of program to unlock a computer after logging into it with remote desktop, in order to avoid someone to go and type the login user and pass.

    What I should do is use some code like yours but i need to make focus on the login screen, does anybody knows how can i reference the windows login screen prompted when the computer is locked by remote desktop?

    Many Thanks for your help!

  3. #3
    Newbie HENDU is an unknown quantity at this point
    Join Date
    Feb 2009
    Posts
    1

    Re: [C++] Keyboard/Mouse emulation

    This is a very good example; I appreciate you putting this up... Now for a question .

    Any reason why a period would not show up?

    Thanks in advance!

  4. #4
    Learning Programmer Muted is on a distinguished road Muted's Avatar
    Join Date
    Jan 2009
    Location
    USA, Texas, Smithville (boonies)
    Posts
    51

    Re: [C++] Keyboard/Mouse emulation

    Let me ask you a question, I'm interested in using this kind of program to unlock a computer after logging into it with remote desktop, in order to avoid someone to go and type the login user and pass.
    I do not think that is possible, but it might be, I've never actually attempted something like that.
    You wouldn't need focus, you can use SendInput, because it clicks as if your mouse would.

    Any reason why a period would not show up?
    I'm unsure. It depends on a lot of things. Especially which one you're refering to.
    I don't like you, I don't have to.
    I'm here to learn, not please you.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Similar Threads

  1. Data Types for a Neural Network Emulation
    By nikomaster in forum C and C++
    Replies: 5
    Last Post: 03-04-2010, 06:01 PM

Bookmarks

Bookmarks

     
        Algorithms and Data Structures

        Java tutorials

        Algorithms Forum

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts