关闭

Windows编程基础--第19节 MFC之自定义消息

标签: mfcwindows
158人阅读 评论(0) 收藏 举报
分类:

Windows编程基础–第19节 MFC之自定义消息

windows程序中最重要的就是消息机制,前面几节我们都是使用Windows系统设定好的消息进行编程,今天我们来使用自定义的消息来看看MFC中消息的传递过程;
MFC中自定义消息有两种方法:

  1. #define WM_MY_DEFINED_MSG (WM_USR+100)
  2. RegisterWindowMessage(WM_MY_REGISTER_MSG_SRR)
    下面我们来尝试一下这两种方法有什么不同;

1. 新建项目

新建一个基于对话框项目“day21”,布局如下,自行处理:
这里写图片描述

2.第一种自定义消息

2.1 定义消息ID

我们来到day20Dlg.h 的头文件中,在上方创建一个宏定义如下:

#define WM_MY_FRIST_MSG (WM_USER + 100)

这里我们定义了一个WM_MY_FRIST_MSG整型数值,它的值时WM_USER + 100,其中WM_USER 是微软定义好的宏,它的值是:#define WM_USER 0x0400 ,这说明在0x0400之前的消息(包含0x0400)都已经被windows系统使用,我们自定义消息只能在这之后,所以我们加上了100;

2.2 映射消息函数

我们切换到day20Dlg.cpp中,找到下面这地方:

