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; m_bHighLight = TRUE; } } 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->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); 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);