Login dark
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,则删除列表中的任何当前选定内容,并清除编辑控件

    */
    
}

复制代码

_

  • 原文链接
  • 注:知识搬运,供学习交流使用,侵联删!

_