文章目录
- 鼠标和键盘的操作
- 被转换为相应的系统信息
- 窗口过程在接收到
- 鼠标或键盘消息后
- 会进行相应的处理。
- 可通过
- SendMessage()和PostMessage()
- 发消息到
- 指定的窗口过程中,
- 这两函数发送鼠标和键盘的相关消息
- 可进行鼠标和键盘的模拟操作。
- 还可通过keybd_event()和mouse_event()两专用函数
- 进行鼠标和键盘按键的模拟操作。
基于发送消息的模拟
- w应程是基消息机制的,
- 对鼠标和键盘的操作
- 也会被系统转化为相应的消息。
- 先学如何通过发送消息
- 进行鼠标和键盘的模拟操作。
鼠标、键盘按键常用的消息
- 移标时,系统对应的消息是WM_MOUSEMOVE
- 按左键对应的是WM_LBUTTONDOWN
- 释放左对应的是WM_LBUTTONUP
- 在MSDN中查询到的鼠标消息如图1-8所示。
- 也定义了键盘的按下与抬起的消息。
- 按下是WM_KEYDOWN,
- 抬起是WM_KEYUP。
- 还一较常用的消息是WM_CHAR。
- MSDN中查询到的键盘消息如图1-9所示。
PostMessage()函数对键盘按键的模拟
- PostMessage()和SendMessage()这两个函数可对指定窗口发消息。
- 鼠标和按键的操作被系统转换为相应的消息,
- 就可用PostMessage()和SendMessage()
- 通过按鼠标和键盘按键发送的消息来模拟他们的操作。
- 对于模拟键盘按键消息,
- 最好用PostMessage()而不要用SendMessage()。
- 后者很多情况不成功。
用PostMessage()模拟键盘发送(按F5键发送)的信息来刷新网页。
- 先开VC6.0,创一个对话框工程,
- 按如下设界面
- 按照如图上进行布局,
- 然后为开始按钮设置控件变量。
- 小程序在IE浏览器处输入
- 要刷新的页面的标题,
- 在刷新频率处输入
- 一个刷新的时间间隔,单位是秒。
下一段
- 了解程序功能
- 将界面布置好
- 就可开始写代码。
- 代码分两部分,
- 第一部分是
- 程序要处理开始按钮的事件
- 第二部分是
- 按指定时间间隔对
- 指定的浏览器发送按F5键的消息刷新网页
- 第一部分是
响应“开始”按钮事件的代码
- 先编写响应“开始”按钮事件的代码,
- 双击“开始”按钮来编写它的响应事件。
- 代码如下:
void CKeyBoardDlg::OnBtnStart()
{
//TODO: Add your control notification handler code here
CString strBtn;
int nInterval=0;
//获取输入的浏览器标题
GetDlgItemText(IDC_EDIT_CAPTION,m_StrCaption);
//获取输入的刷新频率
nInterval=GetDlgItemInt(IDC_EDIT_INTERVAL,FALSE,TRUE);
//判断输入是否非法
if(m_StrCaption==""|nInterval==0)
{
return ;
}
//获取按钮的标题
m_Start.GetWindowText(strBtn);
if(strBtn=="开始")
{
//设置定时器
SetTimer(1,nInterval*1000,NULL);
m_Start.SetWindowText("停止");
GetDlgItem(IDC_EDIT_CAPTION->EableWindow(FALSE));
GetDlgItem(IDC_EDIT_INTERVAL->EnableWindow(FALSE));
}
else
{
KillTimer(1);
m_Start.SetWindowText("开始");
GetDlgItem(IDC_EDIT_CAPTION->EableWindow(TRUE));
GetDlgItem(IDC_EDIT_INTERVAL->EnableWindow(TRUE));
}
}
- 代码首先判断按钮的文本,
- 如是开始,通过SetTimer()设一定时器;
- 如果不是,通过KillTimer()关定时器。
SetTimer()和KillTimer()
- SetTimer()和KillTimer()是MFC中CWnd类的两个成员函数,不是API函数。
- 很多MFC中的类成员和API函数的写法是一样的,但还是有区别的。
- 比较一下SetTimer()在MFC中的定义和API函数的定义的差别。
- MFC中的定义
UINT SetTimer(
UINT nIDEvent,
UINT nElapse,
void (CALLBACK EXPORT* lpfnTimer)(
HWND UINT,UINT,DWORD)
);
- API函数的定义如下:
UINT_PTR SetTimer(
HWND hWnd,//handle to window
UINT_PTR nIDEvent,//timer identifier
UINT uElapse,//time-out value
TIMERPROC lpTimerFunc//timer procedure
);
- 定义看出,
- MFC中SetTimer()比API中SetTimer()
- 少了HWND的窗口句柄的参数。
- 在MFC中,窗口相关的成员函数
- 都不需要指定窗口句柄,
- 在MFC内部已维护
- 一个m_hWnd的句柄变量。
按钮事件中添加定时器
- 在按钮事件中添加定时器,
- 那么定时器就会
- 按照指定的时间间隔进行相应的处理,
- 定时器的部分代码如下:
- 那么定时器就会
void CKeyBoardDlg::OnTimer(UINT nIDEvent)
{
//TODO:Add your mesage handler code here and/or call default
HWND hWnd=::FindWindow(NULL,m_StrCaption.GetBuffer(0));
//发送键盘按下
::PostMessage(hWnd,WM_KEYDOWN,VK_F5,1);
//发送键盘抬起
::PostMessage(hWnd,WM_KEYUP,VK_F5,1);
CDialog::OnTimer(nIDEvent);
}
- 关于定时器的处理非常简单,
- 通过FindWindow()函数得到要刷新窗口的句柄,
- 然后发送WM_KEYDOWN和WM_KEYUP消息来模拟键盘按键即可。
- 模拟可省去WM_KEYUP消息的发送,
- 但为模拟消息更接近真实,
- 建议模拟时候将消息成对发。
API函数模拟鼠标键盘按键
- 总发送消息是非常辛苦的,类型多,不同的消息的附件参数而异。
- windows为几乎每个消息都提供了相应的API函数。不记忆过多的消息,使用API函数进行开发。
鼠标键盘按键模拟函数
- 用Windows的系统消息进行
- 模拟鼠标或键盘按键操作时候,
- 不直观方便。
- Windows下大部分消息
- 都可直接使用对应的API
- 可用WM_GETTEXT消息去获取文本的内容,
- 对应的函数有GetWindowText()。
- 介绍两函数,
- 用来模拟鼠标和键盘的输入,
- 分别是keybd_event和mouse_event,
- 定义如下
VOID keybd_event(
BYTE bVk,//virtual-key code
BYTE bScan,//hardware scan code
DWORD dwFlags,//function options
ULONG_PTR dwExtraInfo//additional keystroke data
);
VOID mouse_event(
DWORD dwFlags,//motion and click options
DWORD dx,//horizontal position or change
DWORD dy,//vertical position or change
DWORD dwData,//wheel movement
ULONG_PTR dwExtraInfo//application-defined information
);
- 从这两个分别是键盘事件和鼠标事件,
- 在程序里使用时,阅读代码的人来说就比较直观。
- 下面用这俩函数
- 上一小节编写的刷新网页的小工具。
网页刷新工具
- 这俩个API,
- 不要给他们传递窗口句柄当作参数。
- 那么这俩函数
- 在进行鼠标和键盘的模拟时
- 必须将
- 目标窗口激活并处于所有窗口的最前端,
- 并且处于激活状态。
程序的界面部分
- 比上个程序的窗口要简单些。
- 有两按钮,
- 按钮“模拟键盘”
- 通过keybd_event()来模拟按F5键从而刷新网页,
- "模拟鼠标"是通过mouse_event()来模拟鼠标右键,
- 从而弹出浏览器的快捷菜单,
- 再通过keybd_event()模拟按R键来刷新网页。
- 按钮“模拟键盘”
将目标窗口设到最前并处于激活
- 知道了程序要实现的功能,
- 先完成将目标窗口设置到最前面
- 并处于激活状态的部分,
- 代码如下:
VOID CSimInputDlg::FindAndFocus()
{
GetDlgItemText(IDC_EDIT_CAPTION,m_StrCaption);
//判断输入是否为空
if(m_StrCaption == "")
{
return ;
}
m_hWnd=::FindWindow(NULL,m_StrCaption.GetBuffer(0));
//该函数将创建指定的线程设置到前台
//并且激活该窗口
::SetForegroundWindow(m_hWnd);
}
SetForegroundWindow的使用非常简单,它会将指定的窗口设置到最前面并处于激活状态,该函数只有1个参数,是目标窗口的窗口句柄。
"模拟键盘"按钮对应的代码
void