自定义消息

一、实现过程

  1. 使用宏定义消息ID,例如:

#define    WM_OCRRESULT  (WM_USER+101)

   其中WM_USER为系统消息和用户自定义消息的分界线,小于WM_USER的消息被系统所占用,如:WM_LBUTTONDOWN消息,大于WM_USER的消息为用户自定义消息;

  2. 在类声明AFX_MSG块中声明消息响应函数的原型,例如:

afx_msg void OnOcrResult(WPARAM wParam, LPARAM lParam);   函数可以有返回值,也可以无返回值; 函数原型可以有参数,也可以无参数,如果无参数,经常导致在debug下正常运行,release下程序就奔溃了。
class CDlgOCRMain : public CDialog
{
protected: 
    // Generated message map functions
    //{{AFX_MSG(CDlgOCRMain)
    virtual BOOL OnInitDialog();
    afx_msg void OnDestroy();
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg BOOL OnEraseBkgnd(CDC *pDC);
    afx_msg void OnPaint();
    afx_msg void OnOcrResult(WPARAM wParam, LPARAM lParam);
    //}}AFX_MSG 
    DECLARE_MESSAGE_MAP()
}

  3. 在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消 
息处理函数中,格式为:ON_MESSAGE(MsgID,MsgFun)

    注意:ON_MESSAGE一定要放到AFX_MSG_MAP之后,END_MESSAGE_MAP()之前

BEGIN_MESSAGE_MAP(CDlgOCRMain, CDialog)
    //{{AFX_MSG_MAP(CDlgOCRMain)
    ON_WM_DESTROY()
    ON_WM_SIZE()
    ON_WM_ERASEBKGND()
    ON_WM_PAINT()
    //}}AFX_MSG_MAP 

    ON_MESSAGE(WM_OCRRESULT, OnOcrResult) 
END_MESSAGE_MAP()

   4. 实现消息处理函数

void CDlgOCRMain::OnOcrResult(WPARAM wParam, LPARAM lParam)
{
  //........................               
}

 二、自定义消息出错

  如果我们消息响应函数原型为: afx_msg void OnXXXX(); 则在经常导致在debug下正常运行,release下程序就奔溃了。

  解决方法:

      afx_msg void OnXXXX()改为afx_msg void OnXXXX(WPARAM wParam, LPARAM lParam)

  原因:

    当有自定义的消息产生时,系统会调用自定义消息处理函数,系统想当然的认为这个函数有两个参数,分别是WPARAM wParamLPARAM lParam。系统在调用函数时,会把这两个参数压栈。 然而函数自身并没有参数。在release优化的情况下,在返回上一级函数时,依据的是这个函数的自动变量,参数等信息,于是这两个参数被系统留了下来,也就是说参数仍然保存在栈中,这样就产生了冲突,所以程序就崩溃了。

    在debug下,每调用一个函数时,系统会把当前函数在堆栈中的位置保存在一个寄存器中(SP),当函数执行完毕后返回上一级函数时,SP指针返回到函数调用前SP指针指向的位置。也就是说保证了入栈和出栈的一致性。

原文地址:https://www.cnblogs.com/xydblog/p/3566266.html