1.11M Members

Simulate Mouse Move

 
0
 

Hi,
I'm using windows XP and trying to simulate mouse movement and mouse clicks. The following code supposed to move mouse to absolute position (100,100) and perform a click:

//test.cpp file:

#include "stdafx.h"

int main(int argc, char* argv[]){
	INPUT *buffer = new INPUT[3]; //allocate a buffer
	buffer->type = INPUT_MOUSE;
	buffer->mi.dx = 100;
	buffer->mi.dy = 100;
	buffer->mi.mouseData = 0;
	buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
	buffer->mi.time = 0;
	buffer->mi.dwExtraInfo = 0;

	(buffer+1)->type = INPUT_MOUSE;
	(buffer+1)->mi.dx = 100;
	(buffer+1)->mi.dy = 100;
	(buffer+1)->mi.mouseData = 0;
	(buffer+1)->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
	(buffer+1)->mi.time = 0;
	(buffer+1)->mi.dwExtraInfo = 0;

	(buffer+2)->type = INPUT_MOUSE;
	(buffer+2)->mi.dx = 100;
	(buffer+2)->mi.dy = 100;
	(buffer+2)->mi.mouseData = 0;
	(buffer+2)->mi.dwFlags = MOUSEEVENTF_LEFTUP;
	(buffer+2)->mi.time = 0;
	(buffer+2)->mi.dwExtraInfo = 0;


	SendInput(3,buffer,sizeof(INPUT));
	delete (buffer); //clean up our messes.
	return 0;
}

when "stdafx.h" is:

#pragma once
#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0500                 // so the code would compile
#include <windows.h>

The problem is that the mouse moves to position (0,0) and performs a click. I've been unable so far to simulate mouse movement to any absolute coordinate (x,y) specified in mi.dx and mi.dy respectively.
If someone knows a way to force mouse to move to absolute position (x,y) please tell me...

 
0
 

#include <windows.h> , i need the code for the header file, so that the functions inbuilt their with certain arguments and pointers can be changed,

 
0
 

Good point! Perhaps no user in the world can move a mouse that fast under normal conditions—but hey, it could happen! And in the old days of Windows 3.1, it may have been more likely. This is why Windows does, in fact, provide a way to get the mouse coordinates at the time any given message was sent.
Normally, a message arrives at your app when Windows calls your app's window proc. This callback function receives the HWND, message ID, WPARAM, and LPARAM. But actually, it's a little more complicated than that. Your app doesn't just get messages like a thunderbolt from the blue; it must fetch them by calling ::GetMessage. That's why 16-bit Windows (Windows 3.1) is called a cooperative, nonpreemptive multitasking operating system. In those days this held true globally; nowadays we know 32-bit versions of Windows are true (preemptive) multitasking systems. Nevertheless, within a process or thread, you still must call ::GetMessage and ::DispatchMessage to process messages in an orderly, synchronized fashion. Most every process or User Interface thread contains a central Get/Dispatch loop. This loop is called the message pump.
GetMessage retrieves the next message in the queue by filling a special MSG structure.

struct MSG {
    HWND        hwnd;
    UINT        message;
    WPARAM      wParam;
    LPARAM      lParam;
    DWORD       time;
    POINT       pt;
 };

The first four members are the familiar window proc arguments; MSG.time is (what else?) the time the message was sent, and MSG.pt holds the mouse position in screen coordinates when the message was sent.
MSG.pt is just what you want. The only problem is, how do you get it? When an app (MFC or otherwise) calls ::DispatchMessage to dispatch the message, Windows calls the appropriate window proc with hwnd, message, wParam, and lParam. The time and pt get lost in the shuffle. In a C app, you could make the MSG a global, so your window proc and message handler functions could access it. But with MFC, the message pump is buried in the framework, in CWinThread::PumpMessage. So how can you get the rest of the information in the MSG?
Fortunately, CWinThread retrieves the MSG into a CWinThread data member, m_curMsg. You can get the MSG from this public member, but before you go racing to the keyboard, there's an easier way: just call ::GetMessagePos. (There's also ::GetMessageTime to get the time.) GetMessagePos returns the position of the cursor when the last message was retrieved using GetMessage.
Just remember: not all messages are queued. When you or someone else calls SendMessage to send a message to a window, Windows calls the window's window proc directly—without queueing the message. Only truly external events such as user input (mouse or keyboard), hardware interrupts, and messages sent with ::PostMessage are queued. This is generally not a problem, since you are usually not interested in knowing the mouse position or time when some part of your app called SendMessage. (What meaning could it have?) Rather, you're usually interested in the mouse position or time when some real event occurred such as a mouse click or keystroke.
MFC itself uses GetMessageTime and GetMessagePos to implement a function you can use to get the current MSG: CWnd::GetCurrentMessage.

