【www.402.com】FAW-大伙儿维护合法权利和利益事件发酵,多事之秋业绩承压

明天网易上一则《FAW-公众职工必要同样职业同等工资》的音讯爆出,相关音讯人种种发声,详见下图↓

WX通告服务器消息左券


  • 局地合计冗余(如职务管理信息)是为着升高支付成效,但一定水准上浪费了带宽,早先时期会做改过
  • 文书档案版本号:
    • 1.0.3 二〇一六-11-13 @ marco : 发布公文档案
    • 1.0.4 二〇一五-11-16 @ marco : 增加“职务分明”新闻甚至修改职务管理音讯
    • 1.0.5 二零一六-11-17 @ marco : 增加管理工科具管理新闻
    • 1.0.6 2014-11-17 23:54:44.90 @ marco : 删除部分职分音讯保管接口,加多查询接口
    • 1.0.7 2016-11-19 21:21:06.28 @ marco : 名称校订,将TaskLog相关命名校勘为UserStatus
    • 1.0.8 二零一五-11-20 @marco : 职分音信保管中,增添userid用于数据校验
    • 1.0.9 二〇一五-11-24 @marco : 增加任务脚本管理消息(根据职分项目管理)

音讯映射的兑现

  在MFC软件开荒中,分界面操作还是线程之间通讯都会时时用到音信,通过对音讯的拍卖完结相应的操作。
比较典型的进度是,客户操作窗口,然后有音信发出,送给窗口的音讯管理函数管理,对客商的操作做出响应。

www.402.com 1

音信布局

| ---------- 单个消息 ----------  |  
|<------  消息头  ------>| 消息体  |
| size | type | action  | ...    | 

单个消息,长度最长为 8192
其中消息头占用6个字节:
    unsigned short usSize;
    unsigned short usType;
    unsigned short usAction;

 

一、什么是新闻?
   窗口音讯平日由四个部分构成:1、三个无符号整数,是音讯值;2、信息附带的WPARAM类型的参数;3、消
息附带的LPARAM类型的参数。其实,我们日常所说的音信是慷慨上的新闻值,也正是三个无符号整数,常常被定义为宏。

新闻类型定义

enum
{
    _MSG_NONE                            = 0,
    _MSG_GENERAL                        = 2000,    // 通用消息

    _MSG_CONNECT                        = 2001, // 连接,检查版本号
    _MSG_LOGIN                            = 2002,    // 登陆
    _MSG_LOGOUT                            = 2003,
    _MSG_TASK                            = 2004,    // 任务信息
    _MSG_CLIENT_REPORTER                = 2005,    // 客户端状态, 也做用户态心跳用

    _MSG_MANAGE_BEGIN                    = 3000,    // 管理工具消息
    _MSG_MANAGE_TASK_DATA                = 3001,    // 任务数据相关
    _MSG_MANAGE_TASK_SCRIPT                = 3002, // 任务脚本相关
    _MSG_MANAGE_USER_TASK                = 3003,    // 用户任务相关
    _MSG_MANAGE_USER_ACCOUNT            = 3004, // 用户账户相关
    _MSG_MANAGE_TASK_ADD_FRIEND            = 3005, // 加好友任务配置管理
    _MSG_MANAGE_TASK_DELAY_REPLY        = 3006, // 延时恢复任务配置管理
    _MSG_MANAGE_TASK_POST_MOMENT        = 3007, // 发朋友圈任务配置管理
    _MSG_MANAGE_USER_STATUS                = 3008,

    _MSG_NOTIFY                            = 4000,    // 服务器内部消息
    _MSG_TICK,
    _MSG_RECHARGE,
};
  1. Windows音讯概述

     

    Windows 应用程序的输入由Windows系统以音信的花样发送给应用程序的窗口。那几个窗口通过窗口进度来接过和处理音讯,然后把调节返还给Windows。

     

  2. 音讯的归类

     

二、什么是消息映射机制?
   MFC使用生龙活虎种音信映射机制来管理信息,在应用程序框架中的表现就是一个音讯与音讯处理函数风姿罗曼蒂克风华正茂对应的音讯映射
表,以至消息处理函数的宣示和促成等代码。当窗口接受到音信时,会到音信映射表中找出该消息对应的新闻管理函数,
然后由信息管理函数进行相应的管理。

音讯长度定义

*单个新闻最大尺寸_MAX_MSGSIZE = 8192 (即为10248)

const int   _TASK_TYPE_STR_SIZE_        = 36; 
const int   _MAX_USER_NAME_SIZE_        = 36;
const int   _MAX_MOMENT_TEXT_SIZE_        = 700;
const int   _MAX_WX_URI_SIZE_            = 300;
const int   _MAX_SCRIPT_PATH_SIZE_        = 300;

三、Windows消息分类
   Windows音信分为系统音信和顾客自定义音信。Windows系统音讯有两种:
   1、标准Windows消息。除WM_COMMAND以外WM_开班的新闻是明媒正礼新闻。例如,WM_CREATE、WM_CLOSE。
   2、命令消息。消息名称为WM_COMMAND,音讯中附带了标志符ID来不一致是缘于哪个菜单、工具栏按键或加快键的音信。
   3、文告新闻。布告新闻平时由列表框等子窗口发送给父窗口,音信名称也是WM_COMMAND,当中附带了控件通告码
