=WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别(控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息)
=WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别
所谓消息反射就是控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息
1、“=WM_VSCROLL”是消息反射标志 , WM_VSCROLL是 消息响应的标志,在VC6.0的ClassWizard中注意会发现这两个不同的消息,VS2010中没有“=WM_VSCROLL”,但是可以通过手动添加:
消息映射宏声明:
- BEGIN_MESSAGE_MAP(CMyScrollBar, CScrollBar)
- //{{AFX_MSG_MAP(CMyScrollBar)
- ON_WM_VSCROLL() //普通消息
- ON_WM_VSCROLL_REFLECT() //反射消息,由控件自身处理
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
消息响应函数
- //响应“WM_VSCROLL”消息
- void CMyScrollBar::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: Add your message handler code here and/or call default
- CScrollBar::OnVScroll(nSBCode, nPos, pScrollBar);
- }
- //响应“=WM_VSCROLL”消息
- void CMyScrollBar::VScroll(UINT nSBCode, UINT nPos)
- {
- // TODO: Add your message handler code here
- }
注意:上面两个“TODO”的内容是有区别的
2、以MFC基于对话框工程来讲解:
a. CMyDialog,CMyApp,然后添加一个CMyScrollBar:public CScrollBar类
b. 在MyDialog.h中添加垂直滚动条,绑定一个变量
CMyScrollBar m_Vsrcrollbar;
c. 在CMyDialog中OnInitDialog函数中初始化上面的变量
- //初始化垂直滚动条
- int i_scroMax = 100;
- m_Vscrollbar.SetScrollRange(0,i_scroMax);
- m_Vscrollbar.SetScrollPos(50);
d. 为CMyScrollBar类添加"WM_VSCROLL"消息(这个消息是反射消息)响应函数 (通过ClassWiard)
- #define INT_SBLINEUP 4
- #define INT_SBLINEDOWN 4
- #define INT_SBPAGEUP 25
- #define INT_SBPAGEDOWN 25 //下面所有代码都会使用
- void CMyScrollBar::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: Add your message handler code here and/or call default
- int pos,*Minpos,*Maxpos;
- pos = GetScrollPos();
- GetScrollRange(Minpos,Maxpos);
- switch( nSBCode )
- {
- case SB_LINEUP:
- if( pos > *Minpos )
- pos -= INT_SBLINEUP;
- break;
- case SB_LINEDOWN:
- if( pos < *Maxpos )
- pos += INT_SBLINEDOWN;
- break;
- case SB_PAGEUP:
- if( pos-INT_SBPAGEUP > *Minpos )
- pos -= INT_SBPAGEUP;
- else
- pos = *Minpos;
- break;
- case SB_PAGEDOWN:
- if( pos+INT_SBPAGEDOWN < *Maxpos )
- pos += INT_SBPAGEDOWN;
- else
- pos = *Maxpos;
- break;
- case SB_THUMBPOSITION:
- pos = nPos;
- break;
- }
- SetScrollPos(pos,TRUE);
- CScrollBar::OnVScroll(nSBCode, nPos, pScrollBar);
- }
编译运行后,单击滚动条发现没有任何反应;在上面的函数上加断点,调试发现触发WM_VSCROLL消息后,根本没有调用这个函数。那么如何让CMyScrollBar类控件对象自己处理“WM_VSCROLL”消息呢?请看“第e步”。
e.为CMyScrollBar类添加"=WM_VSCROLL"消息(这个消息是反射消息)响应函数 (通过类视图,右键单击类名|Add Windows Message Handler....,用ClassWizard也行)
- void CMyScrollBar::VScroll(UINT nSBCode, UINT nPos)
- {
- // TODO: Add your message handler code here
- int pos,Minpos=0,Maxpos=100;
- pos = GetScrollPos();
- GetScrollRange(&Minpos,&Maxpos);
- switch( nSBCode )
- {
- case SB_LINEUP:
- if( pos > Minpos )
- pos -= INT_SBLINEUP;
- break;
- case SB_LINEDOWN:
- if( pos < Maxpos )
- pos += INT_SBLINEDOWN;
- break;
- case SB_PAGEUP:
- if( pos-INT_SBPAGEUP > Minpos )
- pos -= INT_SBPAGEUP;
- else
- pos = Minpos;
- break;
- case SB_PAGEDOWN:
- if( pos+INT_SBPAGEDOWN < Maxpos )
- pos += INT_SBPAGEDOWN;
- else
- pos = Maxpos;
- break;
- case SB_THUMBPOSITION:
- pos = nPos;
- break;
- }
- SetScrollPos(pos,TRUE);
- }
运行后发现垂直滚动条可以很好的运行;调试发现,触发WM_VSCROLL消息后,会跳到下面这个函数中
- CMyScrollBar::VScroll(UINT nSBCode, UINT nPos)
总结:两个消息的宏声明不一样
- BEGIN_MESSAGE_MAP(CMyScrollBar, CScrollBar)
- //{{AFX_MSG_MAP(CMyScrollBar)
- ON_WM_VSCROLL() //普通消息
- ON_WM_VSCROLL_REFLECT() //反射消息,由控件自身处理
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
f. 在MyDialog.h中添加垂直滚动条,绑定一个变量
CMyScrollBar m_srcrolbar;
g. 在CMyDialog中OnInitDialog函数中初始化上面的变量
- int i_scroMax = 100;
- m_scrolbar.SetScrollRange(0,i_scroMax);
- m_scrolbar.SetScrollPos(50);
h. 在CMyDialog类中响应WM_VSROLL消息响应
- void CMyDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- int pos,Minpos=0,Maxpos=0;
- pos = m_scrolbar.GetScrollPos();
- m_scrolbar.GetScrollRange(&Minpos,&Maxpos);
- switch( nSBCode )
- {
- case SB_LINEUP:
- if( pos > Minpos )
- pos -= INT_SBLINEUP;
- break;
- case SB_LINEDOWN:
- if( pos < Maxpos )
- pos += INT_SBLINEDOWN;
- break;
- case SB_PAGEUP:
- if( pos-INT_SBPAGEUP > Minpos )
- pos -= INT_SBPAGEUP;
- else
- pos = Minpos;
- break;
- case SB_PAGEDOWN:
- if( pos+INT_SBPAGEDOWN < Maxpos )
- pos += INT_SBPAGEDOWN;
- else
- pos = Maxpos;
- break;
- case SB_THUMBPOSITION:
- pos = nPos;
- break;
- }
- m_scrolbar.SetScrollPos(pos,TRUE);
- CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
- }
运行发现m_srcolbar对象对应的控件可以正常的运行。因为这个OnVscroll函数中的代码是针对m_srcolbar对象设计的,故其可以正确运行。
J. 上面的代码看起来很不和谐,有个办法能很好的解决这个问题,就是让绑定控件的变量m_Vscrollbar的类Child自己现实“WM_SCROLL”消息响应函数Child::OnVScroll函数,其父窗体类CFatherDlg也实现“WM_SCROLL”消息响应函数CFatherDlg::OnVScroll,然后用如下方式调用:
Mark:20131215,(VC6/VS2010环境下调试)此函数被调用了两次,难以理解!即使为空函数体也是这种情况,求解!
- //Mark:20131215
- void CFatherDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- if( pScrollBar->GetDlgCtrlID() == m_Vscrollbar.GetDlgCtrlID()) //如果消息对应的控件ID号是我要处理的控件则进行对应处理
- {
- m_Vscrollbar.OnVScroll(nSBCode,nPos,pScrollBar);
- }
- //这样就可以针对控件的ID号分别控制多个垂直滚动条,而达到互不干扰、代码思路清晰的好处
- CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
- }
注意:上面的m_Vscrollbar对象的OnVscroll函数一定要声明成public访问权限,用ClassWizard添加的是Protected访问权限,可以自己手动改过来。
3、总结
如果要控件对应的对象自己处理一个消息,那么控件类自己必须实现“=WM_XXXX”反射响应函数;如果让控件的拥有者相对应的对象处理这个消息,那么应该在改对象的类中实现“WM_XXX”普通响应函数,并针对这个控件绑定的对象设计代码。
http://blog.csdn.net/qq2399431200/article/details/17336455
=WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别(控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息)的更多相关文章
- 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘
[C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...
- LockWindowUpdate的函数的用法(不忽略消息,只是暂时不响应,但WM_SETREDRAW根本不接受重绘消息)
Application.ProcessMessages;LockWindowUpdate(Self.Handle); //锁住当前窗口 LockWindowUpdate(0)//解除锁定窗口 Loc ...
- Objective-c中的对象间的消息传递以及消息路由
刚开始使用Objective-C时,总是习惯将对象间发送消息之间称呼为方法调用.心想,这和c#不是一回事吗?不就是调用实例方法吗,还搞个消息发送作甚,最后还不是要转化为方法的调用?通过一段时间的理解学 ...
- Delphi 消息函数 SendMessage函数和 PostMessage的区别
SendMessage函数 将指定的消息发到窗口.它调用特定窗口的窗口处理函数,并且不会立即返回,直到窗口处理函数处理了这个消息. PostMessage函数 将一个消息放入与创建这个窗口的消息队列相 ...
- 反射,内省,BeanUtil的区别
PS:为了操作反射方便,sun创建了 内省, Apache闲麻烦自己创建了BeanUtils 1.开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所 ...
- Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法
Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...
- python 面向对象专题(六):元类type、反射、函数与类的区别、特殊的双下方法
目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3. 函数与类的区别 4. 特殊的双下方法 1. 元类type type:获取对象 ...
- WCF消息交换模式之请求-响应模式
WCF的消息交换模式(MEP)有三种:请求/响应.单向模式和双工模式.WCF的默认MEP是请求/响应模式. 请求/响应模式操作签名代码如下,无需指定模式,默认就是. [OperationContrac ...
- 消息点击事件的响应链---hitTest:withEvent:方法
*当用户点击屏幕时,会产生一个触摸事件,系统会将触摸事件加入到 UIApplication管理事件队里中 *UIApplication 会从事件队列中取出最前面的事件进行分发以便处理,通常,先发送事件 ...
随机推荐
- 编写Linux中sh文件执行时出现莫名字符的问题
今天在项目中需要编写一个sh,执行一些初始化操作,然后调取原来的执行文件,但是我在操作中主要到了首行需要加入#!/bin/sh 的表达式,但是在执行时总是报错,原因是每次执行,表达式后边都会添加一个莫 ...
- erlang 中带下划线变量的使用
在erlang里'_'是一个特殊的变量(其实erlang里不应该叫“变”量,照顾习惯,姑且这么叫吧),它可以代替任何东西,在match的时候非常有用,例如: {A, _, [B|_], {B}} = ...
- Spring处理跨域请求
[nio-8080-exec-8] o.s.web.cors.DefaultCorsProcessor : Skip CORS processing: request is from s ...
- 《Head First 设计模式》学习笔记——命令模式
在软件系统,"行为请求者"与"行为实施者"通常存在一个"紧耦合".但在某些场合,比方要对行为进行"记录.撤销/重做.事务" ...
- Less小总结
= 导航 顶部 变量 混合 继承 函数 顶部 变量 混合 继承 函数 Less 是一个Css 预编译器,意思指的是它可以扩展Css语言,添加功能如允许变量(variables),混合(mi ...
- WinForm - 无边框窗体自定义移动
为了界面的好看,有时候需要将窗体FormBorderStyle属性设为None,这样就可以根据自己的喜欢来设计界面.但这样窗体无法进行移动的.而且默认的窗体(FormBorderStyle=Sizab ...
- 对偶空间(dual linear space)
1. 定义 设 V 为定义在数域 F 上的向量空间,定义 V 上的线性函数是从 V 到 F 的映射:f:V→F,且满足 ∀x,y∈V,k∈F 有:f(x+y)=f(x)+f(y),f(ka)=kf(a ...
- Opencv中SVM样本训练、归类流程及实现
支持向量机(SVM)中最核心的是什么?个人理解就是前4个字--"支持向量",一旦在两类或多累样本集中定位到某些特定的点作为支持向量,就可以依据这些支持向量计算出来分类超平面,再依据 ...
- 《Planet Earth II》观看笔记
carrion:n. 腐肉:臭尸:不洁之物 cub:n. 幼兽:不懂规矩的年轻人:chick; n. 小鸡:小鸟:少妇 herd:兽群: 1. 高频单词 terrain:n. [地理] 地形,地势:领 ...
- 《Silk》(皇家律师)—— 英美海洋法系
Abortion Act:堕胎法: 1. 表达习惯 we employ him, not the other way round, Officially,-,官方的说法是,Unofficially,- ...