自给制ListView控件(基础第一篇)
首先需要了解Windows消息编程的一些基本内容.
Windows操作系统是消息驱动(或称为事件驱动)
例如:
1.用户单击了应用程序的菜单!
2.Windows就像用一个射像头监视你的一举一动.所以它拍到了你单击了应用程序的菜单.
3.Windows告诉应用程序:刚才有个用户单击了菜单,该怎么办?(通过消息来传递)
4.应用程序嘿嘿两下,收到我来搞定.
消息的种类:
1.(系统消息)
Windows利用系统定义的消息控制应用程序(Windows与应用程序通信)
如 LB:列表框控制消息 SBM:滚动条控制消息 WM:通用窗口消息
2.通知消息(从子窗口包括控件发送至它们的父窗口的消息)
Win32使用WM_NOTIFY消息通知它们的父窗口,如鼠标点击,控件背景重绘事件等等
在最初的Windows 3.x中不存在WM_NOTIFY.那么用什么通知呢?
使用一个简单的WM_COMMAND消息来通知
WM_COMMAND结构
{
code(放通知码)
lParam(放控件句柄)
wParam(放控件ID)
}
这样一来lParam,wParam都被填满了,没有额外的空间来传递一些其它消息.
例如:鼠标按下的位置和时间.为了克服这个困难 windows3.x提出了一个比较低级的解决策略.
那就是给一些消息添加附加消息.最为明显的就是控件自画用到的DRAWITEMSTRUCT
这个结构包含9个内容.几乎你需要控件的信息都给你提供了.为什么说它比较低级呢?
因为不同的消息附加的内容不同,结果就是一盘散沙.非常混乱.
在Win32中,MS提出了解个更好的解决安案:引进NMHDR结构.这个结构的引进使得消息统一起来
NMHDR
{
HWnd hWndFrom;相当于原WM_COMMAND传递方式的lParam放控件句柄
UINT idFrom;相当于原WM_COMMAND传递方式的wParam放控件ID
UINT code;相当于原WM_COMMAND传递方式的Notify code通知码
}
现在来说下WM_NOTIFY相对于WM_COMMAND有什么特别之处
{
code;一个通过码
wParam;控件ID,但一般不使用它
lParam;指向NMHDR结构体的指针
某些控件可能会发送更大的结构体,它们的第一个成员必须是NMHDR这样我们可方便的转换
}
比如自绘制传递的通常是 NMCUSTOMDRAW 结构体
typedef struct{
NMHDR hdr;
DWORD dwDrawStage;
} NMCUSTOMDRAW
那么指向 NMCUSTOMDRAW的指针当然也指向了NMHDR了.所以二者的转化就成为了可能.
3.反射消息(自己生的孩子自己养,自已发的消息自已处理)
在Windows里面,子控件经常向父控件发送消息,例如很多子控件要绘制自己的背景,就可能向父窗口发送消息WM_CTLCOLOR。对于从子控件发来的消息,父控件有可能在处理之前,把消息返还给子控件处理,这样消息看起来就想是从父窗口反射回来一样,故此得名:消息反射
你会发现一一对应.OCM_*表示反射的消息
OCM_NOTIFY = OCM_BASE + WM_NOTIFY
消息反射的原理是将发送父窗体的消息加上OCM_BASE在反还给子窗体.
如果子窗体认识的话会减去OCM_BASE
首先需要了解Windows消息编程的一些基本内容.
Windows操作系统是消息驱动(或称为事件驱动)
例如:
1.用户单击了应用程序的菜单!
2.Windows就像用一个射像头监视你的一举一动.所以它拍到了你单击了应用程序的菜单.
3.Windows告诉应用程序:刚才有个用户单击了菜单,该怎么办?(通过消息来传递)
4.应用程序嘿嘿两下,收到我来搞定.
消息的种类:
1.(系统消息)
Windows利用系统定义的消息控制应用程序(Windows与应用程序通信)
如 LB:列表框控制消息 SBM:滚动条控制消息 WM:通用窗口消息
2.通知消息(从子窗口包括控件发送至它们的父窗口的消息)
Win32使用WM_NOTIFY消息通知它们的父窗口,如鼠标点击,控件背景重绘事件等等
在最初的Windows 3.x中不存在WM_NOTIFY.那么用什么通知呢?
使用一个简单的WM_COMMAND消息来通知
WM_COMMAND结构
{
code(放通知码)
lParam(放控件句柄)
wParam(放控件ID)
}
这样一来lParam,wParam都被填满了,没有额外的空间来传递一些其它消息.
例如:鼠标按下的位置和时间.为了克服这个困难 windows3.x提出了一个比较低级的解决策略.
那就是给一些消息添加附加消息.最为明显的就是控件自画用到的DRAWITEMSTRUCT
这个结构包含9个内容.几乎你需要控件的信息都给你提供了.为什么说它比较低级呢?
因为不同的消息附加的内容不同,结果就是一盘散沙.非常混乱.
在Win32中,MS提出了解个更好的解决安案:引进NMHDR结构.这个结构的引进使得消息统一起来
NMHDR
{
HWnd hWndFrom;相当于原WM_COMMAND传递方式的lParam放控件句柄
UINT idFrom;相当于原WM_COMMAND传递方式的wParam放控件ID
UINT code;相当于原WM_COMMAND传递方式的Notify code通知码
}
现在来说下WM_NOTIFY相对于WM_COMMAND有什么特别之处
{
code;一个通过码
wParam;控件ID,但一般不使用它
lParam;指向NMHDR结构体的指针
某些控件可能会发送更大的结构体,它们的第一个成员必须是NMHDR这样我们可方便的转换
}
比如自绘制传递的通常是 NMCUSTOMDRAW 结构体
typedef struct{
NMHDR hdr;
DWORD dwDrawStage;
} NMCUSTOMDRAW
那么指向 NMCUSTOMDRAW的指针当然也指向了NMHDR了.所以二者的转化就成为了可能.
3.反射消息(自己生的孩子自己养,自已发的消息自已处理)
在Windows里面,子控件经常向父控件发送消息,例如很多子控件要绘制自己的背景,就可能向父窗口发送消息WM_CTLCOLOR。对于从子控件发来的消息,父控件有可能在处理之前,把消息返还给子控件处理,这样消息看起来就想是从父窗口反射回来一样,故此得名:消息反射
WM_COMMAND | OCM_COMMAND |
WM_CTLCOLORBTN | OCM_CTLCOLORBTN |
WM_CTLCOLOREDIT | OCM_CTLCOLOREDIT |
WM_CTLCOLORDLG | OCM_CTLCOLORDLG |
WM_CTLCOLORLISTBOX | OCM_CTLCOLORLISTBOX |
WM_CTLCOLORSCROLLBAR | OCM_CTLCOLORSCROLLBAR |
WM_CTLCOLORSTATIC | OCM_CTLCOLORSTATIC |
WM_CTLCOLOR | OCM_CTLCOLOR |
WM_DRAWITEM | OCM_DRAWITEM |
WM_MEASUREITEM | OCM_MEASUREITEM |
WM_DELETEITEM | OCM_DELETEITEM |
WM_VKEYTOITEM | OCM_VKEYTOITEM |
WM_CHARTOITEM | OCM_CHARTOITEM |
WM_COMPAREITEM | OCM_COMPAREITEM |
WM_HSCROLL | OCM_HSCROLL |
WM_VSCROLL | OCM_VSCROLL |
WM_PARENTNOTIFY | OCM_PARENTNOTIFY |
WM_NOTIFY | OCM_NOTIFY |
OCM_NOTIFY = OCM_BASE + WM_NOTIFY
消息反射的原理是将发送父窗体的消息加上OCM_BASE在反还给子窗体.
如果子窗体认识的话会减去OCM_BASE