Input text to a different program

I am attempting to create a program to be able to output text to a text box in another program. If the program has a text box (like that of Windows Live Messenger), I want to be able to print text into it.

I would also like to be able to move and click the mouse based on co-ordinates. I did try this but it did not work. I used mouse_event() which I now know was completely incorrect. I am planning to start from scratch with a blank Windows GUI.

So, if anyone can tell me how I can output text (I know how to use virtual keys like VK_CONTROL, I want to be able to output strings, if that is possible), and how I can move and left-click with the mouse, it would be greatly appreciated.

Thanks.
Last edited on
It's a very classic Win32 question since 1995 (see Win32 group http://tinyurl.com/cmhb5g)
closed account (z05DSL3A)
I would also like to be able to move and click the mouse based on co-ordinates.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include"windows.h"

void LeftClick ( )
{  
  INPUT    Input={0};
  // left down 
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
  ::SendInput(1,&Input,sizeof(INPUT));

  // left up
  ::ZeroMemory(&Input,sizeof(INPUT));
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;
  ::SendInput(1,&Input,sizeof(INPUT));
}

void RightClick ( )
{  
  INPUT    Input={0};
  // right down 
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_RIGHTDOWN;
  ::SendInput(1,&Input,sizeof(INPUT));

  // right up
  ::ZeroMemory(&Input,sizeof(INPUT));
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_RIGHTUP;
  ::SendInput(1,&Input,sizeof(INPUT));
}

void MouseMove (int x, int y )
{  
  double fScreenWidth    = ::GetSystemMetrics( SM_CXSCREEN )-1; 
  double fScreenHeight  = ::GetSystemMetrics( SM_CYSCREEN )-1; 
  double fx = x*(65535.0f/fScreenWidth);
  double fy = y*(65535.0f/fScreenHeight);
  INPUT  Input={0};
  Input.type      = INPUT_MOUSE;
  Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
  Input.mi.dx = fx;
  Input.mi.dy = fy;
  ::SendInput(1,&Input,sizeof(INPUT));
}

int main()
{
    MouseMove(5,5);
    RightClick();

    return 0;
}
Thanks George and Grey wolf.

I cannot follow your link, George, as I am at school and Google groups has been blocked. I shall look at it at home.

Grey Wolf - I found those functions before but they did not work. I shall attempt it again later on.
closed account (z05DSL3A)
What version of windows are you using? I think it works on versions from 2000 onwards, but there is somthing in Vista that can block it (check the docs for SendInput() on MSDN).
Last edited on
I use either Vista or 7. Ideally I'd use XP but, whatever...
closed account (z05DSL3A)
Microsoft Windows Vista. This function fails when it is blocked by User Interface Privilege Isolation (UIPI). Note that neither GetLastError nor the return value will indicate the failure was caused by UIPI blocking.
From MSDN


You may need to read around User Interface Privilege Isolation (UIPI) to get a solution.

Ok.

Any ideas on the text input? Can it be done in the same way, or will I have to use single-keys (which is really out of the question (unless necessary) because I will be using quite long sentences).
closed account (z05DSL3A)
Nothing is springing to mind about injecting text into another applications controls, sorry.
Also, Grey Wolf, how do I use INPUT data type? It's not in windows.h.

How about a Flash/Shockwave game?
Last edited on
closed account (z05DSL3A)
The INPUT structure is a union of MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi;
So you first set the type (INPUT_MOUSE, INPUT_KEYBOARD, INPUT_HARDWARE), the set the respective data sructure.

eg
1
2
3
4
Input.type      = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
Input.mi.dx = fx;
Input.mi.dy = fy;

or
1
2
Input.type      = INPUT_KEYBOARD;
Input.ki.wVk =...


The MSDN info (what it is) is here:
http://msdn.microsoft.com/en-us/library/ms646270(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms646273(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms646271(VS.85).aspx
In that case I have done so. However it does not compile.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <cstdio>
#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

void MoveMouse();
void LeftClick();

typedef struct tagMOUSEINPUT {
    LONG dx;
    LONG dy;
    DWORD mouseData;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;

typedef struct tagKEYBDINPUT {
        WORD wVk;
        WORD wScan;
        DWORD dwFlags;
        DWORD time;
        ULONG_PTR dwExtraInfo;
    } KEYBDINPUT, *PKEYBDINPUT;

typedef struct tagINPUT { 
  DWORD type; 
  union {MOUSEINPUT mi; 
            KEYBDINPUT ki;
            // HARDWAREINPUT hi;
           };
}INPUT, *PINPUT;

int main() {
MoveMouse();
cin.get();
return  0;
}

void MoveMouse() {
int x, y;
double fScreenWidth  = ::GetSystemMetrics(SM_CXSCREEN)-1;
double fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN)-1;
double fx = x*(65535.0f/fScreenWidth);
double fy = y*(65535.0f/fScreenHeight);
INPUT Input = {0};
Input.type        = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
Input.mi.dx = fx;
Input.mi.dy = fy;
::SendInput(1,&Input,sizeof(INPUT));
}

void LeftClick() {  
INPUT    Input={0};
Input.type        = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
::SendInput(1,&Input,sizeof(INPUT));
::ZeroMemory(&Input,sizeof(INPUT));
Input.type      = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;
::SendInput(1,&Input,sizeof(INPUT));
}