来分别控件。
   CWnd的派生类都足以接过到专门的学问Windows音讯、通告新闻和下令音讯。命令音讯还足以由文书档案类等选择。
 客商自定义新闻其实正是客商定义叁个宏作为新闻,此宏的值应该当先等于WM_USELacrosse,然后此宏就足以跟系统消息
同黄金时代接纳,窗口类中可以定义它的管理函数。

1、通用新闻

  1. 队列新闻和非队列消息

     

    从新闻的发送渠道上看,消息分三种:队列音信和非队列消息。队列音信送到系统音讯队列,然后到线程音信队列;非队列新闻平素送给指标窗口进度。

    此处,对消息队列阐述如下:

    Windows 维护一个系统新闻队列(System message queue),种种GUI线程有三个线程音讯队列(Thread message queue)。

     

    鼠 标、键盘事件由鼠标或键盘驱动程序调换到输入消息并把新闻放进系统新闻队列,比如WM_MOUSEMOVE、WM_LBUTTONUP、WM_KEYDOWN、WM_CHAEnclave等等。Windows每一趟从系统消息队列移走贰个新闻,分明它是送给哪个窗口的和那么些窗口是由哪些线程创制的,然后,把它放进窗口创立线程的线程音信队列。线程音讯队列接纳送给该线程所成立窗口的音讯。线程从消息队列抽出信息,通过Windows把它送给适当的窗口进度来拍卖。

     

    除外键盘、鼠标新闻以外,队列新闻还应该有WM_PAINT、WM_TIMER和WM_QUIT。

     

    那一个队列新闻以外的绝大许多消息是非队列新闻。

  2. 系统音信和应用程序音信

     

四、音讯映射表
   除了某个未有基类的类或CObject的直白派生类外,其他的类都得以自动生成音信映射表。下边包车型地铁讲明都是CMainFrame
为例。新闻映射表如下:
C++代码:
 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
    ON_WM_CREATE()
    ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize)
  
    ON_REGISTERED_MESSAGE(AFX_WM_CREATETOOLBAR, &CMainFrame:OnToolbarCreateNew)
    ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnApplicationLook)
    ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_APPLOOK_WIN_2000, ID_VIEW_APPLOOK_WINDOWS_7, &CMainFrame::OnUpdateApplicationLook)
    ON_WM_SETTINGCHANGE()
 END_MESSAGE_MAP()
   在BEGIN_MESSAGE_MAG和END_MESSAGE_MAP之间的源委成为音讯映射入口项。新闻映射除了在CMainFrame的实线文件中
累计音信映射表外,在类的定义文件MainFrame.h中还大概会增添贰个宏调用:
   DECLARE_MESSAGE_MAP()
诚如那个宏调用写在类定义的结尾处。

连接

音讯类型:

_MSG_CONNECT_

音讯内容:

const int _MAX_VERSION_STRSIZE_ = 16

const static MSGSTRUCT_INFO MSGCONNECT_ACTION_INFOS[] =
{
    {MSGDIR_C2S,        MSGFIELDTYPE_INT,        0,                        "platform"}, 
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        0,                        "result"},
    {MSGDIR_S2C,        MSGFIELDTYPE_STRING,    _MAX_VERSION_STRSIZE_,    "version"},
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,        0,                        ""}
};

从消息的源于来看,能够分成:系统定义的新闻和应用程序定义的新闻。

五、增加音讯管理函数
   不管是半自动抬高依旧手动增加都有八个步骤:
   1、在类定义中参与音讯管理函数的函数注明,注意要以afx_msg打头。例如MainFrame.h中WM_CREATE的消息管理函数
声明:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
   2、在类的音信映射表中增添该信息的音讯映射入口项。例如WM_CREATE的音信映射入口项:ON_WM_CREATE()。
   3、在类的达成中增添音讯处理函数的函数达成。举个例子,MainFrm.cpp中WM_CREATE的新闻管理函数的达成:
   int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
   {
      ......
   }
   通过上述多个步骤之后,WM_CREATE等新闻就能够在窗口类中被信息管理函数处理了。

登入

信息类型:

_MSG_LOGIN_

消息action:

MSGLOGIN_ACTION_LOGIN = 1

消息result:

enum ME_LOGIN_MGR_RESULT
{
    E_LOGIN_MGR_OK,
    E_LOGIN_NAME_NOT_EXIST,
    E_LOGIN_NAME_ERROR,
    E_LOGIN_PWD_ERROR,

    //公用
    E_CHECK_PLAYER_FULL,
    E_CHECK_SERVER_FORBID,
    E_CHECK_SERVER_ERROR,
    E_CHECK_OK,
};

消息内容:

enum CLIENT_USER_TYPE
{
    CLIENT_USER_INVALID            = -1,
    CLIENT_USER_NORMAL            = 0,
    CLIENT_USER_MANAGER            = 1,
    CLIENT_USER_VALID_END        = 2
};

