Step 1. 建立一個 ListCtrlEdit Class 將以下的程式碼依序輸入
ListCtrlEdit.h
#if !defined(_ListCtrlEDIT_H_) #define _ListCtrlEDIT_H_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ListCtrl.h : header file // #include "afxcmn.h" #define IDC_MY_LIST_EDITBOX 0xffff #define MLSM_ITEMCHANGED (WM_USER + 200) ///////////////////////////////////////////////////////////////////////////// // CListCtrl window class CListCtrlEdit : public CListCtrl { // Construction public: CListCtrlEdit(){}; virtual ~CListCtrlEdit(){}; CEdit m_Edit; int m_Flag; public: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CListCtrl) public: virtual BOOL PreTranslateMessage(MSG* pMsg); //}}AFX_VIRTUAL // Implementation protected: int m_Row; int m_Col; //{{AFX_MSG(CListCtrl) afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); afx_msg void OnKillfocusEdit(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif
ListCtrlEdit.cpp
#include "stdafx.h" #include "ListCtrlEdit.h" ////////////////////////////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CListCtrlEdit, CListCtrl) ON_WM_LBUTTONDBLCLK() //ON_WM_LBUTTONDOWN() ON_WM_MEASUREITEM() ON_EN_KILLFOCUS(IDC_MY_LIST_EDITBOX, OnKillfocusEdit) END_MESSAGE_MAP() void CListCtrlEdit::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CListCtrl::OnLButtonDblClk(nFlags, point); LVHITTESTINFO hi; hi.pt = point; if(SubItemHitTest(&hi) != -1 ) { if (hi.iSubItem == 0 || hi.iSubItem == 1)//限制可編輯欄位 return; m_Row = hi.iItem; m_Col = hi.iSubItem; if(m_Edit.m_hWnd == NULL) { RECT rect; rect.left = rect.top = 0; rect.bottom = 20; rect.right = 100; m_Edit.Create(WS_CHILD | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, rect, this, IDC_MY_LIST_EDITBOX); m_Edit.SetFont(this->GetFont(), FALSE); } CRect rect; GetSubItemRect(hi.iItem, hi.iSubItem, LVIR_BOUNDS, rect); m_Edit.SetWindowText(this->GetItemText(hi.iItem, hi.iSubItem)); m_Edit.MoveWindow(&rect); m_Edit.ShowWindow(SW_SHOW);//顯示編輯框 m_Edit.MoveWindow(&rect);//將編輯框移動到子項上面,覆蓋在子項上 m_Edit.SetFocus();//使編輯框取得焦點 m_Edit.CreateSolidCaret(1, rect.Height()-5);//創建一個光標 m_Edit.ShowCaret();//顯示光標 m_Edit.SetSel(-1);//使光標移到最後面 } } void CListCtrlEdit::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CListCtrl::OnLButtonDown(nFlags, point); LVHITTESTINFO hi; hi.pt = point; if(SubItemHitTest(&hi) != -1 ) { if (hi.iSubItem == 0 ) return; m_Row = hi.iItem; m_Col = hi.iSubItem; if(m_Edit.m_hWnd == NULL) { RECT rect; rect.left = rect.top = 0; rect.bottom = 20; rect.right = 100; m_Edit.Create(WS_CHILD | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, rect, this, IDC_MY_LIST_EDITBOX); m_Edit.SetFont(this->GetFont(), FALSE); } CRect rect; GetSubItemRect(hi.iItem, hi.iSubItem, LVIR_BOUNDS, rect); m_Edit.SetWindowText(this->GetItemText(hi.iItem, hi.iSubItem)); m_Edit.MoveWindow(&rect); m_Edit.ShowWindow(1); m_Edit.SetSel(0, 100); m_Edit.SetFocus(); } } BOOL CListCtrlEdit::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class BOOL bHandledMsg = FALSE; if(pMsg->hwnd == m_Edit.m_hWnd) { switch (pMsg->message) { case WM_KEYDOWN: { switch (pMsg->wParam) { case VK_RETURN: if(m_Row != -1) { CString ItemText; m_Edit.GetWindowText(ItemText); this->SetItemText(m_Row, m_Col, ItemText); ::PostMessage(GetParent()->m_hWnd, MLSM_ITEMCHANGED, (WPARAM)MAKELONG(m_Row, m_Col), (LPARAM)this->m_hWnd); } break; case VK_ESCAPE: m_Edit.ShowWindow(0); m_Col = m_Row = -1; bHandledMsg = TRUE; break; } } break; } } return (bHandledMsg ? TRUE : CListCtrl::PreTranslateMessage(pMsg)); } void CListCtrlEdit::OnKillfocusEdit() { if(m_Edit.m_hWnd != NULL) { m_Edit.ShowWindow(0); if(m_Row != -1 && m_Row != 1) { CString ItemText; m_Edit.GetWindowText(ItemText); this->SetItemText(m_Row, m_Col, ItemText); ::PostMessage(GetParent()->m_hWnd, MLSM_ITEMCHANGED, (WPARAM)MAKELONG(m_Row, m_Col), (LPARAM)this->m_hWnd); } } m_Row = m_Col = -1; m_Edit.ShowWindow(0); }
Step 2. 使用CListCtrlEdit Class在自己的Project上宣告一個物件即可使用。
參考資料:
- MFC 重载CListCtrl实现可编辑功能
- MFC可编辑CListCtrl
- 使CListCtrl可編輯(轉)
- CListCtrl可編輯列值封裝類
- ListCtrl控件可编辑
- MFC实现CListCtrl子项可编辑的简便操作