MFC编程->可编辑List Control控件

        List Control使用时,要使得单元格内内容可编辑,list控件代码需要重写。


#if !defined(AFX_EDITLISTCTRL_H__A02CE0B0_FF7B_4A54_8570_12B03905EC3E__INCLUDED_)
#define AFX_EDITLISTCTRL_H__A02CE0B0_FF7B_4A54_8570_12B03905EC3E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditListCtrl.h : header file
// Download by http://www.codefans.net

/
//CItemEdit window

class CItemEdit : public CEdit
{
	// Construction
public:
	CItemEdit();
	
	// Attributes
public:
	
	// Operations
public:
	
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CItemEdit)
	//}}AFX_VIRTUAL
	
	// Implementation
public:
	int m_iXPos;
	virtual ~CItemEdit();
	
	// Generated message map functions
protected:
	//{{AFX_MSG(CItemEdit)
	afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
	//}}AFX_MSG
	
	DECLARE_MESSAGE_MAP()
};

/

/
// CEditListCtrl window
// Download by http://www.codefans.net
class CEditListCtrl : public CListCtrl
{
// Construction
public:
	CEditListCtrl();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CEditListCtrl)
	protected:
	virtual void PreSubclassWindow();
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~CEditListCtrl();

	// Generated message map functions
protected:
	//{{AFX_MSG(CEditListCtrl)
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnPaint();
	afx_msg void OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	//}}AFX_MSG
	afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
	DECLARE_MESSAGE_MAP()
private:
	int m_iSubItem;            //子项标识符
	int m_iItem;               //主项标识符
	BOOL m_bHighLight;         //是否高亮文本
	BOOL m_bFocus;             //是否绘制焦点框
	CItemEdit m_edtItemEdit;   // 用于子类化EditLabel函数返回的CEdit*指针
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_EDITLISTCTRL_H__A02CE0B0_FF7B_4A54_8570_12B03905EC3E__INCLUDED_)


// EditListCtrl.cpp : implementation file
// Download by http://www.codefans.net

#include "stdafx.h"
#include "EditListCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CEditListCtrl

CEditListCtrl::CEditListCtrl()
{
	m_iItem = -1;
	m_iSubItem = -1;
	
	m_bHighLight = FALSE;
	m_bFocus = FALSE;
}

CEditListCtrl::~CEditListCtrl()
{
}


BEGIN_MESSAGE_MAP(CEditListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(CEditListCtrl)
	ON_WM_LBUTTONDOWN()
	ON_WM_PAINT()
	ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginlabeledit)
	ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()

/
// CEditListCtrl message handlers

void CEditListCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default

	m_bFocus = TRUE;

	LVHITTESTINFO  lvhit;
	lvhit.pt = point;
	int item = SubItemHitTest(&lvhit);
	
	//if (over a item/subitem)
	if (item != -1 && (lvhit.flags & LVHT_ONITEM))
	{
		CListCtrl::OnLButtonDown(nFlags, point);
		
		if(m_bHighLight && m_iItem == lvhit.iItem && m_iSubItem == lvhit.iSubItem)
		{
			//第二次单击
			EditLabel(m_iItem);
			return;
		}
		else
		{
			//第一次单击
			m_iItem = lvhit.iItem;
			m_iSubItem = lvhit.iSubItem;
			
		}
	}
	else
	{
		if(m_edtItemEdit.m_hWnd == NULL)
		{
			//未出现文本编辑框时
			m_bHighLight = FALSE;
		}
		
		CListCtrl::OnLButtonDown(nFlags, point);
	}
	
	Invalidate();
}

//EditLabel() cause this function has been called
void CEditListCtrl::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;

	// TODO: Add your control notification handler code here
	if (m_iSubItem >= 0)
    {
		ASSERT(m_iItem == pDispInfo->item.iItem);
		
		CRect  rcSubItem;
		GetSubItemRect( pDispInfo->item.iItem, m_iSubItem, LVIR_BOUNDS, rcSubItem);
		
		//get edit control and subclass
		HWND hWnd= (HWND)SendMessage(LVM_GETEDITCONTROL);
		ASSERT(hWnd != NULL);
		VERIFY(m_edtItemEdit.SubclassWindow(hWnd));

		//move edit control text 4 pixel to the right of org label,
		//as Windows does it...
		m_edtItemEdit.m_iXPos = rcSubItem.left + 4;
		m_edtItemEdit.SetWindowText(GetItemText(pDispInfo->item.iItem, m_iSubItem));
	}

	*pResult = 0;
}


