SendMessage发送消息
@TOC
正文
函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回
函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
参数:
hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。
Msg:指定被发送的消息。
wParam:指定附加的消息指定信息。
IParam:指定附加的消息指定信息。
返回值:返回值指定消息处理的结果,依赖于所发送的消息 注意:wParam IParam两个参数的使用可以看视频:https://www.bilibili.com/video/BV1bD4y1g7Gq/?vd_source=189e32a0967ed45997385a775f5fc6a1
Windows是一个消息驱动式系统,SendMessage是应用程序和应用程序之间进行消息传递的主要手段之一
发送鼠标消息 复制代码 // SendMessageDlg.cpp: 实现文件 //
include "pch.h"
include "framework.h"
include "SendMessage.h"
include "SendMessageDlg.h"
include "afxdialogex.h"
ifdef _DEBUG
define new DEBUG_NEW
endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx { public: CAboutDlg();
// 对话框数据
ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现 protected: DECLARE_MESSAGE_MAP() };
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { }
void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP()
// CSendMessageDlg 对话框
CSendMessageDlg::CSendMessageDlg(CWnd pParent /=nullptr*/) : CDialogEx(IDD_SENDMESSAGE_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }
void CSendMessageDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CSendMessageDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_LBUTTONDOWN() ON_BN_CLICKED(IDC_BUTTON1, &CSendMessageDlg::OnBnClickedButton1) ON_WM_LBUTTONUP() END_MESSAGE_MAP()
HANDLE hStdout;//控制台句柄 // CSendMessageDlg 消息处理程序
BOOL CSendMessageDlg::OnInitDialog() { CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
AllocConsole();//创建控制台
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);//获得控制台输出句柄
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CSendMessageDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } }
// 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。
void CSendMessageDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSendMessageDlg::OnQueryDragIcon()
{
return static_cast
void CSendMessageDlg::OnLButtonDown(UINT nFlags, CPoint point)
//参数nFlags的使用看:https://www.cnblogs.com/liming19680104/p/17136095.html
{
//鼠标左键按下消息处理函数
CString str,str1,str2;
str1.Format(_T("%d"), point.x);
//获取鼠标坐标参数
str2.Format(_T("%d"), point.y);
str = str1 +_T(",") + str2+_T("\r\n");
WriteConsole(hStdout, _T("你按下鼠标左键了\r\n"), _tcslen(_T("你按下鼠标左键了\r\n")), NULL, NULL);//在控制台输出
WriteConsole(hStdout, str, _tcslen(str), NULL, NULL);
CDialogEx::OnLButtonDown(nFlags, point);
}
void CSendMessageDlg::OnBnClickedButton1() //按下鼠标左键按钮 { SendMessage(WM_LBUTTONDOWN);//发送按下鼠标左键消息 // Sleep(2000); SendMessage(WM_LBUTTONUP);//发送释放鼠标左键消息 //WM_MOUSEFIRST 0x0200 //移动鼠标时发生 //WM_MOUSEMOVE 0x0200 //移动鼠标时发生,同WM_MOUSEFIRST //WM_LBUTTONDOWN 0x0201 //按下鼠标左键 //WM_LBUTTONUP 0x0202 //释放鼠标左键 //WM_LBUTTONDBLCLK 0x0203 //双击鼠标左键 //WM_RBUTTONDOWN 0x0204 //按下鼠标右键 //WM_RBUTTONUP 0x0205 //释放鼠标右键 //WM_RBUTTONDBLCLK 0x0206 //双击鼠标右键 //WM_MBUTTONDOWN 0x0207 //按下鼠标中键 //WM_MBUTTONUP 0x0208 //释放鼠标中键 //WM_MBUTTONDBLCLK 0x0209 //双击鼠标中键 Sleep(2000); SendMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(32, 34)); //发送左键按下消息,坐标(32,34) Sleep(2000); SendMessage(WM_LBUTTONUP, 0, MAKELPARAM(32, 34)); //发送左键释放消息,坐标(32,34)
}
void CSendMessageDlg::OnLButtonUp(UINT nFlags, CPoint point) { //鼠标左键释放消息处理函数
WriteConsole(hStdout, _T("你释放鼠标左键了\r\n"), _tcslen(_T("你释放鼠标左键了\r\n")), NULL, NULL);
CDialogEx::OnLButtonUp(nFlags, point);
} 复制代码 实例工程下载:
链接:https://pan.baidu.com/s/1U7hEkyHLbNkDtk1HaE6ADQ 提取码:6666
向指定窗口发送鼠标消息 实例功能:向指定窗口发送鼠标右键消息,弹出菜单
测试窗口程序下载:
链接:https://pan.baidu.com/s/1T91E684ZhkBrrXk85Vs3Xg 提取码:6666
代码:
复制代码 HWND hWnd = ::FindWindow(_T("#32770"), _T("菜单测试")); //MFC对话框默认类名是#32770
if(hWnd)
{
::PostMessage(hWnd,WM_RBUTTONDOWN,MK_RBUTTON,MAKELPARAM(20,25));//向指定窗口发送鼠标右键按下消息
/*
参数2:WM_RBUTTONDOWN=0x0204消息:当用户在光标位于窗口的工作区时按下鼠标右键时发送
窗口通过其 WindowProc 函数接收此消息
参数3:WPARAM wParam 表示的意思如下
MK_CONTROL 键盘CTRL键被按下。
MK_LBUTTON 鼠标左键被按下。
MK_MBUTTON 鼠标中键被按下。
MK_RBUTTON 鼠标右键被按下。
MK_SHIFT 键盘SHIFT键被按下
参数4:LPARAM lParam
低字节表示光标的X坐标,坐标是相对于客户区域的左上角
高字节表示光标的Y坐标,坐标是相对于客户区域的左上角
MAKELPARAM(20,20)是宏:表示坐标是20,20
使用以下代码获取光标的坐标:
xPos = GET_X_LPARAM(lParam);
yPos = GET_Y_LPARAM(lParam);
*/
::PostMessage(hWnd, WM_RBUTTONUP, 0, MAKELPARAM(20, 25));//向指定窗口发送鼠标右键弹起消息
//参数2:当用户在光标位于窗口的工作区时松开鼠标右键时发布
// 参数4:LPARAM lParam
// 低字节表示光标的X坐标,坐标是相对于客户区域的左上角
// 高字节表示光标的Y坐标,坐标是相对于客户区域的左上角
// MAKELPARAM(20, 20)是宏:表示坐标是20, 20
// 使用以下代码获取光标的坐标:
// xPos = GET_X_LPARAM(lParam);
// yPos = GET_Y_LPARAM(lParam);
//窗口通过其 WindowProc 函数接收此消息
}
复制代码
发送键盘消息 复制代码 // SendMessage1Dlg.cpp: 实现文件 //
include "pch.h"
include "framework.h"
include "SendMessage1.h"
include "SendMessage1Dlg.h"
include "afxdialogex.h"
ifdef _DEBUG
define new DEBUG_NEW
endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx { public: CAboutDlg();
// 对话框数据
ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现 protected: DECLARE_MESSAGE_MAP() };
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { }
void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP()
// CSendMessage1Dlg 对话框
CSendMessage1Dlg::CSendMessage1Dlg(CWnd pParent /=nullptr*/) : CDialogEx(IDD_SENDMESSAGE1_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }
void CSendMessage1Dlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); }
BEGIN_MESSAGE_MAP(CSendMessage1Dlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_KEYDOWN() ON_BN_CLICKED(IDC_BUTTON1, &CSendMessage1Dlg::OnBnClickedButton1) END_MESSAGE_MAP()
HANDLE hStdout; CString str1, str; // CSendMessage1Dlg 消息处理程序
BOOL CSendMessage1Dlg::OnInitDialog() { CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
AllocConsole();//创建控制台
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);//获得控制台输出句柄
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CSendMessage1Dlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } }
// 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。
void CSendMessage1Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSendMessage1Dlg::OnQueryDragIcon()
{
return static_cast
void CSendMessage1Dlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
//参数含义看:https://www.cnblogs.com/liming19680104/p/17137040.html
{
//键盘按下消息处理函数
if (nChar == 66) //如果按下的B键
//66 是B(大写)的ASCII吗
{
WriteConsole(hStdout, _T("你按下了B键\r\n"), _tcslen(_T("你按下了B键\r\n")), NULL, NULL);//在控制台输出
}
CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSendMessage1Dlg::OnBnClickedButton1() { //按钮响应函数 SendMessage(WM_KEYDOWN, 'B', 0);//发送B键按下消息 //参数1:键盘动作类型,看:https://www.cnblogs.com/liming19680104/p/17137040.html
} 复制代码
设置窗口标题 复制代码 HWND hWnd = ::FindWindow(NULL, _T("sss.txt - 记事本")); BOOL b=::SetForegroundWindow(hWnd); //指定窗口设置到前台 //将指定窗口设置到前台,并且激活该窗口。键盘输入转向该窗口 //参数:将要设置前台的窗口句柄 //返回值:如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零 //备注:前台窗口是z序顶部的窗口,是用户的工作窗口
TCHAR ch[] = _T("学习笔记");
::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)ch);//设置窗口标题
复制代码
单击按钮 实例功能:单击计算器中的7按钮
实例中的计算器下载:
链接:https://pan.baidu.com/s/1Aed_FTzULUeKawv5jkVDKg 提取码:6666
复制代码 HWND hWnd = ::FindWindow(_T("ThunderRT6FormDC"), _T("计算器<标准型>")); //获取计算器句柄
if(hWnd)
{
::ShowWindow(hWnd, SW_NORMAL);
::SetForegroundWindow(hWnd);
//保证BM_CLICK消息成功
HWND hWnd1 = ::GetDlgItem(hWnd, 0x15);
//获取计算器7按钮的句柄
//0x15 获取方法看:https://www.cnblogs.com/liming19680104/p/17198189.html
::SendMessage(hWnd1,BM_CLICK,0,0); //单击按钮
/*
BM_CLICK消息:模拟用户单击按钮。
此消息会导致该按钮接收 WM_LBUTTONDOWN 和 WM_LBUTTONUP 消息,以及按钮的父窗口接收 BN_CLICKED 通知代码
备注:如果该按钮位于对话框中且对话框未处于活动状态, 则BM_CLICK 消息可能会失败。 若要确保在这种情况下成功,
请在将BM_CLICK消息发送到按钮之前调用 SetActiveWindow 函数以激活对话框
按钮包括单选框、复选框等
*/
复制代码
实例工程下载:
链接:https://pan.baidu.com/s/1gcHO7am6-tFM2aq1ZLRmWg 提取码:6666
搜索控件的消息 每个控件都有自己的消息,自己可以百度搜索。比如我要搜索按钮消息,可以输入:button message
combo下拉框 用来练习的下拉框:
链接:https://pan.baidu.com/s/1mJJK0YMt7rG_WWTjxrxoMw 提取码:6666
复制代码 HWND hWnd = ::FindWindow(_T("#32770"), _T("测试")); //MFC对话框默认类名是#32770
if(hWnd)
{
::ShowWindow(hWnd, SW_NORMAL);
::SetForegroundWindow(hWnd);
HWND hWnd1 = ::GetDlgItem(hWnd, 0x3E8);
//获取下拉框的句柄
//0x3E8 获取方法看:https://www.cnblogs.com/liming19680104/p/17198189.html
::SendMessage(hWnd1,CB_INSERTSTRING, -1, (LPARAM)_T("100"));
/*
CB_INSERTSTRING消息:将字符串或项数据插入组合框列表中
参数3:wParam要插入字符串的位置的从零开始的索引。 如果此参数为 -1,则字符串将添加到列表末尾
参数4:lParam指向要插入的 null 终止字符串的指针
*/
::SendMessage(hWnd1,CB_SETCURSEL,5,0);
/*
程序发送 CB_SETCURSEL 消息,以在组合框中选择字符串。
参数3:wParam指定要选择的字符串的从零开始的索引。
如果此参数为 -1,则删除列表中的任何当前选定内容,并清除编辑控件
*/
}
复制代码
- 原文链接
- 注:知识搬运,供学习交流使用,侵联删!