Jump to content
Sign in to follow this  
whoa2k

C/C++ - WinAPI | WinWaitActive() & Send()

Recommended Posts

whoa2k

Any idea how to implement these two AutoIt functions in C/C++ ?

Share this post


Link to post
Share on other sites
matwachich

For the first: a loop, GetForegroundWindow, GetWindowText, StrStr

The second: SendInput

PS: => MSDN

Share this post


Link to post
Share on other sites
funkey

Hello,
I just build a function similar to AutoIt's Send() function. To keep it more easy I just made a second function named SendVK() t send virtual key codes. Maybe someone likes it!
 

#include <Windows.h>
#include <tchar.h>
#include <string>

#ifdef _UNICODE
#    define tstring std::wstring
#else
#    define tstring std::string
#endif

void Send(const TCHAR *CharacterString, HWND hKeepActive)
{
    TCHAR cChar, FiLoBuffer[32];
    INPUT Input = { 0 };
    KEYBDINPUT kb = { 0 };
    int iModifiers = 0;
    int iUpDown = 0;
    BOOL bNoMoreModifier;

    cChar = *CharacterString;
    BlockInput(TRUE);
    while ((cChar))
    {
        if (hKeepActive != NULL)
        {
            if (IsIconic(hKeepActive)) ShowWindow(hKeepActive, SW_RESTORE);
            if (hKeepActive != GetForegroundWindow()) SetForegroundWindow(hKeepActive);
        }
        ZeroMemory(&kb, sizeof(KEYBDINPUT));
        bNoMoreModifier = FALSE;
        switch (cChar)
        {
        case '!':
            kb.wVk = VK_MENU;
            FiLoBuffer[iModifiers++] = VK_MENU;
            break;
        case '+':
            kb.wVk = VK_SHIFT;
            FiLoBuffer[iModifiers++] = VK_SHIFT;
            break;
        case '^':
            kb.wVk = VK_CONTROL;
            FiLoBuffer[iModifiers++] = VK_CONTROL;
            break;
        case '#':
            kb.wVk = VK_RWIN;
            FiLoBuffer[iModifiers++] = VK_RWIN;
            break;
        default:
            bNoMoreModifier = TRUE;
            break;
        }

        if ((iModifiers > 0) && bNoMoreModifier)    //First char after modifierer
        {
            if ((cChar > 0x60) && (cChar < 0x7b))
                kb.wVk = cChar - 0x20;
            else
                kb.wVk = cChar;

            kb.wScan = 0;
        }
        else if (iModifiers > 0)
        {
            kb.wScan = 0;
        }
        else
        {
            kb.wVk = 0;
            kb.wScan = cChar;
        }
        kb.dwFlags = KEYEVENTF_UNICODE;
        Input.type = INPUT_KEYBOARD;
        Input.ki = kb;
        SendInput(1, &Input, sizeof(Input));

        if ((iModifiers == 0) || (bNoMoreModifier))
        {
            if (iModifiers != 0)
            {
                if ((cChar > 0x60) && (cChar < 0x7b))
                    kb.wVk = cChar - 0x20;
                else
                    kb.wVk = cChar;
                kb.wScan = 0;
            }
            else
            {
                kb.wVk = 0;
                kb.wScan = cChar;
            }
            kb.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
            Input.type = INPUT_KEYBOARD;
            Input.ki = kb;
            SendInput(1, &Input, sizeof(Input));
        }

        if ((bNoMoreModifier || (CharacterString[1] == NULL)) && (iModifiers > 0))
        {
            for (int i = iModifiers - 1; i >= 0; i--)
            {
                kb.wVk = FiLoBuffer[i];
                kb.wScan = 0;
                kb.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
                Input.type = INPUT_KEYBOARD;
                Input.ki = kb;
                SendInput(1, &Input, sizeof(Input));
                FiLoBuffer[i] = 0;
            }
            iModifiers = 0;
        }

        cChar = *++CharacterString;
    }
    BlockInput(FALSE);
}

/*        0 = down & up, 1 = down , 2 = up        */
void SendVK(WORD vk, HWND hKeepActive, int iUpDown)
{
    INPUT Input = { 0 };
    KEYBDINPUT kb = { 0 };

    if (hKeepActive != NULL)
    {
        if (IsIconic(hKeepActive)) ShowWindow(hKeepActive, SW_RESTORE);
        if (hKeepActive != GetForegroundWindow()) SetForegroundWindow(hKeepActive);
    }

    if ((iUpDown == 0) || (iUpDown == 1))
    {
        kb.wVk = vk;
        kb.wScan = 0;
        kb.dwFlags = KEYEVENTF_UNICODE;
        Input.type = INPUT_KEYBOARD;
        Input.ki = kb;
        SendInput(1, &Input, sizeof(Input));
    }

    if ((iUpDown == 0) || (iUpDown == 2))
    {
        kb.wVk = vk;
        kb.wScan = 0;
        kb.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
        Input.type = INPUT_KEYBOARD;
        Input.ki = kb;
        SendInput(1, &Input, sizeof(Input));
    }
}

//int _tmain(int, char**)
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    HWND hNotepad = FindWindow(_T("Notepad"), NULL);
    if (hNotepad == NULL)
    {
        MessageBox(NULL, _T("Please open notepad!"), _T("Information"),
            MB_ICONINFORMATION);
        return 0;
    }

    Sleep(500);

    Send(_T("Hello\nmy\tfriends+1^a"), hNotepad);
    Sleep(2000);

    SendVK(VK_END, hNotepad, 0);
    SendVK(VkKeyScan('^'), hNotepad, 0);
    SendVK(VkKeyScan('#'), hNotepad, 0);
    SendVK(VkKeyScan('+'), hNotepad, 0);

    Send(_T("#r"), NULL);

    Sleep(500);
    SendVK(VK_F4, NULL, 0);
    SendVK(VK_DOWN, NULL, 0);

    return 0;
}

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Share this post


Link to post
Share on other sites
LarryDalooza

AutoIt also gets around Windows enforcement of a process not "stealing" focus from the foreground window in it's "WinActivate" functionality. That nuance is an example of other things that AutoIt does that are not just straight ports of Windows API.


f_mrcleansmalm_77ce002.jpgAutoIt has helped make me wealthy

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×