static const MSGSTRUCT_INFO MSGLOGIN_ACTION_LOGIN_INFOS[] = 
{
    {MSGDIR_C2S,        MSGFIELDTYPE_STRING,    _MAX_NAMESIZE,    "account"}, 
    {MSGDIR_C2S,        MSGFIELDTYPE_STRING,    _MAX_NAMESIZE,    "passwd"}, 
    {MSGDIR_C2S,        MSGFIELDTYPE_STRING,    _MAX_NAMESIZE,    "resolution"}, 
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        0,                "result"}, 
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        0,                "accountType"}, // 即 CLIENT_USER_TYPE
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,        0,                ""}
};

系统消息ID的范围是从0到WM_USE奥迪Q5-1,或0X80000到0XBFFFF;应用程序音讯从WM_USER(0X0400)到0X7FFF,或0XC000到0XFFFF;WM_USE本田CR-V到0X7FFF范围的音信由应用程序自身使用;0XC000到0XFFFF范围的新闻用来和别的应用程序通讯,为了ID的唯少年老成性,使用::RegisterWindowMessage来得到该限定的新闻ID。

六、各类Windows音信的音信管理函数
   标准Windows新闻的音信管理函数都与WM_CREATE音信看似。
   命令音信的新闻映射入口项形式如:ON_COMMAND(ID_VIEW_CUSTOMIZE, &CMainFrame::OnViewCustomize),消息为
