网站服务器空间大小,qq推广引流网站,软件培训机构,wordpress程序不能升级转自#xff1a;https://blog.csdn.net/kinghzking/article/details/6180956
2008年04月06日 星期日 00:09
控件通知消息有很多种#xff0c;但是有一种是很常用#xff0c;但是又不是很容易掌握的#xff0c;那就是WM_NOTIFY#xff0c;我试着对此做一下比较全面的论述…转自https://blog.csdn.net/kinghzking/article/details/6180956
2008年04月06日 星期日 00:09
控件通知消息有很多种但是有一种是很常用但是又不是很容易掌握的那就是WM_NOTIFY我试着对此做一下比较全面的论述有不对的地方还希望各路大虾批评指正。 控件通知消息 在《深度解析VC中的消息上》中我们提到了消息的分类有3种窗口消息、命令消息和控件通知消息我们这里要谈的是最后一种控件通知消息。 控件通知消息是指这样一种消息一个窗口内的子控件发生了一些事情需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框以及Windows公共控件如树状视图、列表视图等。例如单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。 它类似于命令消息当用户与控件窗口交互时那么控件通知消息就会从控件窗口发送到它的主窗口。但是这种消息的存在并不是为了处理用户命令而是为了让主窗口能够改变控件例如加载、显示数据。例如按下一个按钮他向父窗口发送的消息也可以看作是一个控件通知消息单击鼠标所产生的消息可以由主窗口直接处理然后交给控件窗口处理。 控件通知消息主要由窗口类即直接或间接由CWND类派生类处理。 控件通知格式 控件通知经历了一个演变过程因而SendMessage( )的变量Message、wParam和lParam有三种格式。 第一控件通知格式 第一控件通知格式只是窗口消息的子集。它的特征格式如下WM_XXXX。它主要来自下面的3种消息类型 (1)表示一个控件窗口要么已经被创建或销毁要么已经被鼠标单击的消息WM_PARENTNOTIFY (2)发送到父窗口用来绘制自身窗口的消息例如 WM_CTLCOLOR、WM_DRAWITEM、WM_MEASUREITEM、WM_DELETEITEM、WM_CHARTOITEM、WM_VKTOITEM、WM_COMMAND和WM_COMPAREITEM (3)有滚动调控件发送通知父窗口滚动窗口的消息WM_VSCROLL和WM_HSCROLL 第二控件通知格式 第二控件通知格式与命令消息共享它的特征格式如下WM_COMMAND。 在WM_COMMAND中lParam用来区分是命令消息还是控件通知消息如果lParam为NULL则这是个命令消息否则lParam里面放的必然就是控件的句柄是一个控件通知消息。对于wParam则是低位放的是控件ID高位放的是相应的消息事件。 第三控件通知格式 这个才真正涉及到我们要讲的内容同时他也是最为灵活的一种格式。它的特征格式如下WM_NOTIFY。 在WM_NOTIFY中lParam中放的是一个称为NMHDR结构的指针。在wParam中放的则是控件的ID。 NMHDR结构的由来 NMHDR结构是很值得一提的该结构包括有关制作该通知的控件的任何内容而不受空间和类型的限制他的来历也是很有意思的。 在最初的windows3.x中根本就不存在什么WM_NOTIFY控件通知它们父窗口如鼠标点击,控件背景绘制事件通过发送一个消息到父窗口。简单的通知仅发送一个WM_COMMAND消息包含一个通知码和一个在wParam中的控件ID及一个在lPraram中的控件句柄。这样一来wParam和lParam就都被填充了没有额外的空间来传递一些其它的消息例如鼠标按下的位置和时间。 为了克服这个困难windows3.x就提出了一个比较低级的解决策略那就是给一些消息添加一些附加消息最为明显的就是控件自画用到的DRAWITEMSTRUCT。不知道大家对这个结构熟悉不不过如果你是老手你应该非常清楚这个结构这个结构包含了9个内容几乎你需要控制的信息都给你提供了。为什么说它比较低级呢因为不同的消息附加的内容不同结果就是一盘散沙非常混乱。 在win32中MS又提出了一个更好的解决方案引进NMHDR结构。这个结构的引进就是消息统一起来利用它可以传递复杂的信息。这个结构的布局如下 NMHDR { HWnd hWndFrom ; 相当于原WM_COMMAND传递方式的lParam UINT idFrom ; 相当于原WM_COMMAND传递方式的wParamlow-order UINT code ; 相当于原WM_COMMAND传递方式的Notify Code(wParams high-order) } 对于这个结构的应用于WM_NOTIFY信息结构结果WM_NOTIFY就变成了 A、无附加信息。结构变得很简单就是一个NMHDR结构。 B、有附加信息。定义一个大的结构它的第一个元素就是NMHDR结构它的后面放置附加信息。 WM_NOTIFY结构的好处 除了上面我们所说的好处外WN_NOTIFY还有自己的独特的好处 由于在大结构中第一个成员为NMHDR,这样一来我们就可以利用指向NMHDR的指针来传递结构地址根据指针的特性无论消息有没有附加信息这个指针都适用也能够很方便的进行强制转换。 分析ON_NOTIFY 类向导可以创建ON_NOTIFY消息映射入口并提供一个处理函数的框架来处理 WM_NOTIFY类型的消息。ON_NOTIFY消息映射宏有如下语法. ON_NOTIFY(wNotifyCode,id,memberFxn) 其中wNotifyCode:要处理的通知消息通知码。比如上面我们提到的LVN_KEYDOWNId:控件标识IDMemberFxn:处理此消息的成员函数。 此成员函数有如下的原型声明: afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result); 比如:假设你想成员函数OnKeydownList1处理ClistCtrl(标识IDIDC_LIST1的 LVN_KEYDOWN消息,你可以使用类向导添加如下的消息映射: ON_NOTIFY( LVN_KEYDOWN, IDC_LIST1, OnKeydownList1 ) 在上面的例子中,类向导提供如下函数: void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult) { LV_KEYDOWN* pLVKey (LV_KEYDOWN*)pNMHDR; *pResult 0; } 这时类向导提供了一个适当类型的指针你既可以通过pNMHDR也可以通过 pLVKey来访问这个通知结构。 ON_NOTIFY_RANGE 有时我们可能需要为一组控件处理相同的WM_NOTIFY消息。这时需要使用ON_NOTIFY_RANGE而不是ON_NOTIFY。不过很不幸的是VC6的ClassWizard并不支持这个消息所以我们必须手工添加。方法和一般的手工添加的消息一样不过需要注意的是 (1)当你使用 ON_NOTIFY_RANGE时,你需要指定控件的ID范围.其消息映射入口及函数原型如下: ON_NOTIFY_RANGE( wNotifyCode, id, idLast, memberFxn ) 其中wNotifyCode:消息通知码.比如:LVN_KEYDOWN。id: 第一控件的标识ID。 idLast:最后一个控件的标识ID。标识值一定要连续memberFxn: 消息处理函数。 (2)成员函数必须有如下原型申明afx_msg void memberFxn( UINT id, NMHDR * pNotifyStruct, LRESULT * result );