VC++ 自定义消息学习总结

来源:互联网 发布:淘宝有聊天壁纸设置吗 编辑:程序博客网 时间:2024/05/02 04:39

VC添加自定义消息

http://blog.csdn.net/jinnee_cumtb/article/details/4524375
 
  VC的ClassWizard不允许增加用户自定义消息,所以你必须手工进行添加。当你添加了自定义的消息以后,ClassWizard就可以像处理其它消息一样处理你定义的消息了。
一、VC6添加自定义消息
    1、定义消息。在Windows中,所有的消息都用一个特定的整数值来表示,为了避免自定义消息与已存在的其他消息发生冲突,应该利用Windows提供 的一个常量:WM_USER,小于这个常量的是系统保留的。即用户自定义的消息至少为WM_USER+1,注意最后表示的消息的数值不要超过 0x7FFF。在开发Windows95应用程序时,Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用 WM_USER消息。
    #define UM_PROGRESS WM_USER + 100
    2、在类头文件的AFX_MSG块中声明消息处理函数:
    class CMainFrame:public CFrameWnd{
    protected:
    //{{AFX_MSG(CMainFrame)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    3、在类的实现文件中,使用ON_MESSAGE宏指令将消息映射到消息处理表中。
    BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
        ON_WM_CREATE()
        ON_WM_TIMER()
        ON_MESSAGE(UM_PROGRESS, OnProgress)//注意这条语句的后面没有分号
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP() 
    4、实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。
    LPESULT CMainFrame::OnProgress(WPARAM wParam,LPARAM lParam){
       CRect rect;
       m_wndStatusBar.GetItemRect(2,&rect); //获得窗格区域
       //创建进度栏,注意第三个参数为CWnd* pParentWnd,根据情况选择父窗体
       m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_VERTICAL,rect,this,123);
       m_progress.SetPos(50);
       return 0;
    }
    5、在适当的时候发送自定义消息,进行消息处理。需要注意使用SendMessage还是PostMessage进行处理:SendMessage是消息处理完毕后再返回;而PostMessage则是把消息放到消息队列后立即返回。
    SendMessage(UM_PROGRESS); 
    PostMessage(UM_PROGRESS);    
    如果用户需要整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。
二、VC2003添加自定义消息
    在VC2003中添加自定义消息和VC6基本一致。需要注意的是VC6处理的消息可以没有参数,但VC2003消息处理的函数必须带有两个参数 wParam和lParam,并且其返回值类型为LRESULT。这里,还有另一种方法可以实现地定义消息的处理(VC6和VC2003均适用):
    1、定义消息:#define UM_PROGRESS WM_USER + 100
    2、重载CMainFrame的DefWindowProc函数,然后添加对用户自定义消息处理:
    LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam,
                                      LPARAM lParam){
        switch(message){
       case UM_PROGRESS:{
            //通过指定资源ID获得相应的索引
            int index = m_wndStatusBar.CommandToIndex(IDS_PROGRESS); 
           CRect rect;
          m_wndStatusBar.GetItemRect(index,&rect);
           m_progress.Create(WS_CHILD|WS_VISIBLE,rect, &m_wndStatusBar
                              ,123);
           m_progress.SetPos(50);
           break;
        }
        default:
            break;
     }
     return CFrameWnd::DefWindowProc(message, wParam, lParam);
    }
========

自定义消息

http://www.cnblogs.com/xydblog/archive/2014/02/25/3566266.html
一、实现过程

  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 wParam和LPARAM lParam。系统在调用函数时,会把这两个参数压栈。 然而函数自身并没有参数。在release优化的情况下,在返回上一级函数时,依据的是这个函数的自动变量,参数等信息,于是这两个参数被系统留了下来,也就是说参数仍然保存在栈中,这样就产生了冲突,所以程序就崩溃了。






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




========

VC/MFC中如何自定义消息