ID_VIEW_CUSTOMIZE,新闻处理函数为OnViewCustomize。
   假诺想要使用有个别管理函数批量甩卖有个别命令音信,则能够像CMainFrame新闻映射表中的ON_COMMAND_RANGE(ID_VIEW_APPLOOK_WIN_2000,
ID_VIEW_APPLOOK_WINDWOS_7, &CMainFrame::OnApplicationLook卡塔尔(قطر‎相符增添消息映射入口项,那样值在ID_VIEW_APPLOOK_WIN_2000到ID_VIEW_
APPLOOK_WINDOWS_7之内的菜单项等的通令新闻都由CMainFrame的OnApplicationLook函数处理。函数原型为afx_msg void OnApplicationLook
(UINT id卡塔尔(قطر‎;参数id为客户操作的菜单项等的ID。
   在操作列表框等控件时往往会给父窗口发送WM_NOTIFY文告音信。WM_NOTIFY音讯的wParam参数为发送文告音信的控件的ID,lParam参数指向
一个布局体,恐怕是NMHD智跑构造体,也或者是首先个因素为NMHDPAJERO布局体变量的其它结构体。NMHD奥迪Q5构造体的定义如下(仅作掌握):
   Typedef struct tagNMHDR
   {
      HWND hwndFrom;
      UINT idFrom;
      UINT code;
   } NMHDR;
 hwndFrom为发送通告信息控件的句柄,idFrom为控件ID,code为要拍卖的公告新闻的文告码,比如NM_CLICk。
 布告新闻的新闻映射入口项格局如:
   ON_NOTIFY(wNotifyCode, id, memberFxn)
 wNotifyCode为要拍卖的音讯公告码,举例:NM_CLICK。id为控件标记ID。memberFxn为此新闻的管理函数。
 公告音讯的管理函数的原型为:
   afx_msg void memberFxn(NMHDR * pNotifyStruct, LRESULT *result);
 要是须要利用顾客自定义新闻,首先要定义新闻宏,如:#define WM_UPDATE_WND(WM_USEHaval+1卡塔尔(قطر‎,再到新闻映射表中加多信息映射入口项:
  ON_MESSAGE(WM_UPDATE_WND, &CMainFrame::OnUpdateWnd卡塔尔(قطر‎,然后在MainFrm,h中增多音讯管理函数的函数声明:afx_msg LRESULT OnUpdateWnd(
WPARAM wParam, LPARAM lParam卡塔尔国;最终在MainFrm.cpp中完毕此函数。
   本节对MFC音讯映射机制只是做了比较容易的批注,让大家对它有早晚的认识,编制程序入门那不要强求完全明白。在之后的课程中会常常涉及
到音信的运用,大家会逐年熟识MFC的音讯映射机制。

登出

音讯类型:

_MSG_LOGOUT_

消息内容:

static const MSGSTRUCT_INFO MSGLOGOUT_ACTION_LOGOUT_INFOS[] = 
{
    {MSGDIR_C2S,        MSGFIELDTYPE_BOOL,        false,            "pending"}, // 登出的同时,是否允许服务器清除缓存
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        0,                "result"}, 
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,        0,                ""}
};
  1. 新闻结商谈新闻管理 

心跳

音信类型:

_MSG_CLIENT_REPORTER

消息内容:

enum ENUM_USER_STATUS
{
    E_USER_OFFFLINE    = 0,    // 离线
    E_USER_TASKING    = 1,    // 任务中
    E_USER_PAUSE    = 2,    // 暂停
    E_USER_IDEL        = 3,    // 空闲状态
    E_USER_EXCEPTION= 4,    // 异常
};

static const MSGSTRUCT_INFO MSGCLIENTREPORTER_ACTION_REPT_STATUS_INFOS[] = 
{
    {MSGDIR_ALL,        MSGFIELDTYPE_INT,        0,                "statusCode"},  // 即 ENUM_USER_STATUS
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        0,                "result"}, 
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,        0,                ""}
};

任务分发

enum MSGTASK_ACTION // Client --> Server | Server --> Client
{
    MSGTASK_ACTION_QUERY_INFO        = 0,
    MSGTASK_ACTION_NTFY_TASK        = 1,
    MSGTASK_ACTION_SUBMIT_RESULT    = 2,
    MSGTASK_ACTION_ACK                = 3
};

新闻类型:

_MSG_TASK_

职责项目:

添加好友:"task_add_friend"
延迟回复:"task_delay_reply"
发朋友圈:"task_post_moment"

消息内容:

加老铁职分消息:

static const MSGSTRUCT_INFO MSG_TASK_ADD_FRIEND_INFOS[] =
{
    { MSGDIR_S2C,    MSGFIELDTYPE_INT,        0,                        "taskID" },
    { MSGDIR_S2C,    MSGFIELDTYPE_STRING,    _TASK_TYPE_STR_SIZE_,    "taskType" },
    { MSGDIR_S2C,    MSGFIELDTYPE_STRING,    _MAX_SCRIPT_PATH_SIZE_, "taskScriptPath" },
    { MSGDIR_S2C,    MSGFIELDTYPE_STRING,    _MAX_USER_NAME_SIZE_,    "taskOwner" },
    { MSGDIR_S2C,    MSGFIELDTYPE_DOUBLE,        0,                        "lon" },
    { MSGDIR_S2C,    MSGFIELDTYPE_DOUBLE,        0,                        "lat" },
    { MSGDIR_NONE,    MSGFIENDTYPE_NONE,        0,                        "" }
};

延时回复:

static const MSGSTRUCT_INFO MSG_TASK_DELAY_REPLY_INFOS[] =
{
    { MSGDIR_S2C, MSGFIELDTYPE_INT,            0,                        "taskID" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _TASK_TYPE_STR_SIZE_,    "taskType" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _MAX_SCRIPT_PATH_SIZE_, "taskScriptPath" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _MAX_USER_NAME_SIZE_,    "taskOwner" },
    { MSGDIR_S2C, MSGFIELDTYPE_I64,            0,                        "delay" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,        0,                        "" }
};

发生活圈:

static const MSGSTRUCT_INFO MSG_TASK_POST_MOMENT_INFOS[] =
{
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "taskID" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _TASK_TYPE_STR_SIZE_,    "taskType" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _MAX_SCRIPT_PATH_SIZE_, "taskScriptPath" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _MAX_USER_NAME_SIZE_,    "taskOwner" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _MAX_MOMENT_TEXT_SIZE_, "momentText" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _MAX_WX_URI_SIZE_ * 9,    "momentImages" },
    { MSGDIR_S2C, MSGFIELDTYPE_BOOL,    0,                        "show_position" },
    { MSGDIR_S2C, MSGFIELDTYPE_DOUBLE,    0,                        "lon" },
    { MSGDIR_S2C, MSGFIELDTYPE_DOUBLE,    0,                        "lat" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,    0,                        "" }
};
  1. 音信的组织

     

    为了从音讯队列获取新闻消息,须要选拔MSG结构。举个例子,::GetMessage函数(从音讯队列获得音信并从队列中移走)和::PeekMessage函数(从消息队列得到新闻不过能够不移走State of Qatar都利用了该组织来保存获得的消息音信。

    MSG 构造的定义如下:

     

    typedef struct tagMSG { // msg

    HWND hwnd;

     

    UINT message;

    WPARAM wParam;

    LPARAM lParam;

    DWORD time;

    POINT pt;

    } MSG;

     

    该组织满含了多个分子,用来说述音信的关于属性:

    选择新闻的窗口句柄、音信标记( ID)、第三个信息参数、第贰个新闻参数、新闻发出的年华、新闻发生时鼠标的职位。

     

  2. 应用程序通过窗口进度来处理音讯

     

    www.402.com,如前所述,各个“窗口类”都要注册叁个之类形式的窗口过程:

    LRESULT CALLBACK MainWndProc (

    HWND hwnd,// 窗口句柄

     

    UINT msg,// 音信标记

     

    WPARAM wParam,// 音信参数1

     

    LPARAM lParam// 音讯参数2

     

    )

    应用程序通过窗口进度来拍卖音信:非队列信息由 Windows直接送给目标窗口的窗口进度,队列音讯由::DispatchMessage等派发给指标窗口的窗口进程。窗口进程被调用时,选用四个参数:

     

    a window handle (窗口句柄);

     

    a message identifier (音信标记);

     

    two 32-bit values called message parameters (八个三十一位的音信参数);

     

    供给的话,窗口进程用 ::GetMessageTime获撤除息发出的时光,用::GetMessagePos获取音讯发生时鼠标光标所在的地点。

     

    在窗口进度里,用 switch/case分支管理语句来识别和管理音信。

     

  3. 应用程序通过音讯循环来博取对音信的拍卖

     

    各样GDI应用程序在主窗口创造之后,都会进来音信循环,选用客商输入、解释和拍卖新闻。

    新闻循环的组织如下:

    while (GetMessage(&msg, (HWND卡塔尔 NULL, 0, 0卡塔尔(قطر‎卡塔尔国 {// 从音信队列获得消息

     

    if (hwndDlgModeless == (HWND) NULL ||

    !IsDialogMessage(hwndDlgModeless, &msg) &&

    !TranslateAccelerator(hwndMain, haccel, &msg)) {

    TranslateMessage(&msg);

    DispatchMessage(&msg卡塔尔国; // 发送消息

     

    }

     

    }

    音信循环从音信队列中赢得音信,如若不是赶快键新闻还是对话框新闻,就开展信息调换和派发,让指标窗口的窗口进程来拍卖。

    当得到音讯 WM_QUIT,或许::GetMessage出错开上下班时间,退出音信循环。

     

  4. MFC新闻管理

     

职分结果提交:

enum MSGTASK_ACTION // Client --> Server | Server --> Client
{
    MSGTASK_ACTION_QUERY_INFO        = 0,
    MSGTASK_ACTION_TASKNTFY            = 1,
    MSGTASK_ACTION_RESULT_SUBMIT    = 2,
};

音讯类型:

_MSG_TASK_

消息action:

MSGTASK_ACTION_RESULT_SUBMIT

消息result:

submitResult:0为正确,其他为错误

消息体:

static const MSGSTRUCT_INFO MSG_TASK_RESULT_SUBMIT_INFOS[] =
{
    { MSGDIR_C2S, MSGFIELDTYPE_INT,        0,                        "taskID" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING,    _TASK_TYPE_STR_SIZE_,    "taskType" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING,    _MAX_USER_NAME_SIZE_,    "taskOwner" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT,        0,                        "taskResult" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "submitResult" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,    0,                        "" }
};

使用MFC框架编制程序时,音讯发送和管理的原形也如上所述。但是,有一点须要重申的是,全体的MFC窗口都应用相符窗口进度,技师不必去设计和落到实处协和的窗口进度,而是通过MFC提供的大器晚成套信息映射机制来管理音信。因而,MFC简化了技士编制程序时管理音讯的繁杂。

任务料定

音信类型:

_MSG_TASK_

消息ACTION:

MSGTASK_ACTION_ACK

消息result(ack):

enum TASK_ACK
{
    TASK_ACK_OK        = 0,
    TASK_ACK_ERROR    =1
};

音讯内容:

static const MSGSTRUCT_INFO MSG_TASK_ACK_INFOS[] =
{
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "ack" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" }
};

所谓音信映射,轻松地讲,正是让程序猿钦定要某些MFC类(有新闻处理工科夫的类)管理有个别消息。MFC提供了工具ClassWizard来扶植完结音信映射,在拍卖音信的类中增添一些有关音讯映射的剧情和拍卖音讯的积极分子函数。技师将幸不辱命新闻管理函数,完结所愿意的音信管理本事。

2、管理工科具音讯

只要派生类要覆盖基类的消息管理函数,就用ClassWizard在派生类中增加二个音信映射条目款项,用同大器晚成的原型定义三个函数,然后达成该函数。这么些函数覆盖派生类的别的基类的同名管理函数。

义务数据更新新闻

音讯类型:

_MSG_MANAGE_TASK_DATA

消息action:

// action 定义
enum MSGMTASKDATA_ACTION
{
    MSGMTASKDATA_ACTION_QUERY,    // 查询
    MSGMTASKDATA_ACIION_ADD,    // 新增
    MSGMTASKDATA_ACTION_UPDATE,    // 更新
    MSGMTASKDATA_ACTION_DELETE, // 删除
};

消息result:

enum MSGMTASKDATA_RESULT
{
    MSGMTASKDATA_RESULT_INVALID = -1,
    MSGMTASKDATA_RESULT_SUCC    = 0,
    MSGMTASKDATA_RESULT_FAILED  = 1,
};

音讯内容:

// 任务状态
enum TASK_STATE
{
    TASK_STATE_OVERDUE    = -1,    // 过期的
    TASK_STATE_FINISHED = 0,    // 已完成的
    TASK_STATE_ACTIVATED = 1,    // 激活状态    
    TASK_STATE_NOT_ACTIVATED = 2    // 未激活(未开始)
};

_MAX_TASK_TYPE_SIZE_ = 32
_MAX_TASK_TYPE_SIZE_ = 50

上边几节将分析MFC的音信机制的完毕原理和音信管理的进度。为此,首先要深入分析ClassWizard达成新闻映射的虚实,然后研商MFC的窗口进程,解析MFC窗口进度是哪些实现音讯处理的。

任务消息查询新闻(只兑现查询作用卡塔尔国

// 只实现MSGMTASKDATA_ACTION_QUERY 查询功能
const MSGSTRUCT_INFO MSGMTASKDATA_TASK_LIST_INFOS[] = {
    {MSGDIR_C2S,        MSGFIELDTYPE_INT,                        0,        "userid"},        // 请求参数为userid
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "result"},        
    {MSGDIR_S2C,        MSGFIELDTYPE_VECTOR,                    0,        "taskList"},    // vector的元素对应于MSGMTASKDATA_TASK_INFOS
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,                        0,        ""},
};

const MSGSTRUCT_INFO MSGMTASKDATA_TASK_INFOS[] = {
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "taskid"},
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "userid" },
    {MSGDIR_S2C,        MSGFIELDTYPE_STRING,    _MAX_TASK_NAME_SIZE_,    "taskName" },        // 任务名
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,        _MAX_TASK_TYPE_SIZE_,    "taskType" },        // 任务类型
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "state"},            // 状态
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "taskInterval" },    // 任务间隔
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "activateDate" },    // 开始日期
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,        "taskDuration" },    // 有效时间
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,                        0,        ""},
};
  1. 音讯映射的定义和兑现

     

  2. MFC管理的三类音讯

     

