我们有时候可能想让ListCtrl中的每一个cell(n行,m列)可编辑,或者是想让ListCtrl中的某个cell通过下拉菜单来选择某个范围内的值。这样的需求还是很容易满足的,实现起来也比较简单,在源码网站也可以找到很多的代码,其实实际上就是在当前激活的地方创建一个edit或者combox来实现的。
下面举个简单的例子:可编辑的ListCtrl
从CListCtrl继承,实现我们自己的CEditList。
代码太多,不可能全部粘贴上来,只说明关键的地方,假设是双击进行编辑,重写double click事件函数
----------------------------------------------------------------------------------------------------------------------------------------
void CEditList::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
{
if( GetFocus() != this)
SetFocus();
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
#ifndef _CLICK_LIST_EDIT_
if ( m_fGetType && m_fGetType( pNMListView->iSubItem ) == eEdit )
EditItem (pNMListView->iItem, pNMListView->iSubItem);
#endif
*pResult = 0;
}
-------------------------------------------------------------------------------------------------------------------------------------------
然后实现EditItem函数,这个函数主要做的事情就是在双击的地方获取listctrl的cell的矩形区域,并在此放置一个edit控件,为了控制一些事件,这个edit控件最好是自己写的从CEdit继承下来的。
我在这里是这么实现的:
---------------------------------------------------------------------------------------------------------------------------------------------
CEdit *CEditList::EditItem(int nItem, int nSubItem)
{
CRect rect;
int offset = 0;
if(!EnsureVisible(nItem, TRUE))
{
return NULL;
}
GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
// Now scroll if we need to expose the column
CRect rcClient;
GetClientRect(rcClient);
if( offset + rect.left < 0 || offset + rect.left > rcClient.right )
{
CSize size(offset + rect.left,0);
Scroll(size);
rect.left -= size.cx;
}
rect.left += offset;
rect.right = rect.left + GetColumnWidth(nSubItem);
if(rect.right > rcClient.right)
rect.right = rcClient.right;
// Get Column alignment
LV_COLUMN lvcol;
lvcol.mask = LVCF_FMT;
GetColumn(nSubItem, &lvcol);
DWORD dwStyle;
if((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT)
dwStyle = ES_LEFT;
else if((lvcol.fmt & LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT)
dwStyle = ES_RIGHT;
else
dwStyle = ES_CENTER;
dwStyle |=WS_BORDER|WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
CEditItem *pEdit = NULL;
if ( m_bToolTipCloumnType )
{
CString szTipText = getColumnType( nSubItem );
pEdit = new CEditItem(nItem, nSubItem, GetItemText(nItem, nSubItem), szTipText );
}
else
{
pEdit = new CEditItem(nItem, nSubItem, GetItemText(nItem, nSubItem));
}
#define IDC_EDITCTRL 0xffe0
pEdit->Create(dwStyle, rect, this, IDC_EDITCTRL);
//funny thing happend here, uncomment this,
//and then edit an item,
//enter a long text so that the ES_AUTOHSCROLL comes to rescue
//yes that's look funny, ???.
return pEdit;
}
------------------------------------------------------------------------------------------------------------------------------------------
这样我们就写了自己的ListCtrl,在用的时候,只要将.h和.cpp文件包含到工程中,将原来的CListCtrl m_list改为我们自己的CEditList m_list。这样ListCtrl就具有了可编辑功能,下拉的combox与此类同。扩展下去,我们一样可以实现好多控件。