定义一个自定义消息号:const UINT WM_MYMESSAGE = WM_USER + n; // 自定义消息一般大于WM_USER,然后就可以为该消息添加映射了。

  afx_msg LRESULT OnMyMessage ( WPARAM wParam, LPARAM lParam );

  ON_MESSAGE ( WM_MYMESSAGE, OnMyMessage )

  LRESULT cxx::OnMyMessage ( WPARAM wParma, LPARAM lParam )
  {
  ...
  }

  如果该消息不需要返回值,也不需要参数,那么可以使用宏ON_MESSAGE_VOID来映射

  afx_msg void OnMyMessage ();
  ON_MESSAGE_VOID ( WM_MYMESSAGE, OnMyMessage )
  void cxx::OnMyMessage ()
  {
  ...
  }

  复杂全面版本:

  消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。在MFC ClassWizard中不允许添加用户自定义消息,所以我们必须在程序中添加相应代码,以便可以象处理其它消息一样处理自定义消息。通常的做法是采取以下步骤:


  第一步:定义消息。

  推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

  #define WM_MY_MESSAGE (WM_USER+100)

  第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。

  LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
  {
  // TODO: 处理用户自定义消息
  ...
  return 0;
  }

  第三步:在类头文件的AFX_MSG块中说明消息处理函数:

  class CMainFrame:public CMDIFrameWnd


  {


  ...


  // 一般消息映射函数

  protected:

  // {{AFX_MSG(CMainFrame)

  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

  afx_msg void OnTimer(UINT nIDEvent);

  afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()
  }

  第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。


  BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)


  //{{AFX_MSG_MAP(CMainFrame)


  ON_WM_CREATE()


  ON_WM_TIMER()


  ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)


  //}}AFX_MSG_MAP


  END_MESSAGE_MAP()


  如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义消息:


  static UINT WM_MY_MESSAGE=RegisterWindowMessage(User);


  并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。


  当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessage发送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他进程发送消息可通过如下方法发送消息:


  DWORD result;


  SendMessageTimeout(wnd->m_hWnd, // 目标窗口


  WM_MY_MESSAGE, // 消息


  0, // WPARAM


  0, // LPARAM


  SMTO_ABORTIFHUNG |


  SMTO_NORMAL,


  TIMEOUT_INTERVAL,


  &result);


  以避免其它进程如果被阻塞而造成系统死等状态。


  可是如果需要向其它类(如主框架、子窗口、视类、对话框、状态条、工具条或其他控件等)发送消息时,上述方法显得无能为力,而在编程过程中往往需要获取其它类中的某个识别信号,MFC框架给我们造成了种种限制,但是可以通过获取某个类的指针而向这个类发送消息,而自定义消息的各种动作则在这个类中定义,这样就可以自由自在的向其它类发送消息了。


  下面举的例子叙述了向视类和框架类发送消息的方法:


  在主框架类中向视类发送消息:


  视类中定义消息:


  ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定义消息映射


  视类定义消息处理函数:


  // 消息处理函数


  LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)


  {


  // TODO: 处理用户自定义消息


  ...


  return 0;


  }


  //发送消息的测试函数


  void CMainFrame::OnTest()


  {


  CView * active = GetActiveView();//获取当前视类指针


  if(active != NULL)


  active->PostMessage(WM_MY_MESSAGE,0,0);


  }


  在其它类中向视类发送消息:


  //发送消息的测试函数


  void CMainFrame::OnTest()


  {


  CMDIFrameWnd *pFrame;


  CMDIChildWnd *pChild;


  CView *pView;


  //获取主窗口指针


  pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;


  // 获取子窗口指针


  pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();


  //获取视类指针


  pView = pChild->GetActiveView();


  if(pView != NULL)


  pView->PostMessage(WM_MY_MESSAGE,0,0);//发送消息


  }


  其余步骤同上。


  在视类中向主框架发送消息:


  首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下


  //发送消息的测试函数


  void CMessageView::OnTest()


  {


  CFrameWnd * active = GetActiveFrame();//获取当前主窗口框架指针


  if(active != this)


  active->PostMessage(WM_MY_MESSAGE,0,0);


  return 0;


  }


  在其它类中向不同的类发送消息可依次方法类推,这样我们的程序就可以的不受限制向其它类和进程发送消息,而避免了种种意想不到的风险。


  下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消息的具体过程。


  实现步骤:


  第一步:在VC++中新建工程Message,所有ClassWizard步骤选项均为缺省,完成。


  第二步:在主菜单中添加测试菜单为调出对话框,在框架类中建立相应函数OnTest()


  第三步:在资源中建立对话框,通过ClassWizard添加新类TestDialog,添加测试按钮,


  在对话框类中建立相应函数OnDialogTest()


  //通过对话框按钮发送消息的函数


  void TestDialog::OnDialogTest()


  {


  CMDIFrameWnd *pFrame;


  CMDIChildWnd *pChild;


  CView *pView;


  //获取主窗口指针


  pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;


  // 获取子窗口指针


  pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();


  //获取视类指针


  pView = pChild->GetActiveView();


  if(active != NULL)


  active->PostMessage(WM_MY_MESSAGE,0,0);//发送消息


  }


  在Message.h头文件中添加如下语句:


  static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);


  第四步:在视类中添加自定义消息:


  在头文件MessageView.h中添加消息映射


  protected:


  //{{AFX_MSG(CMessageView)


  //}}AFX_MSG


  afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行为添加代码


  DECLARE_MESSAGE_MAP()


  在视类文件MessageView.cpp中的消息映射中添加自定义消息映射


  BEGIN_MESSAGE_MAP(CMessageView, CView)


  //{{AFX_MSG_MAP(CMessageView)


  //}}AFX_MSG_MAP


  // Standard printing commands


  ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行添加代码定义唯一消息


  END_MESSAGE_MAP()


  添加相应的0消息处理函数


  LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)


  {


  CRect rect;


  GetClientRect(&rect);


  InvalidateRect(&rect);


  test=!test;


  return 0;


  }


  在MessageView.h中添加布尔变量 public:BOOL test;


  在视类构造函数中初始化 test变量:test=FALSE;


  修改CMessageView::OnDraw()函数


  void CMessageView::OnDraw(CDC* pDC)


  {


  CMessageDoc* pDoc = GetDocument();


  ASSERT_VALID(pDoc);


  // 以下程序显示消息响应效果


  if(test)


  pDC->TextOut(0,0,消息响应!);


  }


  第五步:显示测试对话框


  在MainFrame类中包含对话框头文件:


  #include TestDialog.h;


  OnTest()函数中添加代码


  void CMainFrame::OnTest()


  {


  TestDialog dialog;


  dialog.DoModal();


  }


  运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果。
========

MFC中自定义消息

http://blog.csdn.net/qihailong123456/article/details/6777112


这篇技术文章不是讨论经典的MFC中的消息工作机理的,讨论消息工作原理、方式和路径的文章在网上和书本中


随处可见。网上众多的讨论都是关于如何响应并进行用户自定义消息映射的;网上还有一些文章介绍如何在自定


义类中响应Windows消息,在本文中都简略叙述。但是,网上大部分的文章没用透彻阐述如何在用户自定义类中


响应自定义消息这一通用方法。 
问题定义如下:用户自定义一个类,这个类不一定要有界面(完全可以是不可视的),要求自定义的类可以响应


某个自定义消息。


首先能够响应消息的类必须都从CCmdTarget类中派生,因为只有以这个类中提供了消息的框架和处理机制,而


CWnd类也派生与此类。CWinApp类、CDocument类、CDocTemplate类等都是CCmdTarget的派生类,即子类;而


CFrameWnd类、CView类、CDialog类等都是从CWnd中派生的,其实也是CCmdTarget的子孙,所以都能够响应消息


,但是响应消息的种类不太相同。


那么,如果自己定义的类要求响应命令消息(就是WM_COMMAND,也就是一些菜单、工具栏中的消息,包括快捷键


,这类消息处理的机制与其他以WM_开头的消息处理机制不同,它具有一条层次明确的消息流动路径),那么自


定义的类可以从CCmdTarget中派生。由于CWnd窗体类派生于CCmdTarget父类,那么从CWnd中派生的类也可以理所


应当的响应命令消息。这种命令消息无论是往已有的一些诸如CWinApp类中还是自定义的类中添加都是一件非常


容易的事情,只需用向导即可,在此不再叙述。


如果用户自定义的类要求响应普通的Windows消息(也就是以WM_开头,除了WM_COMMAND以外的消息,这类消息在


WM_USER以下的是系统消息,WM_USER以上的可以由用户自己定义),那就要求自定义的类必须从CWnd中派生。这


