AgentSmith15 Posted July 6, 2009 Posted July 6, 2009 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#631512With 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?expandcollapse popup#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 ); } } [center][/center]
Richard Robertson Posted July 6, 2009 Posted July 6, 2009 When typing a capital letter, you first hold shift and then press the letter, then let go right? It works exactly the same way in code.
AgentSmith15 Posted July 6, 2009 Author Posted July 6, 2009 (edited) So according to the MSDN I have to use the plus sign to create a capitol letter. So yea I feel like a idiot... I launched Code::Blocks and changed the source to SendText("+Some text to send."); and it outputs =some text to send. Why is that? Edited July 6, 2009 by AgentSmith15 [center][/center]
Richard Robertson Posted July 6, 2009 Posted July 6, 2009 That function is from an object that is used in scripting.
JSThePatriot Posted July 6, 2009 Posted July 6, 2009 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=1325441It 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)
Valik Posted July 6, 2009 Posted July 6, 2009 ...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.
JSThePatriot Posted July 6, 2009 Posted July 6, 2009 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)
Valik Posted July 6, 2009 Posted July 6, 2009 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.
JSThePatriot Posted July 6, 2009 Posted July 6, 2009 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)
Valik Posted July 6, 2009 Posted July 6, 2009 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.
JSThePatriot Posted July 6, 2009 Posted July 6, 2009 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)
Valik Posted July 6, 2009 Posted July 6, 2009 (edited) ...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): expandcollapse popup#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 July 6, 2009 by Valik Typo
JSThePatriot Posted July 6, 2009 Posted July 6, 2009 Thanks Valik... that is making sense. 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)
AgentSmith15 Posted July 7, 2009 Author Posted July 7, 2009 (edited) 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 July 7, 2009 by AgentSmith15 [center][/center]
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now