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

来源:互联网 发布:日本的电视直播软件 编辑:程序博客网 时间:2024/04/29 13:12
 

   丫的,被一个粗心的小错误折腾了半天,总算是把CDockPane上CListCtrl的消息响应给搞定了。

    因为以前都是在对话框里面使用CListCtrl控件,可以在VC6里面的ClassWizard里面直接就给该控件添加各种消息处理函数。

但是到了Feature Pack里面,可以把CListCtrl放到一个CDockPane上面,这时就比较郁闷了,所以只能手工添加消息的处理。

为此,我特意到VC6下新建了一个对话框,并加上一个CListCtrl控件,并添加了LVN_ITEMCHANGED消息,及其处理函数。

 

    然后我就如法炮制,跑到VS2010的项目里面,到CListCtrl所属的CStlListWnd的消息映射里面手工加上

[cpp] view plaincopyprint?ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList1) 
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList1)

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

然后添加对应的处理函数

[cpp] view plaincopyprint?afx_msg void OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult); 
afx_msg void OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult);

 

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

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

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

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

[cpp] view plaincopyprint?NM_LISTVIEW*   pNMListView   =   (NM_LISTVIEW*)pNMHDR; 
NM_LISTVIEW*   pNMListView   =   (NM_LISTVIEW*)pNMHDR;

NM_LISTVIEW结构体的定义如下

[cpp] view plaincopyprint?typedef struct tagNMLISTVIEW { 
    NMHDR hdr; 
    int iItem; 
    int iSubItem; 
    UINT uNewState; 
    UINT uOldState; 
    UINT uChanged; 
    POINT ptAction; 
    LPARAM lParam; 
} NMLISTVIEW, *LPNMLISTVIEW; 
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被选中而触发的消息

 

代码大致如下:

[cpp] view plaincopyprint?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  
        //......  
    }    

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即0x1000和0x2000

这点估计以后要用到

 

 

原创粉丝点击