是由于此类消息的处理机制决定的,这类消息没有命令消息那条繁琐的流动路径,而是消息发出者直接发给对应


CWnd的窗体句柄,由CWnd负责消息的响应。所以这类消息必须同一个CWnd类对应,更精确的说必须与一个HWND类


型的窗体句柄相对应。这样得出一个重要的结论,就是从CCmdTarget中派生而没有从CWnd派生的类没有处理此类


消息的能力。


综上所述,就是为什么命令消息可以放到大部分类中处理,包括CWinThread、CWinApp、CDocument、CView、


CFrameWnd或是自定义的类中,而普通Windows消息和用户自定义的消息只能放到CFrameWnd和CView等派生与CWnd


中的类中处理。


由此可见,我们自定义的类要想响应自定义消息就只能从CWnd中派生(当然不响应任何消息的类可以从CObject


中派生)。先来看看如何自定义消息:


在.h中做的工作:


第一步要声明消息:


#define WM_MYMSG WM_USER+8


第二步要在类声明中声明消息映射:


DECLARE_MESSAGE_MAP()


第三步要在类声明中定义消息处理函数:


afx_msg LRESULT MyMsgHandler(WPARAM,LPARAM);


在.cpp中做的工作:


第四步要实现消息映射:


BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()


第五步要实现消息处理函数(当然可以不实现):


LRESULT CMainFrame::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("Hello,World!");
return 0; 
}


在引发或发出消息的地方只用写上:


::SendMessge(::AfxGetMainWnd()->m_hWnd,WM_MYMSG,0,0);


到此,自定义消息完毕,这是好多网上文章都写的东西。大家会发现上面代码是在CMainFrame类中实现的,但是


如果要用自定义类,就没有那么简单了。显然把第四步与第五步的CMainFrame换成自定义的类名(这里我用


CMyTestObject来代表自定义类)是不能正常工作的。原因在于在发送消息的SendMessage函数中的第一个参数是


要响应消息对应的HWND类型的窗体句柄,而CMyTestObject类中的m_hWnd中在没有调用CWnd::Create之前是没有


任何意义的,也就是没有调用CWnd::Create或CWnd::CreateEx函数时,CWnd不对应任何窗体,消息处理不能正常


运作。


所以,又一个重要的结论,在自定义类能够处理任何消息之前一定要确保m_hWnd关联到一个窗体,即便这个窗体


是不可见的。那么有人说,在自定义类的构造函数中调用Create函数就行了,不错,当然也可以在别处调用,只


要确保在消息发送之前。但是,Create的调用很有说法,要注意两个地方,第一个参数是类的名称,我建议最好


设为NULL;第五个参数是父窗体对象的指针,这个函数指定的对象一定要存在,我建议最好为整个程序的主窗体


。还有很多人问第六个参数的意义,这个参数关系不大,是子窗体ID,用于传给父窗体记录以便识别。如下是我


的自定义类的构造函数:


CMyTestObject::CMyTestObject()
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),::AfxGetMainWnd(),1234);
}    //一定要在生成主窗体后使用,在主窗体完成OnCreate消息的处理后


CMyTestObject::CMyTestObject(CWnd *pParent)
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),pParent,1234);
}


不能如下调用Create,因为此时CMyTestObject不关联任何窗体,所以this中的m_hWnd无效:


CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),this,1234);


这时上面四、五两步修改成:


BEGIN_MESSAGE_MAP(CMyTestObject, CWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()


LRESULT CMyTestObject::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("My Messge Handler in My Self-Custom Class!");
return 0; 
}


在类外部发出消息:


CMyTestObject *test=new CMyTestObject();
::SendMessage(test->m_hWnd,WM_MYMSG,0,0);


在类内部某个成员函数(方法)中发出消息:


::SendMessage(m_hWnd,WM_MYMSG,0,0);


最后一个问题便是容易产生警告错误的窗体回收,自定义的类要显式调用窗体销毁,析构函数如下:


CMyTestObject::~CMyTestObject()
{
CWnd::DestroyWindow();
}
 
========

vc中SendMessage自定义消息函数用法实例

http://www.jb51.net/article/56565.htm