加基友任务管理新闻

// Query
const MSGSTRUCT_INFO MSGMTASK_AF_ACTION_QUERY_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "changePos" },
    { MSGDIR_S2C, MSGFIELDTYPE_DOUBLE, 0, "posLon" },
    { MSGDIR_S2C, MSGFIELDTYPE_DOUBLE, 0, "posLat" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "taskInterval" },    // 任务间隔
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "activateDate" },    // 开始日期
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

// add & update
const MSGSTRUCT_INFO MSGMTASK_AF_ACTION_CU_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "changePos" },
    { MSGDIR_C2S, MSGFIELDTYPE_DOUBLE, 0, "posLon" },
    { MSGDIR_C2S, MSGFIELDTYPE_DOUBLE, 0, "posLat" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "taskInterval" },    // 任务间隔
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "activateDate" },    // 开始日期
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

// delete
const MSGSTRUCT_INFO MSGMTASK_AF_ACTION_DEL_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

基于管理函数和管理进度的不及, MFC主要管理三类音信:

延时余烬复起任务管理音讯

//Query
const MSGSTRUCT_INFO MSGMTASK_DR_ACTION_QUERY_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "checkInterval" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "taskInterval" },    // 任务间隔
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "activateDate" },    // 开始日期
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

//add & Update
const MSGSTRUCT_INFO MSGMTASK_DR_ACTION_CU_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "checkInterval" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "taskInterval" },    // 任务间隔
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "activateDate" },    // 开始日期
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

