摘要
本文分享了如何通过代码实现重复点击按钮。要实现该功能有个关键点需要注意:许多软件的按钮不是一个窗口,所以无法通过枚举窗口或者查找子窗口来定位按钮。本文通过直接定位按钮位置来避免这个问题。
该程序的使用方法:
- 管理员运行程序
- 移动鼠标指针到需要单击的位置,按“空格”键记录要点击位置
- 修改每次点击的间隔周期
- 修改点击次数
- 点击按钮“开始点击”启动程序
- 按“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;
}
总结,本代码实现了鼠标单击按钮的简单功能,但是可基于本代码进行更为复杂功能的实现,例如录制多个需要单击的位置实现批量按按钮。