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

        */
        
    }
复制代码

 

 

 

 

 

 

 

 

 

 

posted @   天子骄龙  阅读(2086)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!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 荒野的召唤-欧洲地图
点击右上角即可分享
微信分享提示

目录导航