VC添加自定义消息终级版

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宏指令,其余步骤同上。

   6、SendMessage与PostMessage的区别:
      先来看看Send与Post这两个英文单词的意思:Send有发送的意思,而Post具有投寄的意思。
      联想一下现实生活中我们写信(很久很久以前。。。。)来记就很简单了:
      Send:  相当于邮寄员,他会将快件亲手交给收件人,并且需要收件人签字,他才闪人。而在消息机制中,就是说,系统(邮寄员)会将收到的消息(邮局分发)直接发送到某个窗口的窗口过程(收件人),并且需要该窗口作出处理(收件人签字)才返回。 这东东就是SendMessage
      Post:  相当于邮局、邮筒等等,我们写好信好,会将信交给邮局,或投寄到邮筒里,而什么时候发送,发送到哪里都由邮局来处理,我们投寄信件的时候,是不会等候这封信件到达收件人手里,然后才回家的。 而在消息机制中,就是说,系统(我们)将收到的消息(信件)投寄到应用程序的消息循环(相当于邮筒)中,然后就闪人,具体啥时候处理这条消息(啥时候发送邮件),那就得看“办事效率”了。
      区别很明显,SendMessage的消息是不进队列的,而PostMessage的需要排队。 
      但,值得说明的是:虽然一个要进队,一个不进队,但是最终处理消息的地方都一样:都是系统调用窗口过程进行处理(收件人作出反应)
      
     类似的,还有一对函数 PeekMessage和GetMessage~~~~
    7、PreTranslateMessage
     我们可以PreTranslateMessage来对消息预处理,该用的用,不该用的不用。那么,是否Send和Post来的消息我们都可以用它来预处理呢?
     答案当然是否定的:如果你在深圳,要写封信寄到东北去,那么投寄方式有两种:1、自己带着信跑到东北去,2、将信放到邮局,由邮局分发。
     第1 种情况下,就是SendMessage了,这个时候,还有谁能预处理你的信呢?
     第2种情况下,就是PostMessage了,这个时候,嘿嘿,万一运气不好,被邮局给用PreTranslateMessage给截了.....
     所以说,用SendMessage发送的消息是不能用PreTranslateMessage来预处理的。而Post的就可以,因为它要经过“第三者”嘛。
二、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);
    }
三、MFC
                1.  在头文件stdafx.h中增加一个自定义消息宏  
                              #define WM_USER_THREADEND WM_USER + 1

               2.  在于增加新消息的窗口或对话框类的头文件中增加一个回调函数声明,注意要声明为public
                              afx_msg LRESULT OnUserThreadend(WPARAM wParam, LPARAM lParam);

               3.  在窗口或对话框的cpp文件的BEGIN_MESSAGE_MAP,END_MESSAGE_MAP 中增加一行          
                              ON_MESSAGE(WM_USER_THREADEND, OnUserThreadend) 
                
               4.  在窗口或对话框的cpp文件中增加回调函数的实现,如:
                               LRESULT ThreadDialog::OnUserThreadend(WPARAM wParam, LPARAM lParam) 
                                {
                                                TRACE("WM_USER_THREADEND message /n");
                                                return 0;
                                }       

               5.  自定义消息的触发
                               ::PostMessage(GetSafeHwnd(), WM_USER_THREADEND, 0, 0);
                     其中GetSafeHwnd()得到了一个当前窗口的句柄,此消息将发给当前窗口,如果想发送消息给其它                        
                     窗口只需改变这个句柄,前提是目的窗口也实现了此消息的处理函数。

四、vs2010添加自定义消息步骤:

一.在类向导中为对话框类选择 添加之定义消息


2.#define UM_MYMESSAGE WM_USER+1


3.编辑自定义消息处理函数对应的代码。(一般在步骤一只是生成了函数名,还没函数体)


比VC6.0的完全手工添加省事。


这段时间看vc++深入详解.看到添加自定义消息那一节,按照书上的方法就是编译不通过.vc6.0和vs2008中添加消息的方法不同.现在就把添加自定义消息的方法记录下来

红色标记的地方为不同之处.

1.定义消息
#define UM_PROGRESS WM_USER+1

2.类头文件中声明消息响应函数(OnProgress)

vc6.0声明如下

afx_msg void OnProgress();
vs2008声明如下:

afx_msg LRESULT OnProgress(WPARAM wparam,LPARAM lparam);


3.消息映射(消息映射用ON_MESSAGE,命令映射用ON_COMMAND)

在消息映射表中添加映射.在宏BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()之间

vc6.0如下

[cpp]  view plain copy
  1. ON_MESSAGE(UM_PROGRESS,OnProgress)  
[cpp]  view plain copy
  1. ON_MESSAGE(UM_PROGRESS,OnProgress)  

vs2008如下:

ON_MESSAGE(UM_PROGRESS,CMainFrame::OnProgress)

4.定义消息响应函数

  1. LRESULT CMainFrame::OnProgress(WPARAM wparam,LPARAM lparam)  
  2. {  
  3.   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值