头文件
#if !defined(AFX_MYLISTCTRLEDIT_H__7FDA9396_E298_4F10_B778_EB8ADFD82F9A__INCLUDED_)
#define AFX_MYLISTCTRLEDIT_H__7FDA9396_E298_4F10_B778_EB8ADFD82F9A__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyListCtrl.h : header file
//
//#define IDC_MY_LIST_EDITBOX 0xffff
#define MLSM_ITEMCHANGED (WM_USER + 200)
/
// CMyListCtrl window
#include "afxcmn.h"
class CMyListCtrlEdit : public CListCtrl //可编辑
{
// Construction
public:
CMyListCtrlEdit(){};
// Attributes
public:
int m_Flag;
// Operations
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyListCtrl)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
//}}AFX_VIRTUAL
// Implementation
public:
virtual
~CMyListCtrlEdit(){};
CEdit m_EditItem;
// Generated message map functions
protected:
int m_Row;
int m_Col;
//{{AFX_MSG(CMyListCtrl)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
//afx_msg void OnNMKillfocusEdit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnKillfocusEdit();
//afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);//行高
//afx_msg void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif
实现函数
#include "stdafx.h"
#include "MyListCtrlEdit.h"
BEGIN_MESSAGE_MAP(CMyListCtrlEdit, CListCtrl)
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_MEASUREITEM()
ON_EN_KILLFOCUS(IDC_MY_LIST_EDITBOX, OnKillfocusEdit)
//ON_NOTIFY(TVN_SELCHANGED, IDC_MY_LIST_EDITBOX, &CMyListCtrl::OnNMKillfocusEdit)
END_MESSAGE_MAP()
/*************************************************************************
在鼠标左键双击事件中,主要的任务是需要判断被双击的单元格,
如果单元格有效,则需要进入编辑模式,并显示文本框用来响应用户的输入,代码如下:
****************************************************/
void CMyListCtrlEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
/*LVHITTESTINFO hi;
hi.pt = point;
if(SubItemHitTest(&hi) != -1 )
{
if (hi.iSubItem == 0 || hi.iSubItem == 1)
goto exit_label;
m_Row = hi.iItem;
m_Col = hi.iSubItem;
if(m_Row == 1 && m_Col == 2)
{
m_Flag = 1;
goto exit_label;
}
else
m_Flag = 0;
if(m_EditItem.m_hWnd == NULL)
{
RECT rect;
rect.left = rect.top = 0;
rect.bottom = 20;
rect.right = 100;
m_EditItem.Create(WS_CHILD | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, rect, this, IDC_MY_LIST_EDITBOX);
m_EditItem.SetFont(this->GetFont(), FALSE);
}
CRect rect;
GetSubItemRect(hi.iItem, hi.iSubItem, LVIR_BOUNDS, rect);
m_EditItem.SetWindowText(this->GetItemText(hi.iItem, hi.iSubItem));
m_EditItem.MoveWindow(&rect, TRUE);
m_EditItem.ShowWindow(1);
}
exit_label:*/
CListCtrl::OnLButtonDblClk(nFlags, point);
}
/**************************************************************/
/*在鼠标单击事件中,我们需要判断用户单击的是不是其他的单元格,
如果是,表示用户希望退出编辑模式了,此时,需要保存编辑之后的文本:
如果单元格有效,则需要进入编辑模式,并显示文本框用来响应用户的输入*/
/*************************************************************/
void CMyListCtrlEdit::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 )
//goto exit_label;
return;
m_Row = hi.iItem;
m_Col = hi.iSubItem;
if(m_EditItem.m_hWnd == NULL)
{
RECT rect;
rect.left = rect.top = 0;
rect.bottom = 20;
rect.right = 100;
m_EditItem.Create(WS_CHILD | ES_LEFT | WS_BORDER | ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, rect, this, IDC_MY_LIST_EDITBOX);
m_EditItem.SetFont(this->GetFont(), FALSE);
}
CRect rect;
GetSubItemRect(hi.iItem, hi.iSubItem, LVIR_BOUNDS, rect);
m_EditItem.SetWindowText(this->GetItemText(hi.iItem, hi.iSubItem));
m_EditItem.MoveWindow(&rect, TRUE);
m_EditItem.ShowWindow(1);
m_EditItem.SetSel(0, 100);
m_EditItem.SetFocus();
}
//exit_label:
//m_Col = m_Row = -1;
}
/***********************************************************
在PreTranslateMessage函数中,需要截获按键时间中的回车键和ESC键,并保存或取消编辑:
**********************************************************/
BOOL CMyListCtrlEdit::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
BOOL bHandledMsg = FALSE;
if(pMsg->hwnd == m_EditItem.m_hWnd)
{
switch (pMsg->message)
{
case WM_KEYDOWN:
{
switch (pMsg->wParam)
{
case VK_RETURN://回车
if(m_Row != -1)
{
CString ItemText;
m_EditItem.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);
}
case VK_ESCAPE://ESC键
m_EditItem.ShowWindow(0);
m_Col = m_Row = -1;
bHandledMsg = TRUE;
break;
default:
break;
}
}// case WM_KEYDOWN
break;
default:
break;
}// switch(pMsg->message)
}// if(pMsg->hwnd
return (bHandledMsg ? TRUE : CListCtrl::PreTranslateMessage(pMsg));
}
void CMyListCtrlEdit::OnKillfocusEdit()
{
if(m_EditItem.m_hWnd != NULL)
{
m_EditItem.ShowWindow(0);
if(m_Row != -1 && m_Row != 1)
{
CString ItemText;
m_EditItem.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_EditItem.ShowWindow(0);
//m_EditItem.SetWindowTextA("");
}