const MSG* PASCAL CWnd::GetCurrentMessage()
 {
     // fill in time and position when asked for
     _AFX_THREAD_STATE* pThreadState = 
         _afxThreadState.GetData();
     pThreadState->m_lastSentMsg.time = 
         ::GetMessageTime();
     pThreadState->m_lastSentMsg.pt = 
         CPoint(::GetMessagePos());
     return &pThreadState->m_lastSentMsg;
 }

All messages sent—and now I mean sent, not queued—to your window go through AfxCallWndProc (see the previous question). This function remembers the current message in the thread state, in a m_lastSentMsg member.

LRESULT AFXAPI AfxCallWndProc(CWnd* pWnd, 
     HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
 {
   _AFX_THREAD_STATE* pThreadState =  
   _afxThreadState.GetData();
   MSG oldState = pThreadState->m_lastSentMsg;   
   // save for nesting
   pThreadState->m_lastSentMsg.hwnd = hWnd;
   pThreadState->m_lastSentMsg.message = nMsg;
   pThreadState->m_lastSentMsg.wParam = wParam;
   pThreadState->m_lastSentMsg.lParam = lParam;
     .
     .
     .
   // process message
   pThreadState->m_lastSentMsg = oldState;
   return lResult;
 }

GetCurrentMessage simply returns a pointer to m_lastSentMsg (const, so you can't munge it!) after updating the time and pt fields with GetMessageTime and GetMessagePos. AfxCallWndProc doesn't bother to do this because it's a waste of CPU cycles. Very rarely do you care what the message time and cursor position are, so why copy those extra bytes for every message sent? If you need these values, you can call GetCurrentMessage. But once again you have to be careful. GetCurrentMessage returns the current message—whether queued or sent; if for some reason you want to know what the currently queued message was, you have to look in CWinThread::m_curMsg. In either case, the time and pt fields will be the same, since GetMessageTime and GetMessagePos return their respective values for the last message retrieved with GetMessage—that is, the last queued message.
If all that seems confusing, it is. The short answer is: call ::GetMessagePos or CWnd::GetMessage, whichever tickles your fancy. Ta-ta!

 
0
 

to WebHoststalk:
Here are the sources, compiled in VC++ 6.0.

Attachments test.zip (5.57KB)
 
0
 

to meabed:
Hi, I appreciate very much your thorough explanation, but what I need is not getting mouse pointer coordinates, rather setting them. I want to move using my program mouse pointer so specified absolute (x,y) coordinates on the screen and perform a mouse click... The problem is that I can't get mouse to move to (x,y) coordinates, only to (0,0), regardless of what I specifiy in mi.dx, mi.dy.

 
0
 

mate, well u have sent me the source code of the file,

i need the source of windows.h file, as pointed here,

#pragma once

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0500 // add this line

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>

#include <windows.h>

the double Quoted File.

 
0
 

try to add following code in stdafx.h

#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _WIN32_WINNT 0x0500 // so the code would compile
#include <windows.h>
    
    Hi,
    I'm using windows XP and trying to simulate mouse movement and mouse clicks. The following code supposed to move mouse to absolute position (100,100) and perform a click:
    //test.cpp file:
    #include "stdafx.h"
    int main(int argc, char* argv[]){
    INPUT *buffer = new INPUT[3]; //allocate a buffer
    buffer->type = INPUT_MOUSE;
    buffer->mi.dx = 100;
    buffer->mi.dy = 100;
    buffer->mi.mouseData = 0;
    buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
    buffer->mi.time = 0;
    buffer->mi.dwExtraInfo = 0;
    (buffer+1)->type = INPUT_MOUSE;
    (buffer+1)->mi.dx = 100;
    (buffer+1)->mi.dy = 100;
    (buffer+1)->mi.mouseData = 0;
    (buffer+1)->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    (buffer+1)->mi.time = 0;
    (buffer+1)->mi.dwExtraInfo = 0;
    (buffer+2)->type = INPUT_MOUSE;
    (buffer+2)->mi.dx = 100;
    (buffer+2)->mi.dy = 100;
    (buffer+2)->mi.mouseData = 0;
    (buffer+2)->mi.dwFlags = MOUSEEVENTF_LEFTUP;
    (buffer+2)->mi.time = 0;
    (buffer+2)->mi.dwExtraInfo = 0;
    
    SendInput(3,buffer,sizeof(INPUT));
    delete (buffer); //clean up our messes.
    return 0;
    }
    when "stdafx.h" is:
    #pragma once
    #define WIN32_LEAN_AND_MEAN       // Exclude rarely-used stuff from Windows headers
    #define _WIN32_WINNT 0x0500                 // so the code would compile
    #include <windows.h>
    
    The problem is that the mouse moves to position (0,0) and performs a click. I've been unable so far to simulate mouse movement to any absolute coordinate (x,y) specified in mi.dx and mi.dy respectively.
    If someone knows a way to force mouse to move to absolute position (x,y) please tell me...
    
 
0
 

mate, well u have sent me the source code of the file,

i need the source of windows.h file, as pointed here,

the double Quoted File.

Here it is:


/*++ BUILD Version: 0001 Increment this if a change has global effects

Copyright (c) 1985-1997, Microsoft Corporation

Module Name:


windows.h

Abstract:

Master include file for Windows applications.

--*/

#ifndef _WINDOWS_
#define _WINDOWS_


#ifndef WINVER
#define WINVER 0x0400
#else
#if defined(_WIN32_WINNT) && (WINVER < 0x0400) && (_WIN32_WINNT > 0x0400)
#error WINVER setting conflicts with _WIN32_WINNT setting
#endif
#endif

#if(WINVER >= 0x0500)
#pragma message ("")
#pragma message ("NOTE: WINVER has been defined as 0x0500 or greater which enables")
#pragma message ("Windows NT 5.0 and Windows 98 features. When these headers were released,")
#pragma message ("Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the current versions.")
#pragma message ("")
#pragma message ("For this release when WINVER is defined as 0x0500 or greater, you can only")
#pragma message ("build beta or test applications. To build a retail application,")
#pragma message ("set WINVER to 0x0400 or visit http://www.microsoft.com/msdn/sdk")
#pragma message ("to see if retail Windows NT 5.0 or Windows 98 headers are available.")
#pragma message ("")
#pragma message ("See the SDK release notes for more information.")
#pragma message ("")
#endif

#ifndef _INC_WINDOWS
#define _INC_WINDOWS

#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

/* If defined, the following flags inhibit definition
* of the indicated items.
*
* NOGDICAPMASKS - CC_*, LC_*, PC_*, CP_*, TC_*, RC_
* NOVIRTUALKEYCODES - VK_*
* NOWINMESSAGES - WM_*, EM_*, LB_*, CB_*
* NOWINSTYLES - WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_*
* NOSYSMETRICS - SM_*
* NOMENUS - MF_*
* NOICONS - IDI_*
* NOKEYSTATES - MK_*
* NOSYSCOMMANDS - SC_*
* NORASTEROPS - Binary and Tertiary raster ops
* NOSHOWWINDOW - SW_*
* OEMRESOURCE - OEM Resource values
* NOATOM - Atom Manager routines
* NOCLIPBOARD - Clipboard routines
* NOCOLOR - Screen colors
* NOCTLMGR - Control and Dialog routines
* NODRAWTEXT - DrawText() and DT_*
* NOGDI - All GDI defines and routines
* NOKERNEL - All KERNEL defines and routines
* NOUSER - All USER defines and routines
* NONLS - All NLS defines and routines
* NOMB - MB_* and MessageBox()
* NOMEMMGR - GMEM_*, LMEM_*, GHND, LHND, associated routines
* NOMETAFILE - typedef METAFILEPICT
* NOMINMAX - Macros min(a,b) and max(a,b)
* NOMSG - typedef MSG and associated routines
* NOOPENFILE - OpenFile(), OemToAnsi, AnsiToOem, and OF_*
* NOSCROLL - SB_* and scrolling routines
* NOSERVICE - All Service Controller routines, SERVICE_ equates, etc.
* NOSOUND - Sound driver routines
* NOTEXTMETRIC - typedef TEXTMETRIC and associated routines
* NOWH - SetWindowsHook and WH_*
* NOWINOFFSETS - GWL_*, GCL_*, associated routines
* NOCOMM - COMM driver routines
* NOKANJI - Kanji support stuff.
* NOHELP - Help engine interface.
* NOPROFILER - Profiler interface.
* NODEFERWINDOWPOS - DeferWindowPos routines
* NOMCX - Modem Configuration Extensions
*/

#if defined(RC_INVOKED) && !defined(NOWINRES)

#include <winresrc.h>

#else

#if defined(RC_INVOKED)
/* Turn off a bunch of stuff to ensure that RC files compile OK. */
#define NOATOM
#define NOGDI
#define NOGDICAPMASKS
#define NOMETAFILE
#define NOMINMAX
#define NOMSG
#define NOOPENFILE
#define NORASTEROPS
#define NOSCROLL
#define NOSOUND
#define NOSYSMETRICS
#define NOTEXTMETRIC
#define NOWH
#define NOCOMM
#define NOKANJI
#define NOCRYPT
#define NOMCX
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_MIPS_) && !defined(_X86_) && defined(_M_IX86)
#define _X86_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_X86_) && !defined(_MIPS_) && defined(_M_MRX000)
#define _MIPS_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_X86_) && !defined(_MIPS_) && defined(_M_ALPHA)
#define _ALPHA_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_X86_) && !defined(_MIPS_) && defined(_M_PPC)
#define _PPC_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_X86_) && !defined(_MIPS_) && defined(_M_M68K)
#define _68K_
#endif

#if !defined(_68K_) && !defined(_MPPC_) && !defined(_PPC_) && !defined(_ALPHA_) && !defined(_X86_) && !defined(_MIPS_) && defined(_M_MPPC)
#define _MPPC_
#endif

#ifndef _MAC
#if defined(_68K_) || defined(_MPPC_)
#define _MAC
#endif
#endif

#ifndef RC_INVOKED
#if ( _MSC_VER >= 800 )
#pragma warning(disable:4001)
#pragma warning(disable:4201)
#pragma warning(disable:4214)
#pragma warning(disable:4514)
#endif
#include <excpt.h>
#include <stdarg.h>
#endif /* RC_INVOKED */

#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winuser.h>
#ifdef _MAC
DECLARE_HANDLE(HKEY);
typedef HKEY *PHKEY;
#endif
#if !defined(_MAC) || defined(_WIN32NLS)
#include <winnls.h>
#endif
#ifndef _MAC
#include <wincon.h>
#include <winver.h>
#endif
#if !defined(_MAC) || defined(_WIN32REG)
#include <winreg.h>
#endif
#ifndef _MAC
#include <winnetwk.h>
#endif

#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#ifndef _MAC
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#endif
#include <shellapi.h>
#ifndef _MAC
#include <winperf.h>

#if(_WIN32_WINNT >= 0x0400)
#include <winsock2.h>
#include <mswsock.h>
#else
#include <winsock.h>
#endif /* _WIN32_WINNT >= 0x0400 */

#endif
#ifndef NOCRYPT
#include <wincrypt.h>
#endif

#ifndef NOGDI
#include <commdlg.h>
#ifndef _MAC
#include <winspool.h>
#ifdef INC_OLE1
#include <ole.h>
#else
#include <ole2.h>
#endif /* !INC_OLE1 */
#endif /* !MAC */
#endif /* !NOGDI */
#endif /* WIN32_LEAN_AND_MEAN */

#ifdef _MAC
#include <winwlm.h>
#endif


#ifdef INC_OLE2
#include <ole2.h>
#endif /* INC_OLE2 */

#ifndef _MAC
#ifndef NOSERVICE
#include <winsvc.h>
#endif

#if(WINVER >= 0x0400)
#ifndef NOMCX
#include <mcx.h>
#endif /* NOMCX */

#ifndef NOIME
#include <imm.h>
#endif
#endif /* WINVER >= 0x0400 */
#endif

#ifndef RC_INVOKED
#if ( _MSC_VER >= 800 )
#pragma warning(default:4001)
#pragma warning(default:4201)
#pragma warning(default:4214)
/* Leave 4514 disabled. It's a stupid warning anyway. */
#endif
#endif /* RC_INVOKED */

#endif /* RC_INVOKED */

#endif /* _INC_WINDOWS */
#endif /* _WINDOWS_ */

Attachments WINDOWS.H (6.92KB)
 
0
 

:cry: :lol:
have a try by following
int ix,iy;
ix=GetSystemMetrics(SM_CXSCREEN);
iy=GetSystemMetrics(SM_CYSCREEN);
INPUT *buffer = new INPUT[3]; //allocate a buffer
buffer->type = INPUT_MOUSE;
buffer->mi.dx = 190*65535/ix;
buffer->mi.dy = 100*65535/iy;
buffer->mi.mouseData = 0;
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
buffer->mi.time = 0;
buffer->mi.dwExtraInfo = 0;

(buffer+1)->type = INPUT_MOUSE;
(buffer+1)->mi.dx = 190*65535/ix;
(buffer+1)->mi.dy = 100*65535/iy;
(buffer+1)->mi.mouseData = 0;
(buffer+1)->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
(buffer+1)->mi.time = 0;
(buffer+1)->mi.dwExtraInfo = 0;

(buffer+2)->type = INPUT_MOUSE;
(buffer+2)->mi.dx = 190*65535/ix;
(buffer+2)->mi.dy = 100*65535/iy;
(buffer+2)->mi.mouseData = 0;
(buffer+2)->mi.dwFlags = MOUSEEVENTF_LEFTUP;
(buffer+2)->mi.time = 0;
(buffer+2)->mi.dwExtraInfo = 0;


SendInput(3,buffer,sizeof(INPUT));
delete (buffer); //clean up our messes.

 
0
 

You can use SetCursorPos(X,Y) to move the mouse.
I've done it for you:

#include "stdafx.h"

int main(int argc, char* argv[]){
	INPUT *buffer = new INPUT[3]; //allocate a buffer
int X;
int Y;
X = 100;
Y = 100;	
(buffer+1)->type = INPUT_MOUSE;
	(buffer+1)->mi.dx = 100;
	(buffer+1)->mi.dy = 100;
	(buffer+1)->mi.mouseData = 0;
	(buffer+1)->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
	(buffer+1)->mi.time = 0;
	(buffer+1)->mi.dwExtraInfo = 0;

	(buffer+2)->type = INPUT_MOUSE;
	(buffer+2)->mi.dx = 100;
	(buffer+2)->mi.dy = 100;
	(buffer+2)->mi.mouseData = 0;
	(buffer+2)->mi.dwFlags = MOUSEEVENTF_LEFTUP;
	(buffer+2)->mi.time = 0;
	(buffer+2)->mi.dwExtraInfo = 0;
SetCursorPos(X,Y);

	SendInput(3,buffer,sizeof(INPUT));

	delete (buffer); //clean up our messes.

	return 0;
}
 
0
 

could sum1 post stdafx.h please, thanks

 
0
 
#include "windows.h"
int main(int argc, char* argv[]){
INPUT *buffer = new INPUT[3]; //allocate a buffer
int X = 30;
int Y = 50;
SetCursorPos(X,Y);

mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,
    X,
    Y,
    0,
    0
);
return 0;
}

