摘要

   本文分享了如何通过代码实现重复点击按钮。要实现该功能有个关键点需要注意:许多软件的按钮不是一个窗口,所以无法通过枚举窗口或者查找子窗口来定位按钮。本文通过直接定位按钮位置来避免这个问题。

该程序的使用方法:

鼠标右击代码python 代码实现鼠标点击_c++

  1. 管理员运行程序
  2. 移动鼠标指针到需要单击的位置,按“空格”键记录要点击位置
  3. 修改每次点击的间隔周期
  4. 修改点击次数
  5. 点击按钮“开始点击”启动程序
  6. 按“Esc”键可以停止程序。

   实现该功能主要包括两个步骤,获取按钮位置和移动鼠标发送左键按下消息。为了模拟人工单击的效果,本程序在点击完按钮之后增加了移动鼠标到初始位置的逻辑。下面通过代码详细介绍。

获取按钮位置:

   GetPhysicalCursorPos( __out LPPOINT lpPoint),这个函数获取当前鼠标光标所指位置,通过定时器实时刷新,当空格键按下时捕获消息并把当前的光标位置存储下来。

模拟鼠标左键单击实现按钮按下:

   首先通过MoveMouse移动鼠标到记录的按钮位置,之后通过MouseClick发送左键按下消息。这两个函数的详细代码如下

//移动鼠标到绝对位置
int CSimulateMessageDlg::MoveMouse(unsigned int dx, unsigned int dy)
{
	INPUT inputs[1] = {};
	ZeroMemory(inputs, sizeof(inputs));

	inputs[0].type = INPUT_MOUSE;
	inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE ;
	inputs[0].mi.dx = dx;
	inputs[0].mi.dy = dy;

	int nSize = ARRAYSIZE(inputs);
	UINT uSent;
	uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));

	if (uSent != ARRAYSIZE(inputs))
	{
		//OutputString(L"SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
	} 
	return 0;
}
//发送鼠标左键单击消息
int CSimulateMessageDlg::MouseClick(int nMode)
{
	INPUT inputs[1] = {};
	ZeroMemory(inputs, sizeof(inputs));

	inputs[0].type = INPUT_MOUSE;
	inputs[0].mi.dwFlags = nMode | MOUSEEVENTF_ABSOLUTE ;
	inputs[0].mi.dx = 0;
	inputs[0].mi.dy = 0;

	int nSize = ARRAYSIZE(inputs);
	UINT uSent;
	uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));

	if (uSent != ARRAYSIZE(inputs))
	{
		//OutputString(L"SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
	} 

	return 0;
}

   注意到MoveMouse这个函数的两个参数dx、dy指的是鼠标移动的绝对位移,是指的鼠标移动的“点”,这个单位与鼠标的dpi有关,其与屏幕坐标系下的单位对应关系通过以下代码计算比率:

int CSimulateMessageDlg::GetMouseCoor2ScreenRatio(void)//计算鼠标移动绝对位移相对屏幕坐标系的比例
{
	CPoint ptMouse,ptMouseOld;
	GetPhysicalCursorPos(&ptMouseOld);
	MoveMouse(0,000);
	MoveMouse(1000,1000);
	Sleep(10);
	BOOL bRet = ::GetPhysicalCursorPos(&ptMouse);
	if (TRUE == bRet)
	{
		m_RatioX = (double)1000/ptMouse.x;//1000 是鼠标移动的绝对位移
		m_RatioY = (double)1000/ptMouse.y;//1000 是鼠标移动的绝对位移
		MoveMouse(ptMouseOld.x*m_RatioX,ptMouseOld.y*m_RatioY );//归位	
		return 0;
	}
	else
	{
		bRet = GetLastError();
	}

	return -1;
}

   总结,本代码实现了鼠标单击按钮的简单功能,但是可基于本代码进行更为复杂功能的实现,例如录制多个需要单击的位置实现批量按按钮。