void CEditListCtrl::OnPaint() 
{	
	//CPaintDC dc(this); // device context for painting	
	
	if (m_iSubItem >= 0 && m_edtItemEdit.m_hWnd)	
	{
		CRect	rect;
		CRect	rcEdit;
		m_edtItemEdit.GetWindowRect(rcEdit);
		ScreenToClient(rcEdit);

		GetSubItemRect(m_iItem, m_iSubItem, LVIR_LABEL, rect);

		//当文本编辑框缩小时,擦除露出的项文本高亮部分
		if (rcEdit.right < rect.right)
		{
			rect.left = rcEdit.right;
			CClientDC dc(this);
			dc.FillRect(rect, &CBrush(::GetSysColor(COLOR_WINDOW)));
			ValidateRect(rect);
		}
	}

	CListCtrl::OnPaint();
}


void CEditListCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
	LV_ITEM	*plvItem = &pDispInfo->item;
	
	if (m_iSubItem >= 0)
	{
		if (plvItem->pszText != NULL )
		{
			SetItemText(plvItem->iItem,m_iSubItem, plvItem->pszText);
		}
		
		VERIFY(m_edtItemEdit.UnsubclassWindow()!=NULL);	
		*pResult = 0;
	}

	//编辑文本时对控件父窗口操作(如单击其它控件)引发"OnEndlabeledit"时刷新控件
	CRect rect;
	GetWindowRect(&rect);
	CPoint point;
	::GetCursorPos(&point);
	if(!rect.PtInRect(point))
	{
		m_iItem = -1;
		m_iSubItem = -1;
		m_bFocus = FALSE;
		m_bHighLight = FALSE;
	}
}

void CEditListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
	//draw each item.set txt color,bkcolor....
	NMLVCUSTOMDRAW* pNMLVCustomDraw = (NMLVCUSTOMDRAW*)pNMHDR;
	
	// Take the default processing unless we set this to something else below.
	*pResult = CDRF_DODEFAULT;
	
	// First thing - check the draw stage. If it's the control's prepaint
	// stage, then tell Windows we want messages for every item.
	
	if (pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_PREPAINT)
	{
		*pResult = CDRF_NOTIFYITEMDRAW;
	}
	else if (pNMLVCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
	{
		// This is the notification message for an item.  We'll request
		// notifications before each subitem's prepaint stage.
		*pResult = CDRF_NOTIFYSUBITEMDRAW;
	}
	else if (pNMLVCustomDraw->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
	{
		// store the colors back in the NMLVCUSTOMDRAW struct
		// but it's effective only when *pResult = CDRF_DODEFAULT 

		//	pNMLVCustomDraw->clrText = RGB(0, 0, 255);
		//	pNMLVCustomDraw->clrTextBk = RGB(0, 255, 0);
		//	*pResult = CDRF_DODEFAULT;
		
		// This is the prepaint stage for a subitem. Here's where we set the
		// item's text and background colors. Our return value will tell
		// Windows to draw the subitem itself, but it will use the new colors
		// we set here.
		int iItem = (int)pNMLVCustomDraw->nmcd.dwItemSpec;
		int iSubItem = pNMLVCustomDraw->iSubItem;
		
		CDC* pDC = CDC::FromHandle(pNMLVCustomDraw->nmcd.hdc);
		
		CString strItemText = GetItemText(iItem, iSubItem);
		CRect rcItem, rcText;
		GetSubItemRect(iItem, iSubItem, LVIR_LABEL, rcItem);
		rcText = rcItem;
		
		CSize size = pDC->GetTextExtent(strItemText);
		if(strItemText == _T(""))
		{
			size.cx = 41; 
		}
		
		//设置文本高亮矩形
		rcText.left += 4;
		rcText.right = rcText.left + size.cx + 6;
		if(rcText.right > rcItem.right)
		{
			rcText.right = rcItem.right;
		}
		
		COLORREF crOldTextColor = pDC->GetTextColor();

		//绘制项焦点/高亮效果
		if(m_bFocus)
		{
			
			if((m_iItem == iItem) && (m_iSubItem == iSubItem))
			{	
				if(m_bHighLight)
				{					
					
					pDC->FillSolidRect(&rcText, ::GetSysColor(COLOR_HIGHLIGHT));
				}
				pDC->DrawFocusRect(&rcText);
			}		
		}
		
		//绘制项文本
		rcItem.left += 6;
		pDC->DrawText(strItemText, &rcItem, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP);

		pDC->SetTextColor(crOldTextColor);
		*pResult = CDRF_SKIPDEFAULT;// We've painted everything.
	}	
}


void CEditListCtrl::PreSubclassWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	CListCtrl::PreSubclassWindow();
	ModifyStyle(0, LVS_EDITLABELS);
}

