您的位置:首页 > 其它

动态创建的CListCtrl控件的消息响应

2013-09-05 10:56 190 查看
点击打开链接

因为以前都是在对话框里面使用CListCtrl控件,可以在VC6里面的ClassWizard里面直接就给该控件添加各种消息处理函数。但是到了Feature Pack里面,可以把CListCtrl放到一个CDockPane上面,这时就比较郁闷了,所以只能手工添加消息的处理。为此,我特意到VC6下新建了一个对话框,并加上一个CListCtrl控件,并添加了LVN_ITEMCHANGED消息,及其处理函数。
然后我就如法炮制,跑到VS2010的项目里面,到CListCtrl所属的CStlListWnd的消息映射里面手工加上

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList1)

这里的IDC_LIST就是在CStlListWnd里面创建CListCtrl时所用的ID

然后添加对应的处理函数

afx_msg void OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult);

这里就可以在这个函数里面加一个消息框的函数,然后在ListCtrl上点击时,就可以看到该消息已被处理了。

然后就要完善这个函数了,注意这个函数的第一个参数,它就是我们要考虑的重点。

NMHDR这个结构体是所有NOTIFY消息的用到的参数,但是对于不同控件的NOTIFY消息,它的含义也是不同的。

对于我们所使用的CListCtrl,我们就需要转换一下

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

NM_LISTVIEW结构体的定义如下

typedef struct tagNMLISTVIEW {

NMHDR hdr;

int iItem;

int iSubItem;

UINT uNewState;

UINT uOldState;

UINT uChanged;

POINT ptAction;

LPARAM lParam;

} NMLISTVIEW, *LPNMLISTVIEW;

成员很多,但最有用的就是iItem, uNewState, uOldState;

iItem就是CListCtrl中,状态发生变化的Item的编号,从0开始

uNewState是变化之后的状态

uOldState是变化之前的状态

这两个state可用的值有

LVIS_ACTIVATING

Not currently supported.

LVIS_CUT

The item is marked for a cut-and-paste operation.

LVIS_DROPHILITED

The item is highlighted as a drag-and-drop target.

LVIS_FOCUSED

The item has the focus, so it is surrounded by a standard focus rectangle. Although more than one item may be selected, only one item can have the focus.

LVIS_OVERLAYMASK

The item’s overlay image index is retrieved by a mask.

LVIS_SELECTED

The item is selected. The appearance of a selected item depends on whether it has the focus and also on the system colors used for selection.

LVIS_STATEIMAGEMASK

The item’s state image index is retrieved by a mask.

各项可以进行或运算进行组合

重点关注 LVIS_SELECTED

因为我们要处理某一行被选中的消息,那么必然就是某item的状态转变为LVIS_SELECTED

但是要注意,不能用pNMListView->uNewState == LVIS_SELECTED 来进行判断,因为各个state是可以进行或运算的。

因此应该使用 pNMListView->uNewState & LVIS_SELECTED == LVIS_SELECTED 来判断是该notify消息不是某item被选中而触发的消息

代码大致如下:

void CStlListWnd::OnItemchangedList( NMHDR* pNMHDR, LRESULT* pResult )

{

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

*pResult = NULL;

if(pNMListView->iItem == -1)

return;

if(pNMListView->uNewState & LVIS_SELECTED == LVIS_SELECTED)

{

//item is selected

//……

}

}

如果有兴趣,可以在某次消息触发时,都把iItem, uNewState, uOldState打印出来看看

也许会有意想不到的收获,比如说如果列表框前面设置了复选框,

你会发现复选框是否被选中对应的两个状态是4096和8192即0×1000和0×2000

这点估计以后要用

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: