现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

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

2012-09-07 07:02 工业·编程 ⁄ 共 2176字 ⁄ 字号 暂无评论

   因为以前都是在对话框里面使用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 { 

  1.     NMHDR hdr; 
  2. int iItem; 
  3. int iSubItem; 
  4. UINT uNewState; 
  5. UINT uOldState; 
  6. UINT uChanged; 
  7.     POINT ptAction; 
  8. LPARAM lParam; 
  9. } 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 ) 

  1.     NM_LISTVIEW*   pNMListView   =   (NM_LISTVIEW*)pNMHDR;    
  2.     *pResult   =   NULL;    
  3. if(pNMListView->iItem   ==   -1)    
  4. return;    
  5. if(pNMListView->uNewState & LVIS_SELECTED == LVIS_SELECTED) 
  6.     {    
  7. //item   is   selected
  8. //......
  9.     }    

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

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

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

这点估计以后要用到

给我留言

留言无头像?