BEGIN_MESSAGE_MAP(Cday21Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()

这就是消息的关系图,我们来添加一条映射,如下:

BEGIN_MESSAGE_MAP(Cday21Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_MESSAGE(WM_MY_FRIST_MSG, &Cday21Dlg::OnMyFirstMsgTrigger)
END_MESSAGE_MAP()

ON_MESSAGE(WM_MY_FRIST_MSG, &Cday21Dlg::OnMyFirstMsgTrigger)
说明将WM_MY_FRIST_MSG消息ID与类Cday21Dlg的OnMyFirstMsgTrigger成员函数对应,当WM_MY_FRIST_MSG消息被触发时将调用OnMyFirstMsgTrigger方法;

2.3 实现消息函数

我们先切换到Cday21Dlg类中,添加OnMyFirstMsgTrigger方法的声明:

afx_msg LRESULT OnMyFirstMsgTrigger(WPARAM wParam, LPARAM lParam);
这是消息映射函数的固定格式,参数类型也是固定的;

接下来我们实现OnMyFirstMsgTrigger的定义,如下:

LRESULT Cday21Dlg::OnMyFirstMsgTrigger(WPARAM wParam,  LPARAM lParam)
{
    TCHAR szBuf[128];
    _stprintf(szBuf,_T("消息:%s 被触发,消息ID: 0x%x "),_T("WM_MY_FRIST_MSG"),WM_MY_FRIST_MSG); 
    AfxMessageBox(szBuf);
    return 0;
}

代码解释:

  1. 只要执行这个函数就会弹窗显示消息名称和ID;

2.4 发送消息

我们双击资源界面上的“自定义消息ID”按钮,编辑其点击事件处理函数:

void Cday21Dlg::OnBnClickedBtnDefined()
{
    // TODO: 在此添加控件通知处理程序代码

    PostMessage(WM_MY_FRIST_MSG,0,0);
}

代码解释:

  1. 使用PostMessage发送WM_MY_FRIST_MSG消息;

2.5 运行结果

这里写图片描述

3.第二种自定义消息

3.1 定义消息ID

由于我们需要使用RegisterWindowMessage(LPCSTR lpString)来创造消息ID,所以我们需要先定义一个字符串:

#define WM_MY_REGISTER_MSG_SRR _T("WM_MY_REGISTER_MSG_SRR")

接下来我们定义一个全局变量WM_MY_REGISTER_MSG来作为消息ID;

UINT WM_MY_REGISTER_MSG;

接下来我们来初始化消息ID,我们到Cday21Dlg类的构造函数中来创建消息ID:

Cday21Dlg::Cday21Dlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(Cday21Dlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    WM_MY_REGISTER_MSG = RegisterWindowMessage(WM_MY_REGISTER_MSG_SRR);
}

这样我们就通过RegisterWindowMessage来创建了消息ID,但只有在程序运行时我们才会知道消息ID是多少,并且每次运行时都可能不同;

3.2 映射消息函数

我们切换到day20Dlg.cpp中,我们再来添加一条映射,如下:

BEGIN_MESSAGE_MAP(Cday21Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BTN_DEFINED, &Cday21Dlg::OnBnClickedBtnDefined)
    ON_MESSAGE(WM_MY_FRIST_MSG, &Cday21Dlg::OnMyFirstMsgTrigger)
    ON_REGISTERED_MESSAGE(WM_MY_REGISTER_MSG, &Cday21Dlg::OnMyRegisterMsgTrigger)
    ON_BN_CLICKED(IDC_BTN_REG, &Cday21Dlg::OnBnClickedBtnReg)
END_MESSAGE_MAP()

ON_REGISTERED_MESSAGE(WM_MY_REGISTER_MSG, &Cday21Dlg::OnMyRegisterMsgTrigger)
说明将WM_MY_REGISTER_MSG消息ID与类Cday21Dlg的OnMyRegisterMsgTrigger成员函数对应,当WM_MY_REGISTER_MSG消息被触发时将调用OnMyRegisterMsgTrigger方法;
注意:RegisterWindowMessage方法获取的消息需要用ON_REGISTERED_MESSAGE映射消息

3.3 实现消息函数

我们先切换到Cday21Dlg类中,添加OnMyRegisterMsgTrigger方法的声明:

afx_msg LRESULT OnMyRegisterMsgTrigger(WPARAM wParam, LPARAM lParam);
这是消息映射函数的固定格式,参数类型也是固定的;

接下来我们实现OnMyRegisterMsgTrigger的定义,如下:

LRESULT Cday21Dlg::OnMyRegisterMsgTrigger(WPARAM wParam,  LPARAM lParam)
{
    TCHAR szBuf[128];
    _stprintf(szBuf,_T("消息:%s 被触发,消息ID: 0x%x "),_T("WM_MY_REGISTER_MSG"),WM_MY_REGISTER_MSG); 
    AfxMessageBox(szBuf);
    return 0;
}

代码解释:

  1. 只要执行这个函数就会弹窗显示消息名称和ID;

2.4 发送消息

我们双击资源界面上的“REGISTER消息ID”按钮,编辑其点击事件处理函数:

void Cday21Dlg::OnBnClickedBtnReg()
{
    PostMessage(WM_MY_REGISTER_MSG,0,0);
}

代码解释:

  1. 使用PostMessage发送WM_MY_REGISTER_MSG消息;

2.5 运行结果

这里写图片描述

4.对比两种方法

从上面两种方法我们可以看出其优缺点:

  1. #define WM_MY_DEFINED_MSG (WM_USR+100)
    定义的消息ID唯一,但不确定消息ID是否被其它地方占用,可能造成隐患;
  2. RegisterWindowMessage(WM_MY_REGISTER_MSG_SRR)
    优点:定义的消息ID唯一,独立;缺点:在程序运行前不能确定消息ID,不方便在其它程序中指定触发此消息ID;

项目源码可以访问我的码云

>>>我的私人博客<<<

0
0
查看评论

[每日一学]MFC学习笔记——自定义消息的使用

简单概要 windows的消息机制在前面的几章已经介绍过了,今天来学习一下自定义消息。 预备知识 看完前几章的文章。 具体步骤 新建一个工程,名称为“MyMessage”,使用 Unicode 编码。具体界面可以如下: 在界面设计处右击选...
  • kingsollyu
  • kingsollyu
  • 2012-12-11 12:05
  • 4550

MFC中自定义消息过程

这几天接触一个MFCdi
  • feilong911hao
  • feilong911hao
  • 2014-05-29 10:36
  • 797

MFC中自定义消息的步骤

 这篇技术文章不是讨论经典的MFC中的消息工作机理的,讨论消息工作原理、方式和路径的文章在网上和书本中 随处可见。网上众多的讨论都是关于如何响应并进行用户自定义消息映射的;网上还有一些文章介绍如何在自定 义类中响应Windows消息,在本文中都简略叙述。但是,网上大部分的文章没用透彻阐...
  • ljsant
  • ljsant
  • 2016-07-11 14:29
  • 747

MFC中用户自定义消息及其响应函数的方法

1.在对应类的头文件中自定义消息 如:#define WM_RESULT WM_USER+1 2.在头文件中定义消息响应函数,注意:这个函数的返回值必须是LRESULT 参数必须是 WPARAM 和LPARAM类型。 这是因为afx_msg void OnMyMessage
  • gukesdo
  • gukesdo
  • 2011-09-05 20:53
  • 6895

windows基础编程 -- 资源

前言VC环境可以通过资源脚本文件(.rc)给当前程序添加资源,这些资源包括: Accelerator(加速键),Bitmap(位图),Cursor(光标),Dialog(对话框),HTML(网页脚本),Icon(图标),Menu(菜单),StringTable(字符表),ToolBar(工具栏),V...
  • diletrich
  • diletrich
  • 2016-02-18 23:17
  • 333

Windows编程基础学习笔记

Windows编程概述     Windows系统是一个消息驱动的操作系统,每一个事件的发生都会产生一个消息,我们通过消息来知道发生了什么事件。    Windows编程是在实现程序算法的基础上进行窗口编程。程序员可以直接调用Windows API进...
  • lindagod
  • lindagod
  • 2015-02-17 08:28
  • 3094

【转载+修改】MFC 自定义消息四步曲与在参数中传递变量

今天自己也重学了一下 VC小自定义消息的使用,在网上查阅了相关资料,发现http://hi.baidu.com/atlight/blog/item/11ba969442df6218d21b70cd.html这篇博文介绍的最好(在此谢过原文作者),所以就转过了,但自己增加了一些进一步的详细说明,我也是...
  • code_robot
  • code_robot
  • 2012-07-07 16:08
  • 3480

Windows编程基础知识点

什么是窗口(window)? 对于从编程的角度解析,不要简单地认为是一个程序的窗口,而是如下面定义: 什么是句柄(handle): 是一个号码,操作系统使用这一的号码识别对象。操作系统有一个很大的表,包含了所有创建的windows的句柄,操作系统就是通过查找这一的表找到windows的。 记住句...
  • kenden23
  • kenden23
  • 2013-12-15 08:03
  • 1595

JAVA基础18天速成学习笔记之第10天

JAVA基础18天速成学习笔记之第10天 这是我在csdn下载的.觉得有助于复习Java所以贴了出来.感谢作者.下面附有下载地址. http://download.csdn.net/detail/dongwuming/6412153 JFC:java基础类库(具体的类可以查看API文档...
  • thanklife
  • thanklife
  • 2013-11-08 10:47
  • 1120

MFC下的多线程和自定义消息收发

不仅在MFC的程序中,其他设计库如qt,也会存在运行时界面卡死的问题,导致这个问题的原因是内部存在多次循环,界面更新函数处理不过来,消息队列阻塞。为解决这一问题,多线程是首选。也有通过在单线程循环中PeekMessage来解决界面卡死问题,试了一下,效果也很明显,但这个方法只是备选方案,最终的解决之...
  • qwtyuiop
  • qwtyuiop
  • 2014-11-17 21:48
  • 1241
    个人资料
    • 访问:40614次
    • 积分:695
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:6篇
    • 译文:0篇
    • 评论:1条
    文章分类