MFC 重载CListCtrl实现可编辑功能

  1. 头文件

#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("");
}

转载于:https://my.oschina.net/qihaitao/blog/395090

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值