今天只开篇...头疼...
当我开始深入Windows API编程的时候,我一直觉得Windows的窗体概念的设计是非常有意思的.
在编程的时候有一些和尝试格格不入的概率.尽管刚开始会理解困难,但是编程的时候却发现有着重大的优越性.
不过我对Windows的大多数common Control的设计却不怎么喜欢.
他让会让我这样的新手有时候觉得... 啊...怎么会这样.. 比如说我要捕获一个按钮的XXX事件. 按照我现在的知识面要么翻译整个消息.要么做钩子.. 我觉得两者都不是"正常"的手段. 应该发个消息,替换其处理函数,这样的功能才会显得高效.不知道他为什么不这么设计...也许有类似的功能,我没发现?...
不过对Listview控件的设计我却觉得十分的优秀.我们最常用的Explorer的主要部分就是一个TreeView.
很多系统软件的主要部分也是Listview... 可以说相当的常用.


这个控件虽然看起来简单,但是却是我发现的最复杂的控件之一:
有多复杂呢?
它有135个专用宏,126个专用消息,36个专用通知,27个专用结构.它还有一堆别的控件很少见的专用扩展STYLE.
别的不说,一般控件有两三个专用的结构...它有27个...
我最初使用Listview的时候就给这复杂给吓坏了... 当时在做小学期的软件,拿着几个最基本的添加删除宏.
自己做了一个Liked List,然后动态刷新显示...不停地ListView_SetItemText()...现在想想真是吃力不讨好的事情.
好了,直接说如何绑定数据.
这个简洁的手段的核心就是使用LVITEM的lParam参数.(LVITEM是记录ListView里面Item数据的核心结构.)
1.首先定义一个结构,这个结构用来存储需要保存的单个item的数据.
2.最是当添加数据的时候,使用C++的特性为他new 一个这样的结构,然后把它传给LVITEM的lParam
3.当任何时候需要取得这个数据时使用ListView_GetItem宏将其取出.此时该干嘛干嘛...
4.当需要删除时,先使用free将对应的内存释放..
参考代码:PlayListItem为自定义的结构.
struct PlayListItem {
TCHAR szInfo[MAX_PATH];
TCHAR szTime[10];
TCHAR szFileFullPath[MAX_PATH];
};
//插入数据示例
PlayListItem * rgInfo = new PlayListItem();
HWND hWndListView;
int index;
LVITEM lvI;
...//init
lvI.iItem = index;
lvI.iImage = index;
lvI.iSubItem = 0;
lvI.lParam = (LPARAM) rgInfo;
lvI.pszText = LPSTR_TEXTCALLBACK; // sends an LVN_GETDISP message.
ListView_InsertItem(hWndListView, &lvI);
//取数据示例:
LPNMITEMACTIVATE lpnmitem;
LVITEM lvItem;
....
case NM_DBLCLK:
plvdi = (NMLVDISPINFO*)lParam
lvItem.iItem = lpnmitem->iItem;
lvItem.mask = LVIF_PARAM;
ListView_GetItem(ListView,&lvItem);
//LVN_GETDISPINFO消息实例(由于使用了LPSTR_TEXTCALLBACK)
case LVN_GETDISPINFO:
plvdi = (NMLVDISPINFO*)lParam;
switch (plvdi->item.iSubItem) {
case 0:
plvdi->item.pszText = ((PlayListItem *)plvdi->item.lParam)->szInfo;
break;
case 1:
plvdi->item.pszText = ((PlayListItem *)plvdi->item.lParam)->szTime;
break;
default:
break;
}