//delete
const MSGSTRUCT_INFO MSGMTASK_DR_ACTION_DEL_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};

 

发朋友圈职务新闻

//Query
const MSGSTRUCT_INFO MSGMTASK_PM_ACTION_QUERY_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT,        0,                        "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT,        0,                        "userid" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING, _MAX_MOMENT_TEXT_SIZE_,    "momentText" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING, _MAX_WX_URI_SIZE_ * 9,    "momentImages" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING, _MAX_WX_URI_SIZE_,        "forward_url" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "showPos" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "posLon" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "posLat" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "taskInterval" },    // 任务间隔
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "activateDate" },    // 开始日期
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                        "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};


//add & update
const MSGSTRUCT_INFO MSGMTASK_PM_ACTION_CU_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT,            0,                        "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT,            0,                        "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT,            0,                        "userid" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING,        _MAX_MOMENT_TEXT_SIZE_, "momentText" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING,        _MAX_WX_URI_SIZE_*9,    "momentImages" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING,        _MAX_WX_URI_SIZE_,        "forward_url" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "showPos" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "posLon" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "posLat" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "taskInterval" },    // 任务间隔
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "activateDate" },    // 开始日期
    { MSGDIR_C2S, MSGFIELDTYPE_INT,            0,                        "taskDuration" },    // 有效时间
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,        0,                        "" },
};

//delete
const MSGSTRUCT_INFO MSGMTASK_PM_ACTION_DEL_INFOS[] = {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "taskid" },
    { MSGDIR_ALL, MSGFIELDTYPE_INT, 0, "userid" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};
  • Windows 消息,前缀以“WM_”打头,WM_COMMAND例外。Windows信息间接送给MFC窗口进度管理,窗口进度调用对应的新闻管理函数。经常,由窗口对象来管理那类音讯,也正是说,那类新闻管理函数平日是MFC窗口类的分子函数。

     

  • 支配公告音信,是调控子窗口送给父窗口的 WM_COMMAND公告音信。窗口进度调用对应的新闻管理函数。常常,由窗口对象来拍卖那类信息,也便是说,那类音讯管理函数平日是MFC窗口类的积极分子函数。

     

账户消息保管音信

消息类型:

_MSG_MANAGE_USER_ACCOUNT

消息action:

enum MSGMUSERACCOUNT_ACTION
{
    MSGMUSERACCOUNT_ACTION_ADD, 
    MSGMUSERACCOUNT_ACTION_UPDATE, 
    MSGMUSERACCOUNT_ACTION_DELETE,
};

消息result:

// result
enum MSGMUSERACCOUNT_RESULT
{
    MSGMUSERACCOUNT_RESULT_INVALID = -1,
    MSGMUSERACCOUNT_RESULT_SUCC    = 0,
    MSGMUSERACCOUNT_RESULT_FAILED  = 1,
};

新闻内容:

// add & update
static const MSGSTRUCT_INFO MSGMUSERACCOUNT_ACTION_ADD_UPDATE_INFOS[] = 
{
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,            "result"}, 
    {MSGDIR_ALL,        MSGFIELDTYPE_INT,                        0,            "id"}, 
    {MSGDIR_ALL,        MSGFIELDTYPE_INT,                        0,            "type"},
    {MSGDIR_ALL,        MSGFIELDTYPE_STRING,    _MAX_USER_NAME_SIZE_,        "name"},
    {MSGDIR_ALL,        MSGFIELDTYPE_STRING,    _MAX_USER_NAME_SIZE_,        "nickName" },
    {MSGDIR_ALL,        MSGFIELDTYPE_STRING,    _MAX_USER_PASSWD_SIZE_,        "password"},
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,                        0,            ""},
};

