SendMessage发送消息
函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数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<HCURSOR>(m_hIcon); } 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<HCURSOR>(m_hIcon); } 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,则删除列表中的任何当前选定内容,并清除编辑控件 */ }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2022-02-24 halcon-gen_rectangle1创建一个矩形
2022-02-24 halcon-滤波
2022-02-24 halcon--mean_image均值平滑
2021-02-24 photoshop-画笔工具
2020-02-24 荒野的召唤-乌尔霍-南非
2020-02-24 荒野的召唤狩猎地点
2020-02-24 荒野的召唤-欧洲地图