void CEditListCtrl::OnKillFocus(CWnd* pNewWnd) 
{
	CListCtrl::OnKillFocus(pNewWnd);
	
	// TODO: Add your message handler code here
	CRect rect;
	GetWindowRect(&rect);
	CPoint point;
	::GetCursorPos(&point);
	if(!rect.PtInRect(point) && GetParent()->GetFocus() != NULL)
	{
		m_iItem = -1;
		m_iSubItem = -1;
		m_bFocus = FALSE;
		m_bHighLight = FALSE;
		Invalidate();
	}
	
}


void CEditListCtrl::OnSetFocus(CWnd* pOldWnd) 
{
//	CListCtrl::OnSetFocus(pOldWnd);
	
	// TODO: Add your message handler code here
	
}

/
// CItemEdit

CItemEdit::CItemEdit()
{
}

CItemEdit::~CItemEdit()
{
}


BEGIN_MESSAGE_MAP(CItemEdit, CEdit)
    //{{AFX_MSG_MAP(CItemEdit)
    ON_WM_WINDOWPOSCHANGING()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CItemEdit message handlers

void CItemEdit::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
	lpwndpos->x = m_iXPos;
	
	CEdit::OnWindowPosChanging(lpwndpos);
	
	// TODO: Add your message handler code here
	
}


在对话框dlg.h文件里添加以下代码:

        CEditListCtrl m_EditListCtrl;

在对话框dlg.cpp文件里

//m_EditListCtrl初始化
m_EditListCtrl.InsertColumn(0, _T("参数名"), LVCFMT_LEFT, 110);//单元格宽度
m_EditListCtrl.InsertColumn(1, _T("参数"), LVCFMT_LEFT, 110);
m_EditListCtrl.InsertColumn(2, _T("参数名"), LVCFMT_LEFT, 110);
m_EditListCtrl.InsertColumn(4, _T("参数"), LVCFMT_LEFT, 110);

m_EditListCtrl.InsertItem(0, _T("min_win"));
m_EditListCtrl.SetItemText(0, 2, _T("patch_size"));
m_EditListCtrl.SetItemText(0, 1, _T("15"));
m_EditListCtrl.SetItemText(0, 3, _T("15"));

        m_EditListCtrl.InsertItem(1, _T("ncc_thesame"));
m_EditListCtrl.SetItemText(1, 2, _T("valid"));
m_EditListCtrl.SetItemText(1, 1, _T("0.95"));
m_EditListCtrl.SetItemText(1, 3, _T("0.5"));



获取参数代码如下:

     TCHAR szBuf[1024];
      LVITEM lvi;
      lvi.iItem = nItemIndex;
      lvi.iSubItem = 0;
      lvi.mask = LVIF_TEXT;
      lvi.pszText = szBuf;
      lvi.cchTextMax = 1024;
      m_list.GetItem(&lvi);

     

  

调试如上图。





  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值