-1

pardon me for making a file if something relevant already exists but I have searched for too long and my head has almost melted.

So, to the point. Can someone describe to me the code that I need to write to have a c++ application send the same signal as when I manually press the keys 'ctrl' and 'a' at the same time?

I found, among many others, this link:

http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=VS.90).aspx

Apparently, though, function does not work. I tried to use:

using namespace System::Windows::Forms;

But, it does nothing.

Apparently I need to include code. This is my code. I know the basics and yes I can read. So, I have included that:

#define _WIN32_WINNT 0x0501
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <winable.h> /* Dev-C++ specific */

using namespace std;

HWND GameWindow = FindWindow(0, "C:\\Users\\...\\src\\output1.txt");


/* 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() {


    system("start C:\\Users\\...\\src\\output1.txt");
    SetForegroundWindow(GameWindow);

    GenerateKey ('A', FALSE);
    GenerateKey (VK_CAPITAL, TRUE);

    GenerateKey(0x0D, FALSE); /* enter key */

    getch();
    return 0;
}

Now my problem is that, the program is not actually writing this A onto that .txt file.

NOTE: It works if ran from CMD, printing the 'A' on the actual CMD.

kxk
  • 576
  • 2
  • 11
  • 30
  • `using namespace System.Windows.Forms;` isn't valid C or C++ code. Do you know C or C++ at all? Why don't you pick a single one? – GManNickG Sep 06 '11 at 19:16
  • Yeah, ok. Can you tell me how to do what I am asking? – kxk Sep 06 '11 at 19:21
  • Could you give us some context at least? Some code would be nice too. – Daniel Sep 06 '11 at 19:27
  • Are you using C++, C, or C++/CLI? – Marlon Sep 06 '11 at 19:28
  • @ Marlon: I am using C++ @ Daniel: What kind of context do you need man? I am asking for something deterministic. If you know how to do it, tell me. I have no context. I just want to have a document open, set focus and ctrl+a on it. – kxk Sep 06 '11 at 19:32
  • Can you describe your scenario? Instead of simulating keypresses, it sounds like you want to select all text, which you can do with UI automation. – Raymond Chen Sep 06 '11 at 19:34
  • @Raymond: All I want is basically to open a pdf file, focus the window, hit ctrl+a to select all of the content, then press ctrl+c to copy the whole content and then I want to open a new .txt file, focus it, and paste the bloody thing with ctrl+v. – kxk Sep 06 '11 at 19:37
  • @devilwontcry I think you'll find it easier automating the Edit.SelectAll and Edit.Copy menu items than trying to simulate keyboard input. – Raymond Chen Sep 06 '11 at 19:45
  • @Raymond: I am not really sure why it would be easier. It feels so deterministic! A+B=C.... Anyway. As it seems, you are right. Can you give me some more info on those Edit.SelectAll and Edit.Copy items? – kxk Sep 06 '11 at 19:49
  • Automating the menu item avoids focus race conditions. You can look at Windows UI Automation and ask specific questions if you are having difficulty with it. – Raymond Chen Sep 06 '11 at 20:59

2 Answers2

2

Have a look at the SendInput from the Windows API.

Example copy pasted from codeguru forums:

void GenerateKey ( int vk , BOOL bExtended)
{
  KEYBDINPUT  kb={0};
  INPUT    Input={0};
  // generate down 
  if ( bExtended )
    kb.dwFlags  = KEYEVENTF_EXTENDEDKEY;
  kb.wVk  = vk;  
  Input.type  = INPUT_KEYBOARD;

  Input.ki  = kb;
  ::SendInput(1,&Input,sizeof(Input));

  // generate 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));
}

Usage:

GenerateKey ('A', FALSE);
GenerateKey (VK_CAPITAL, TRUE);
GenerateKey ('A', FALSE);

Also, to send keyboard input to another process you will need AttachThreadInput.

Gregory Pakosz
  • 69,011
  • 20
  • 139
  • 164
  • I am reading this, but I am failing on understand it... Can you show me a code snippet for it? – kxk Sep 06 '11 at 19:29
  • 1
    @devil: What part don't you understand? – GManNickG Sep 06 '11 at 19:34
  • @GMan: I am apparently stupid, but I read this link and yet I do not understand how to do it. Could you please show me how? – kxk Sep 06 '11 at 19:35
  • 1
    @devil: You're not stupid. That said, you need to learn to program if you want to program, you can't just go around looking for code to copy and paste without understanding it. Sorry, but for your own good you ought to take the time to really learn C++, from a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Then you'll have no problem identifying any further confusion (for example, how to use a Windows API function), and understanding the rest. – GManNickG Sep 06 '11 at 19:39
  • @devilwontcry next time help yourself, try things! your keyboard won't bite you. or... use google – Gregory Pakosz Sep 06 '11 at 19:41
  • @GMan you're so right, however the question is exotic enough to let a code sample live in an answer here imho – Gregory Pakosz Sep 06 '11 at 19:42
0

I'd look at the AutoHotKey source.

Edit: added github link

Digikata
  • 1,821
  • 17
  • 25