这篇文章主要介绍了vc中SendMessage自定义消息函数用法,以实例实行详细讲述了SendMessage的定义、原理与用法,具有一定的实用价值,需要的朋友可以参考下
..本文实例讲述了vc中SendMessage自定义消息函数用法,分享给大家供大家参考。具体如下:


SendMessage的基本结构如下:




复制代码 代码如下:SendMessage(
    HWND hWnd,  //消息传递的目标窗口或线程的句柄。
    UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定义,下文具体介绍,)
    WPARAM wParam, //参数1 (WPARAM 其实是与UINT是同种类型的,
  //在vc编译器中右键有个“转到WPARAM的定义”的选项可以查看。 
    LPARAM lParam); //参数2
其中一些参数的由来如下:


//typedef unsigned int UINT;
//typedef UINT WPARAM;
//typedef LONG LPARAM;
//typedef LONG LRESULT;


例如可以用以下语句:




复制代码 代码如下:::SendMessage(this->m_hWnd, WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0);
这里我发送的消息是本窗体接收的,所以句柄用:this->m_hWnd
这里的消息类别WM_MY_DOSOME就是我自定义的,
在接收消息的窗体或线程所在的头文件里:




复制代码 代码如下:#define WM_MY_DOSOME WM_USER+1 // do something
当然你还可以定义更多如:


复制代码 代码如下:#define WM_DOOTHER WM_USER+2 // do other
表示要做一些事情。


到这里,可能大家还是对消息类别有点模糊,不要担心,下面很快就讲到。
我们发了一个消息出去,那么接收方要能识别这个消息是干什么,就是通过消息类别来区分,并且开始去做这个消息对应要处理的事情。如下:


一、编写一个事情:
我们在接收窗体里定义一个这样的事情(过程),




复制代码 代码如下:afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2)
{
 MessageBox("收到消息了,我要开始做一些事情了。","收到",MB_OK);
 //可以运用iParam1,iParam2 来做一些事情。
 return 0;
}
这个事情有3点大家要注意,非常重要:


1. 使用了afx_msg,并且要将afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2)
改写到头文件的 
//{{AFX_MSG 
//。。。改写到这里,颜色会变成灰的。这一点非常重要。
//}}AFX_MSG
2. 参数有2个,WPARAM iParam1,LPARAM iParam2,哪怕没有东西传进来也要写,不然会吃苦头的,vc里不会提醒你少写了一个,
但一些莫名奇妙的事情会发生。
3. 类型用 LRESULT,完了要return 0;


二、让接收方知道什么时候做这个事情:
我们在




复制代码 代码如下://{{AFX_MSG_MAP
//。。。这里写上
ON_MESSAGE(WM_MY_DOSOME,DoSomeThing)
//如果还有其他消息就再写一个
ON_MESSAGE(WM_DOOTHER,DoOther)
//}}AFX_MSG_MAP
到这里,当你用SendMessage,发了一个WM_MY_DOSOME类型的消息过来的时候,接收方就会去做DoSomeThing(WPARAM iParam1,LPARAM iParam2)
发了一个WM_DOOTHER类型的消息过来的时候,接收方就会去做DoOther(WPARAM iParam1,LPARAM iParam2)当然,这里DoOther我还没有定义。


这样就是一个完整的消息发送与接受过程,这里没有详细讲参数,iParam1,因为还没有用到很复杂的情况,


在头文件里:




复制代码 代码如下:#define WM_MYMSG  WM_USER+5 //自定义一个消息


afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam); //自定义消息的处理函数声明


在.cpp文件里:




复制代码 代码如下:ON_MESSAGE(WM_MYMSG, OnMyMessage)
//利用ON_MESSAGE()宏在自定义消息与其处理函数间建立映射关系


void CModelessDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
//从lParam中取出CString对象的指针,并将字符串内容在IDC_MSGEDIT中显示出来
{


    CString *str;
    str=(CString *)lParam;


    SetDlgItemText(IDC_EDIT,*str);
}


按下按钮发送消息




复制代码 代码如下:void CModelessDlg::OnMsgBTN() 
{
 CString str= "自定义消息被触发了!";
 SendMessage(WM_MYMSG, 0, (LPARAM) &str);
 //给ModelessDlg自己发一个自定义的消息
}
希望本文所述对大家的VC程序设计有所帮助。


========
0 0