that works just fine :P

 
0
 

ENNN

but there are the param mi.dx and mi.dy what is their function?

maybe there is something else ...

but I haven't found it now ... : :rolleyes:

 
0
 

You realize that this thread has been inactive for several months, yes?

 
0
 

I have used windows.h to move my cursor to a specific pixel on the screen. I do not know what type of style you are programming in because I only got errors with the cod you gave me but I do know that the code below works in a “Win32 Console application”. I have come across many automated mouse & keyboard artificial event simulators in c++, but all I came across that I could maintain is a few keyboard buttons and to move the mouse. Even though my main voyage was to purely get the mouse to click as fast is can for one of the games I have, I hope will help on your attempt to (as for why you want it to click at 100,100 is very strange to me).
As:
#include <iostream>
//#include<iostream.h>
//my compiler looks for iostream without “.h”, you may need to add
//it in as you copy this
#include <windows.h>
#include <conio.h>
//for getch() to pause at the end

using namespace std;

void main()
{
//get the position of cursor first
cout<<"pos before change"<<endl;
POINT pos;
GetCursorPos(&pos);
int x=pos.x;
int y=pos.y;
Sleep(10);
cout<<"x:"<<x<<", "<<"y:"<<y<<endl;
cout<<"pos set to 100,100"<<endl;
//MOVEMENT HERE \/\/\/
SetCursorPos(100,100);
//get cursor pos again
GetCursorPos(&pos);
x=pos.x;
y=pos.y;
Sleep(10);
cout<<"x:"<<x<<", "<<"y:"<<y<<endl;
cout<<"pos set set to x+1,y-1 (if mouse not moving, it should be 101,99)"<<endl;
//set again();
GetCursorPos(&pos);
x=pos.x;
y=pos.y;
SetCursorPos(x+1,y-1);
//read for the last time
GetCursorPos(&pos);
x=pos.x;
y=pos.y;
Sleep(10);
cout<<"x:"<<x<<", "<<"y:"<<y<<endl;
cout<<"press any key to exit";
getch();
}

 
0
 

You realize that this thread has been inactive for several years, yes? :rolleyes:

 
0
 

Hello guys, can any one here compile this source code, make a exe file and upload for some newbees guys like me? have a nice day all of you!

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article