// delete
static const MSGSTRUCT_INFO MSGMUSERACCOUNT_COMMON_INFOS[] = 
{
    {MSGDIR_S2C,        MSGFIELDTYPE_INT,                        0,            "result"}, 
    {MSGDIR_ALL,        MSGFIELDTYPE_INT,                        0,            "id"},
    {MSGDIR_NONE,        MSGFIENDTYPE_NONE,                        0,            ""},
};

亟待建议的是,Win32用到新的WM_NOGIENIAY来拍卖复杂的通报信息。WM_COMMAND类型的通报新闻仅仅能传递一个调节窗口句柄(lparam卡塔尔国、调控窗ID和通报代码(wparam卡塔尔。WM_NOTIFY能传递任性复杂的新闻。

顾客职分监察和控制

新闻类型:

_MSG_MANAGE_USER_TASK_LOG

消息action:

enum MSGM_USER_STATUS_ACTION
{
    MSGM_USER_STATUS_ACTION_QUERY,
};

消息result:

0为正确, 其他为错误

新闻内容:

static const MSGSTRUCT_INFO MSGM_USER_STATUS_LIST_INFOS[] =
{
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,    "result" },
    { MSGDIR_S2C, MSGFIELDTYPE_VECTOR,    0,    "statusList" },    // vector对应于 MSGM_USER_TASK_LOG_INFOS;
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,    0,    "" },
};

static const MSGSTRUCT_INFO MSGM_USER_STATUS_INFOS[] =
{
    { MSGDIR_S2C, MSGFIELDTYPE_INT,            0,                        "userid" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _MAX_USER_NAME_SIZE_,    "userName" },    // vector对应于 MSGM_TASK_LOG_INFOS;
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _MAX_USER_NAME_SIZE_,    "nickName" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,            0,                        "taskid" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,        _MAX_TASK_NAME_SIZE_,    "taskName" },
    { MSGDIR_S2C, MSGFIELDTYPE_I64,            0,                        "actionTime" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
};
  • 命令音讯,那是出自菜单、工具条开关、加速键等顾客接口对象的WM_COMMAND布告音讯,归属应用程序本人定义的新闻。通过新闻映射机制,MFC框架把命令按一定的路子分发给七连串型的目的(具备音讯管理工科夫)管理,如文书档案、窗口、应用程序、文书档案模板等目的。能管理音讯映射的类必得从CCmdTarget类派生。 

职责脚本处理

消息类型:

_MSG_MANAGE_TASK_SCRIPT

消息action:

// action 
enum MSGMTASKSCRIPT_ACTION
{
    MSGMTASKSCRIPT_ACTION_QUERY,
    MSGMTASKSCRIPT_ACTION_CREATE,
    MSGMTASKSCRIPT_ACTION_UPDATE,
    MSGMTASKSCRIPT_ACTION_DELETE,
};

消息result:

// result
enum MSGMTASKSCRIPT_RESULT
{
    MSGMTASKSCRIPT_RESULT_INVALID = -1,
    MSGMTASKSCRIPT_RESULT_SUCC    = 0,
    MSGMTASKSCRIPT_RESULT_FAILED  = 1,
};

音讯内容:

// query 如果taskType为空,则下发所有类型的脚步信息,如果不为空,则查询对应的taskType,下发信息
static const MSGSTRUCT_INFO MSGTASKSCRIPT_QUERY_INFOS[]
{
    { MSGDIR_C2S, MSGFIELDTYPE_STRING, _MAX_TASK_TYPE_SIZE_,    "taskType" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                   "result" },
    { MSGDIR_S2C, MSGFIELDTYPE_VECTOR,    0,                    "scriptList"},    // 元素对应于 MSGTASKSCRIPT_QUERY_SCRIPT_INFOS 
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,    0,                        "" },
};

static const MSGSTRUCT_INFO MSGTASKSCRIPT_QUERY_SCRIPT_INFOS[]
{
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    _MAX_TASK_TYPE_SIZE_,    "taskType" },
    { MSGDIR_S2C, MSGFIELDTYPE_STRING,    0,                       "scriptName" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                      "version" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                      "heightPixels" },
    { MSGDIR_S2C, MSGFIELDTYPE_INT,        0,                      "widthPixels" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE,    0,                        "" },
};
  • // create & update
    static const MSGSTRUCT_INFO MSGTASKSCRIPT_CU_INFOS[]
    {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_STRING, MAX_TASK_TYPE_SIZE, "taskType" },
    { MSGDIR_C2S, MSGFIELDTYPE_STRING, 0, "scriptName" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "version" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "heightPixels" },
    { MSGDIR_C2S, MSGFIELDTYPE_INT, 0, "widthPixels" },
    { MSGDIR_NONE, MSGFIENDTYPE_NONE, 0, "" },
    };

  • // delete
    static const MSGSTRUCT_INFO MSGTASKSCRIPT_DEL_INFOS[]
    {
    { MSGDIR_S2C, MSGFIELDTYPE_INT, 0, "result" },
    { MSGDIR_ALL, MSGFIELDTYPE_STRING, MAX_TASK_TYPE_SIZE, "taskType" },
    };