Errors:
INPUT_MOUSE undeclared
::SendInput has not been declared


I also get the following warning:
Converting from LONG to double
Last edited on
closed account (z05DSL3A)
SendInput, INPUT, et al should all be available with including windows.h, I don't know why you are having a problem with them.
I can find SendInput, INPUT, etc. in winuser.h by doing ctrl-f (Find), they have this #if though: #if (_WIN32_WINNT >= 0x0403) which I tried to workaround with this: #define (_WIN32_WINNT >= 0x0404) , which almost certainly makes no sense, but it is still bigger than 0x0403 (I think... I don't know hex (or whatever that is... looks like some form of hex or unicode) :l)

For some reason I am unable to use them even though they are clearly defined here:
1
2
3
4
5
#if (_WIN32_WINNT >= 0x0403)
#define INPUT_MOUSE 0x00000000
#define INPUT_KEYBOARD 0x00000001
#define INPUT_HARDWARE 0x00000002
#endif /* (_WIN32_WINNT >= 0x0403) */ 


and here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
typedef struct tagMOUSEINPUT {
  LONG dx;
  LONG dy;
  DWORD mouseData;
  DWORD dwFlags;
  DWORD time;
  ULONG_PTR dwExtraInfo;
} MOUSEINPUT,*PMOUSEINPUT;
typedef struct tagKEYBDINPUT {
  WORD wVk;
  WORD wScan;
  DWORD dwFlags;
  DWORD time;
  ULONG_PTR dwExtraInfo;
} KEYBDINPUT,*PKEYBDINPUT;
typedef struct tagHARDWAREINPUT {
  DWORD uMsg;
  WORD wParamL;
  WORD wParamH;
} HARDWAREINPUT,*PHARDWAREINPUT;
typedef struct tagINPUT {
  DWORD type;
  _ANONYMOUS_UNION union {
		MOUSEINPUT mi;
		KEYBDINPUT ki;
		HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT,*PINPUT,*LPINPUT;


I have this code at the moment:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/********************************************************************************/
/* This is a simple dog program that can point-and-click and send what I will   */
/* call 'Bark streams' to another program -- the active window. That is, it     */
/* will output text to other programs and move around a p-a-c game's interface. */
/* I am hoping to add the possibility of colour detection, and at some point    */
/* a very simple decision tree.                                                 */
/********************************************************************************/
#define (_WIN32_WINNT >= 0x0404)
#include <windows.h>
// Defining SendInput() as for whatever reason it cannot work on it's own.
HRESULT __stdcall SendInput(
   BSTR Command,
   VARIANT_BOOL Execute
);

LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
// The Window Procedure -- this handles messages.

char szClassName[]="Dog"; /* The class name of the Window.
                             This is pretty pointless as we don't have a Window
                             but it can stay anyway.*/
class dog { /* The dog's class. I would use a simpler method but for some reason
               I have taken a liking to classes... */
public:
   void movemnt(        ); // Motion (SendInput)
   void brkout (        ); // Dog bark output
};

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszArgument, int nFunsterStil) { // There will be no window as we will not define one :P
                   
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); /* So that we do not 
eat too much processor time, we will make sure we only use non-allocated processor time. */

do {
dog dg;
dg.movemnt();
dg.brkout ();
Sleep(1000); /* To save a little more on processor time, we will sleep for one second after every loop.
               This also helps in that we will not move around and bark too often :P */
} while (true); /* Never ending loop -- we only want this process to close if it is closed by the user. 
                   As we have no window, they can only close from Task Manager anyway, so it doesn't matter.
                   But we still want to run the loop indefinately. */
return 0; // We completed with no errors.
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
   case WM_DESTROY:
       PostQuitMessage(0); // When the user attempts to exit, we will send the process to the exit queue.
   default:
       return DefWindowProc(hwnd, msg, lp, wp); /* For messages that we do not handle, 
                                                   we can return the default window procedure. */
} /* There are no other message cases because we don't have any expected messages -- 
     we just want WM_DESTROY. So we can leave the rest to DefWindowProc. */
return 0; // In the case that we don't get any messages, we can just return 0.
}

// The following is the only function which does not work.
void dog::movemnt() { // The dog will move around and click.
int x, y;
double fScreenWidth  = ::GetSystemMetrics(SM_CXSCREEN)-1;
double fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN)-1;
double fx = x*(65535.0f/fScreenWidth);
double fy = y*(65535.0f/fScreenHeight);
INPUT Input = {0};
Input.type        = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
Input.mi.dx = fx;
Input.mi.dy = fy;
::SendInput(1,&Input,sizeof(INPUT));
INPUT    Input={0};
Input.type        = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTDOWN;
::SendInput(1,&Input,sizeof(INPUT));
::ZeroMemory(&Input,sizeof(INPUT));
Input.type      = INPUT_MOUSE;
Input.mi.dwFlags  = MOUSEEVENTF_LEFTUP;
::SendInput(1,&Input,sizeof(INPUT));
}

void dog::brkout() { // The dog will output "woof woof" or similar.
// This remains unwritten as of yet.
}

Edit: I spelt queue wrong :l
Last edited on
Topic archived. No new replies allowed.