博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用.net c#自给制ListView控件(基础第一篇)

Posted on 2007-12-05 20:41  a-peng  阅读(2963)  评论(0编辑  收藏  举报
自给制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。对于从子控件发来的消息,父控件有可能在处理之前,把消息返还给子控件处理,这样消息看起来就想是从父窗口反射回来一样,故此得名:消息反射
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_*表示反射的消息
OCM_NOTIFY = OCM_BASE + WM_NOTIFY
消息反射的原理是将发送父窗体的消息加上OCM_BASE在反还给子窗体.
如果子窗体认识的话会减去OCM_BASE