Jump to content

SendInput() Issues in C++


Recommended Posts

Hey everyone!

I've used AutoIt for many years and finally decided to try to convert one of my scripts into C++. Things are nearly done, but I am having issues with the SendInput() API.

Basically I am try to rewrite this script at this post

#631512

With my C++ project I cannot send Uppercase characters and special keys like Shift, Ctrl, and ALT. Any idea what I am doing wrong, or any suggestions?

#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x1337

#include <windows.h>
#include <iostream>
#include <winable.h> /* Dev-C++ specific */

using namespace std;

void GenerateKey(BYTE vk);
void  SendText(char *szText);
void keepAlive();
LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);
//char *szText = "Test";
/* HWND = "Window Handle" */
HWND hWnd = FindWindow(0, "Untitled - Notpad");
HHOOK keyboardHook;



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{

    keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProc, hInstance, 0);


    keepAlive();

    UnhookWindowsHookEx(keyboardHook);

    return 0;

}

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;
}

void  SendText(char *szText)
{
    for (int i=0;i<strlen(szText);i++)
    {
        GenerateKey( (UCHAR) VkKeyScan( szText[i] ) );
    }
}

LRESULT CALLBACK keyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) (lParam);

    // If key is being pressed
    if (wParam == WM_KEYDOWN)
    {

        switch (p->vkCode)
        {

            // Invisible keys
        case VK_SCROLL:
        {

            //SendText(szText);
            SendText("Some text to send.");

        }
        break;
        /*     case VK_LSHIFT:  // <These hotkeys don't matter at the moment because I am trying to get things working as is, but will enable them after
                   break;
               case VK_RSHIFT:
                   cout << "[RSHIFT]";
                   break;
               case VK_LCONTROL:
                   cout << "[LCTRL]";
                   break;
               case VK_RCONTROL:
                   cout << "[RCTRL]";
                   break;
               case VK_INSERT:
                   cout << "[INSERT]";
                   break;
               case VK_END:
                   cout << "[END]";
                   break;
               case VK_PRINT:
                   cout << "[PRINT]";
                   break;
                   */

        }

    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

void keepAlive()
{
    MSG message;
    while (GetMessage(&message,NULL,0,0))
    {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}
Link to comment
Share on other sites

Agent,

Long time no see, I hope all is well with you. I did a simple Google search for "sendinput example c" and the third or fourth website came up with this...

http://www.codeguru.com/forum/showthread.p...6&p=1325441

It seemed to contain the information you need. It doesn't seem you're including any keyup events. Also the one that links to the experts exchange had a keyup event so that may be useful to you as well...(the question has the correct code besides the actual call to SendInput() he was using sizeof(hisvariable) instead of sizeof(INPUT).

I hope this sets you in the right direction!

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

...he was using sizeof(hisvariable) instead of sizeof(INPUT).

The size of the variable will always be the size of the type. In other words, sizeof(Input) == sizeof(INPUT). It is not an error to write the former and in some cases it's better code. Think of some of the Microsoft structures where newer versions have a different size and where Microsoft determine the structure version based on the size. Using sizeof(STRUCTURE) you will have to change both the type of variable AND the call to sizeof() where-as if you use sizeof(structure_variable) you only change the type of variable and the size is correctly updated.
Link to comment
Share on other sites

The size of the variable will always be the size of the type. In other words, sizeof(Input) == sizeof(INPUT). It is not an error to write the former and in some cases it's better code. Think of some of the Microsoft structures where newer versions have a different size and where Microsoft determine the structure version based on the size. Using sizeof(STRUCTURE) you will have to change both the type of variable AND the call to sizeof() where-as if you use sizeof(structure_variable) you only change the type of variable and the size is correctly updated.

Thank you for clarifying that... I was taught to use sizeof(yourvariblename) instead of the sizeof(thestructureyoureusing). Maybe where this one went off is because it was a pointer. I don't know... I thought it odd that changing that was the solution to an Experts Exchange deal...

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

The pointer must be dereferenced, of course, otherwise it would return the sizeof the pointer.

#include <iostream>

class C
{
    int a;
    int b;
    int c;
};

int main(int, char*[], char*[])
{
    C c;
    C *p = &c;
    std::cout<<sizeof(c)<<std::endl;
    std::cout<<sizeof(p)<<std::endl;
    std::cout<<sizeof(*p)<<std::endl;
    std::cin.get();
    return 0;
}

That will print 12, 4 and 12 when compiled as 32-bits.

Link to comment
Share on other sites

Okay, I thought so, and the Experts Exchange just simply told him to do the size of the structure because he was simply passing the pointer. It solved his issue, and he was happy. Again thank you for the clarification. I am ever about learning the best, and easiest way (in that order) :) .

Thanks,

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

Actually, on second thought dereferencing the pointer might not be a good idea:

#include <iostream>

class Base
{
public:
    virtual ~Base() { }
private:
    int padding1;
    int padding2;
    int padding3;
};

class Derived : public Base
{
    int a;
    int b;
};

int main(int, char*[], char*[])
{
    Derived d;
    Base *b = &d;
    std::cout<<sizeof(d)<<std::endl;
    std::cout<<sizeof(b)<<std::endl;
    std::cout<<sizeof(*b)<<std::endl;
    std::cout<<sizeof(Base)<<std::endl;
    std::cin.get();
    return 0;
}

Prints 24, 4, 16 and 16 as 32-bits.

Link to comment
Share on other sites

Okay now I'm confused as to whether or not de-referencing or calling sizeof on the type is the acceptable method? I know obviously sizeof(type) works. It would appear the de-referencing works...I see where Derived is printing 24, and dereferenced is showing 16 (the base class) since that is it's type. I added to your example... let me know if I am understanding dereferencing properly...

#include <iostream>

class Base
{
public:
    virtual ~Base() { }
private:
    int padding1;
    int padding2;
    int padding3;
};

class Derived : public Base
{
    int a;
    int b;
};

int main(int, char*[], char*[])
{
    Derived d;
    Base *b = &d;
    Derived *ptrD = &d;
    std::cout<<sizeof(d)<<std::endl;
    std::cout<<sizeof(Derived)<<std::endl;
    std::cout<<sizeof(b)<<std::endl;
    std::cout<<sizeof(*b)<<std::endl;
    std::cout<<sizeof(Base)<<std::endl;
    std::cout<<sizeof(ptrD)<<std::endl;
    std::cout<<sizeof(*ptrD)<<std::endl;
    std::cin.get();
    return 0;
}

ptrD = 4 because it is a pointer

*ptrD = 24 because it's type is Derived

*b = 16 because it's type is Base

It would seem the last line is correct, but looking up in the code, I see where you assigned the base pointer to the address of the derived class. What does this do, and why doesn't sizeof reflect this?

Thanks,

Jarvis

AutoIt Links

File-String Hash Plugin Updated! 04-02-2008 Plugins have been discontinued. I just found out.

ComputerGetInfo UDF's Updated! 11-23-2006

External Links

Vortex Revolutions Engineer / Inventor (Web, Desktop, and Mobile Applications, Hardware Gizmos, Consulting, and more)

Link to comment
Share on other sites

...I see where you assigned the base pointer to the address of the derived class. What does this do, and why doesn't sizeof reflect this?

In a real example Base would be a pure virtual class defining an interface (dry-coded):

#include <iostream>
 
 class Base
 {
 public:
     virtual ~Base() { }    // Destructor
 
     virtual void Method() = 0;
 };
 
 class Derived1 : public Base
 {
 public:
     virtual ~Derived1() { }    // Destructor
 
     virtual void Method() { std::cout<<"Derived1::Method()"<<std::endl; }
 };
 
 class Derived2 : public Base
{
public:
     virtual ~Derived2() { }    // Destructor
   
     virtual void Method() { std::cout<<"Derived2::Method()"<<std::endl; }
};
 
 int main()
 {
     Derived1 d1;
     Derived2 d2;
     Base *pBase = &d1;
     pBase->Method();
     pBase = &d2;
     pBase->Method();
 
     std::cin.get();
     return 0;
 }

The reason sizeof() shows the size of Base in my last post is because it the pointer is of type Base. When dereferncing the pointer only Base members can be accessed. Even though in memory the Derived data is there for that object, it cannot be acessed because the pointer only points to an object of type Base.

Edited by Valik
Typo
Link to comment
Share on other sites

Agent,

Long time no see, I hope all is well with you. I did a simple Google search for "sendinput example c" and the third or fourth website came up with this...

http://www.codeguru.com/forum/showthread.p...6&p=1325441

It seemed to contain the information you need. It doesn't seem you're including any keyup events. Also the one that links to the experts exchange had a keyup event so that may be useful to you as well...(the question has the correct code besides the actual call to SendInput() he was using sizeof(hisvariable) instead of sizeof(INPUT).

I hope this sets you in the right direction!

Jarvis

I've been searching google for awhile of the sendinput API. I will look a little more closely at the link you gave me.

Also I found a great example of another implemtation of the SendInput API

http://www.google.com/codesearch/p?hl=en&a...amp;q=SendInput

[EDIT]

This is a fully working example of sending strings...

http://social.msdn.microsoft.com/Forums/en...d1-c8b6d7158c71

Edited by AgentSmith15
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...