zoukankan      html  css  js  c++  java
  • 16、深入浅出MFC学习笔记,事件与消息

    一、基本概念

    1Windows程序的本质是基于消息的事件驱动。

    Windows程序分为程序代码和UI资源两大部分。如图所示,资源的实际内容是二进制代码,借助各种工具产生。

    wps_clip_image-30469

    32位操作系统中不再有small/medium/large等内存模式之分。LIBC.LIBC Runtime函数库的静态链接版本,MSVCRT.LIBC RunTime函数库动态链接版本的import函数库。

    Windows消息分为两类(按输入):由硬件装置所产生的消息(如鼠标按下),放在系统队列(System Queue)中,以及由Windows系统或其它Windows程序传送过来的消息,放在程序队列(application queue)中。通过调用GetMessage API来取得消息,程序的生命靠它来推动。接受并处理消息的主角是窗口,每一个窗口都应当有一个窗口函数来负责处理消息。

    wps_clip_image-30472

    2、消息映射的雏形示例

        把窗口函数的内容设计得更模块化、更一般化的作法:

    首先,定义一个MSGMAP_ENTRY 结构和一个dim 宏:

    struct MSGMAP_ENTRY {
    UINT nMessage;
    LONG (*pfn)(HWND, UINT, WPARAM, LPARAM);
    };
    #define dim(x) (sizeof(x) / sizeof(x[0]))
        【注意: pfn 是一个函数指针,我准备以此指针所指之函数处理nMessage 消息。这正是对象导向观念中把「资料」和「处理资料的方法」封装起来的一种具体实现,只不过用的不是C++ 语言。】

        接下来,组织两个数组_messageEntries[ ] _commandEntries[ ],把程序中欲处理的消息以及消息处理例程的关联性建立起来:

    定义示例

    // 消息与处理例程之对照表格
    struct MSGMAP_ENTRY _messageEntries[] =
    {
    WM_CREATE, OnCreate,
    WM_PAINT, OnPaint,
    WM_SIZE, OnSize,
    WM_COMMAND, OnCommand,
    WM_SETFOCUS, OnSetFocus,
    WM_CLOSE, OnClose,
    WM_DESTROY, OnDestroy,
    } ;
    这是消息 这是消息处理例程
    // Command-ID与处理例程之对照表格
    struct MSGMAP_ENTRY _commandEntries =
    {
    IDM_ABOUT, OnAbout,
    IDM_FILEOPEN, OnFileOpen,
    IDM_SAVEAS, OnSaveAs,
    } ;
    这是WM_COMMAND 命令项这是命令处理例程

    于是窗口函数可以这么设计:

    窗口函数设计示例

    //----------------------------------------------------------------------
    //窗口函数
    //----------------------------------------------------------------------
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
    WPARAM wParam, LPARAM lParam)
    {
    int i;
    for(i=0; i < dim(_messageEntries); i++) { //
    if (message == _messageEntries[i].nMessage)
    return((*_messageEntries[i].pfn)(hWnd, message, wParam, lParam));
    }
    return(DefWindowProc(hWnd, message, wParam, lParam));
    }
    //----------------------------------------------------------------------
    // OnCommand –专门处理WM_COMMAND
    //----------------------------------------------------------------------
    LONG OnCommand(HWND hWnd, UINT message,
    WPARAM wParam, LPARAM lParam)
    {
    int i;
    for(i=0; i < dim(_commandEntries); i++) { //命令项目对照表
    if (LOWORD(wParam) == _commandEntries[i].nMessage)
    return((*_commandEntries[i].pfn)(hWnd, message, wParam, lParam));
    }
    return(DefWindowProc(hWnd, message, wParam, lParam));
    }
    //----------------------------------------------------------------------
    LONG OnCreate(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
    {
    ...
    }
    //----------------------------------------------------------------------
    LONG OnAbout(HWND hWnd, UINT wMsg, UINT wParam, LONG lParam)
    {
    ...
    }
    //----------------------------------------------------------------------

        这样WndProc OnCommand 永远不必改变,每有新要处理的消息,只要在_messageEntries[ ] _commandEntries[ ] 两个数组中加上新元素,并针对新消息撰写新的处理例程即可。

        这种观念以及作法就是MFC Message Map 的雏形。MFC 把其中的动作包装得更好更精致(当然因此也就更复杂得多),成为一张庞大的消息地图;程序一旦获得消息,就可以按图上溯,直到被处理为止。

    3、对话框的运行

    wps_clip_image-8325

    wps_clip_image-2575

    wps_clip_image-20443

    参考

    [1] 深入浅出MFC

    [2] http://msdn.microsoft.com/en-us/library/0x0cx6b1%28VS.80%29.aspx

  • 相关阅读:
    从视频中每隔固定帧进行提取图片
    np.concatenate的超简单理解
    python-OOP(面向对象)
    机器学习中的ground truth
    深度学习网络中backbone是什么意思?
    缓存
    Linux基础命令
    openoffice相关命令
    HTTP协议
    Solr基础
  • 原文地址:https://www.cnblogs.com/mydomain/p/1963948.html
Copyright © 2011-2022 走看看