zoukankan      html  css  js  c++  java
  • 消息处理(一)

    每个窗口应用都有一个消息队列,线程通过消息循环机制不断地从该队列中取出消息进行处理。

    一、标准窗口消息的处理

    对于标准窗口消息而言,其处理仅限于某个窗口。首先,由窗口类本身处理,若未处理,则传递给基类处理,对所有的祖先类都不能处理的,则由一个MFC提供的一个全局的默认的处理函数进行处理。

    常用窗口消息:

    WM_CREATE消息:当调用CreateWindowEx或CreateWindow请求创建窗口时,就会向被创建的窗口发送该消息。只有在WM_CREATE消息处理之后,CreateWindowEx或CreateWindow调用才会返回。重载CWnd::OnCreate时,如果返回0,这表示继续创建窗口;如果返回-1,则将终止窗口的创建。

    WM_DESTROY消息:当窗口被销毁时,就会发送该消息。该消息首先被传递给被销毁的窗体,然后传递给他所有的子窗体。

    WM_NCDESTROY消息:该消息用于通知窗口,无客户区可以被销毁DestroyWindow函数将在发送WM_DEATROY消息之后紧接着发送该消息,该消息是消息生存期内的最后一个消息。

    WM_CLOSE消息:当请求关闭一个窗口时,向该窗口发送WM_CLOSE消息。不要在OnClose中进行任何自定义资源的清理操作!

    二、命令消息的处理

    命令消息来自菜单、组合键或按钮的单击事件。跟标准窗口消息不同,它们没有默认的处理程序。因此,为这些类别的消息命名处理程序时只受到约定的限制。

    (1)使用命令处理链处理同一命令

    CMsgStudyApp.h
    
    //{{AFX_MSG(CMsgStudyApp)
    //NOTE - the ClassWizard will add and remove member functions here.
    //DO NOT EDIT what you see in these blocks of generated code !
    afx_msg BOOL OnButton1(UINT nID);
    afx_msg BOOL OnHelp(UINT nID);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    
    CMsgStudyApp.cpp
    
    BEGIN_MESSAGE_MAP(CMsgStudyApp, CWinApp)
    //{{AFX_MSG_MAP(CMsgStudyApp)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //DO NOT EDIT what you see in these blocks of generated code!
    //}}AFX_MSG
    //ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    ON_COMMAND_EX(ID_HELP,OnHelp)  //这个可以沿着处理链处理
    ON_COMMAND_EX(IDC_BUTTON1,OnButton1) //这个为什么不行
    END_MESSAGE_MAP()
    
    
    BOOL CMsgStudyApp::OnButton1(UINT nID)
    {
          AfxMessageBox("This is CMsgStudyApp");
          //返回FALSE,允许沿着处理链继续处理
         return FALSE;
    }
    
    BOOL CMsgStudyApp::OnHelp(UINT nID)
    {
          AfxMessageBox("This is CMsgStudyApp");
          //返回FALSE,允许沿着处理链继续处理
         return FALSE;
    }
    
    
    CMsgStudyDlg.h
    
    // Generated message map functions
    //{{AFX_MSG(CMsgStudyDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg BOOL OnButton1(UINT nID);
    afx_msg BOOL OnHelp(UINT nID);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    
    CMsgStudyDlg.cpp
    
    BEGIN_MESSAGE_MAP(CMsgStudyDlg, CDialog)
    //{{AFX_MSG_MAP(CMsgStudyDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_COMMAND_EX(IDC_BUTTON1,OnButton1)
    ON_COMMAND_EX(ID_HELP,OnHelp)
    END_MESSAGE_MAP()
    
    BOOL CMsgStudyDlg::OnButton1(UINT nID)
    {
        AfxMessageBox("This is CMsgStudyDlg");
        //返回FALSE,允许沿着处理链继续处理
        return FALSE;
    }
    
    BOOL CMsgStudyDlg::OnHelp(UINT nID)
    {
        AfxMessageBox("This is CMsgStudyDlg");
        //返回FALSE,允许沿着处理链继续处理
       return FALSE;
    }

    (2)给一组命令提供相同的处理

    .h
    
    afx_msg void OnButton(UINT nID);
    
    .cpp
    
    ON_COMMAND_RANGE(IDC_BUTTON1,IDC_BUTTON4,OnButton)
    
    void CMsgStudyDlg::OnButton(UINT nID)
    {
        switch(nID)
        {
        case IDC_BUTTON1:
            AfxMessageBox("This is BUTTON1");
            break;
        case IDC_BUTTON2:
            AfxMessageBox("This is BUTTON2");
            break;
        case IDC_BUTTON3:
            AfxMessageBox("This is BUTTON3");
            break;
        case IDC_BUTTON4:
            AfxMessageBox("This is BUTTON4");
            break;
        default:
            break;
        }
    }

         为同一个命令添加多个消息映射项能编译通过(程序本身没有问题),但只有第一个匹配的消息映射项才会起作用。因为在MFC默认情况下顺次搜索消息映射表,只要在消息映射表中找到一个匹配项,就返回。
    三、反射消息的处理

    父窗体在处理控件窗口的通知消息,如WM_CTLCOLOR、WM_COMMAND和WM_NOTIFY时,会首先把该消息转化为反射消息,并转交给控件子窗体优先处理该消息。只有在控件子窗体不处理该消息的情况下,父窗体才有机会处理。

  • 相关阅读:
    STM32中断优先级理解
    STM32按键控制程序
    STM32的LED驱动程序
    嵌入式程序员应知道的0x10个C语言Tips[转]
    【Unity】使用RenderTexture为物体生成快照
    对装饰模式(Decorator)的解读
    设计模式之初:理解面向对象设计
    windows RT系统下解决网络丢包问题
    IOS推出测试平台
    小米路由试用心得3——关于数据备份及客户端软件
  • 原文地址:https://www.cnblogs.com/chengtulang/p/3183519.html
Copyright © 2011-2022 走看看