title: SendMessage发送消息
author: Love02xp
date: 2020-08-09 13:04:17
category: [编程代码]
tags: [VC6,代码,学习]
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<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,则删除列表中的任何当前选定内容,并清除编辑控件
*/
}
复制代码
_
- 原文链接
- 注:知识搬运,供学习交流使用,侵联删!
_