在评论了新闻的归类之后,应该是斟酌每一类消息如什么地点理的时候了。不过,要明了怎么管理新闻,首先要驾驭如何映射新闻。

  1. MFC音信映射的完毕形式

     

    MFC 使用ClassWizard援助落成新闻映射,它在源码中增多一些新闻映射的内容,并宣称和兑现音讯管理函数。今后来剖判这个被增加的内容。

     

    在类的概念(头文件)里,它扩充了音信管理函数申明,并累积意气风发行证明音讯映射的宏 DECLARE_MESSAGE_MAP。

     

    在类的兑现(完结公文)里,完毕新闻管理函数,并动用 IMPLEMENT_MESSAGE_MAP宏实现新闻映射。平时情状下,这一个表明和兑现是由MFC的ClassWizard自动来维护的。看多个事例:

     

    在 AppWizard爆发的运用程序类的源码中,应用程序类的定义(头文件)富含了看似如下的代码:

     

    //{{AFX_MSG(CTttApp)

    afx_msg void OnAppAbout();

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

    运用程序类的完成公文中隐含了看似如下的代码:

    BEGIN_MESSAGE_MAP(CTApp, CWinApp)

    //{{AFX_MSG_MAP(CTttApp)

    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

    //}}AFX_MSG_MAP

    END_MESSAGE_MAP()

    头文件里是音信映射和音讯管理函数的扬言,完结公文里是音信映射的贯彻和音信管理函数的贯彻。它意味着让应用程序对象管理命令音信ID_APP_ABOUT,新闻管理函数是OnAppAbout。

     

    为什么如此做之后就成功了一个音讯映射?这几个注解和促成到底作了些什么呢?接着,将钻探这几个主题素材。

  2. 在宣称与贯彻的内部

     

  1. DECLARE_MESSAGE_MAP宏:

     

    首先,看DECLARE_MESSAGE_MAP宏的开始和结果:

    #ifdef _AFXDLL

    #define DECLARE_MESSAGE_MAP() "

    private: "

    static const AFX_MSGMAP_ENTRY _messageEntries[]; "

    protected: "

    static AFX_DATA const AFX_MSGMAP messageMap; "

    static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); "

    virtual const AFX_MSGMAP* GetMessageMap() const; "

    #else

    #define DECLARE_MESSAGE_MAP() "

    private: "

    static const AFX_MSGMAP_ENTRY _messageEntries[]; "

    protected: "

    static AFX_DATA const AFX_MSGMAP messageMap; "

    virtual const AFX_MSGMAP* GetMessageMap() const; "

    #endif

    DECLARE_MESSAGE_MAP 定义了三个版本,分别用于静态或然动态链接到MFC DLL的动静。

     

  2. BEGIN_MESSAE_MAP宏

     

    然后,看BEGIN_MESSAE_MAP宏的内容:

    #ifdef _AFXDLL

    #define BEGIN_MESSAGE_MAP(theClass, baseClass) "

    const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() "

    { return &baseClass::messageMap; } "

    const AFX_MSGMAP* theClass::GetMessageMap() const "

    { return &theClass::messageMap; } "

    AFX_DATADEF const AFX_MSGMAP theClass::messageMap = "

    { &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; "

    const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = "

    { "

    #else

    #define BEGIN_MESSAGE_MAP(theClass, baseClass) "

    const AFX_MSGMAP* theClass::GetMessageMap() const "

    { return &theClass::messageMap; } "

    AFX_DATADEF const AFX_MSGMAP theClass::messageMap = "

    { &baseClass::messageMap, &theClass::_messageEntries[0] }; "

    const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = "

    { "

    #endif

    #define END_MESSAGE_MAP() "

    {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } "

    }; "

    对应地, BEGIN_MESSAGE_MAP定义了四个版本,分别用于静态或许动态链接到MFC DLL的状态。END_MESSAGE_MAP相对轻易,就唯有生龙活虎种概念。

     

  3. ON_COMMAND宏

     

最后,看ON_COMMAND宏的源委:

#define ON_COMMAND(id, memberFxn) "

{"

WM_COMMAND,"

CN_COMMAND,"

(WORD)id,"

(WORD)id,"

AfxSig_vv,"

(AFX_PMSG)memberFxn"

};

  1. 音信映射评释的分解 

在驾驭了有关宏的定义之后,以往来解析它们的功力和职能。

音信映射评释的真相是给所在类增添多少个静态成员变量和静态或编造函数,当然它们是与音讯映射相关的变量和函数。

  1. 分子变量 

有七个成员变量被加上,第贰个是 _messageEntries,第二个是messageMap。

 

  • 首先个分子变量的扬言: 

AFX_MSGMAP_ENTRY _messageEntries[]

那是二个 AFX_MSGMAP_ENT途睿欧Y 类型的数组变量,是一个静态成员变量,用来容纳类的音信映射条目款项。多少个新闻映射条款能够用AFX_MSGMAP_ENTHavalY构造来说述。

上一篇:乐视开创者贾跃亭的乐视生命垂危! 下一篇:没有了