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子项可编辑的简便操作