近期由于项目的要求,需要一个可以编辑的列表控件,由于MFC提供的列表控件只支持第一行可编辑,无法满足项目需求,故只能自己动手重写一个列表控件。重写列表控件的思想为:当点击列表的某行某列时,在此处创建一个文本框。废话不多说,切入正题。

首先,你需要从CListCtrl继承一个类,名字自己取,这里我取名为CMyListCtrl。其次,从CEdit继承一个类,取名为CMyEdit。

  CMyEdit类的代码如下:

  CMyEdit.h文件

#pragma once
#include "afxwin.h"
#define WM_USER_EDIT_END (WM_USER+1000)//编辑文本框时给列表发送的消息
class CMyEdit :
public CEdit
{
public:
  CMyEdit(void);
  ~CMyEdit(void);
  virtual BOOL PreTranslateMessage(MSG* pMsg);//消息重载函数
  afx_msg void OnChange();//文本框的值改变消息
protected:
  DECLARE_MESSAGE_MAP()
};

CMyEdit.CPP文件

#include "StdAfx.h"
#include "MyEdit.h"

CMyEdit::CMyEdit(void)
{
}

CMyEdit::~CMyEdit(void)
{
}
BEGIN_MESSAGE_MAP(CMyEdit,CEdit)
ON_CONTROL_REFLECT(EN_CHANGE, OnChange)//这里为消息反射
END_MESSAGE_MAP()
BOOL CMyEdit::PreTranslateMessage(MSG* pMsg)
{
  return CEdit::PreTranslateMessage(pMsg);
}

}
void CMyEdit::OnChange()
{
  GetParent()->SendMessage(WM_USER_EDIT_END, WPARAM(m_hWnd), (LPARAM)(m_hWnd));//向列表控件发送消息
}

CMyListCtrl类的代码如下:

CMyListCtrl.h文件

#pragma once
#include "afxcmn.h"
#include "MyEdit.h"

class CMyListCtrl :public CListCtrl
{
DECLARE_DYNAMIC(CMyListCtrl)
public:
CMyListCtrl(void);
~CMyListCtrl(void);
protected:
DECLARE_MESSAGE_MAP()
public:
//afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg LRESULT OnEditEnd(WPARAM wParam,LPARAM lParam = FALSE);//从CMyEdit类接收来的消息
virtual BOOL PreTranslateMessage(MSG* pMsg);//消息重载
afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);//垂直滚动条消息
afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);//水平滚动条消息
afx_msg void OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult);//单击列表控件
public:
void ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl);//显示文本框
CMyEdit m_Edit;
int nItem,nSubItem;//表示行号和列号

};

CMyListCtrl.CPP文件

#include "StdAfx.h"
#include "MyListCtrl.h"
//#define WM_USER_EDIT_END WM_USER+1000
IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl)
CMyListCtrl::CMyListCtrl(void)
{
}

CMyListCtrl::~CMyListCtrl(void)
{
}
BEGIN_MESSAGE_MAP(CMyListCtrl,CListCtrl)
//ON_WM_LBUTTONDOWN()
ON_WM_VSCROLL()//水平滚动条消息
ON_WM_HSCROLL()//垂直滚动条消息
ON_MESSAGE(WM_USER_EDIT_END,OnEditEnd)//从CMyEdit类接收来的消息

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,OnNMCustomdrawList)//重绘列表

ON_NOTIFY_REFLECT(NM_CLICK, OnNMClickList)//单击列表控件
END_MESSAGE_MAP()

BOOL CMyListCtrl::PreTranslateMessage(MSG* pMsg)

{

  return CListCtrl::PreTranslateMessage(pMsg);

}

void CMyListCtrl::OnVScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar)
{
  if (m_Edit.m_hWnd != NULL)
  {
    m_Edit.DestroyWindow();
  }
  CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  Invalidate(FALSE);
}

void CMyListCtrl::OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar)
{
  if (m_Edit.m_hWnd != NULL)
  {
    m_Edit.DestroyWindow();
  }
  CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  Invalidate(FALSE);
}

void CMyListCtrl::OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult)

{ 

  DWORD dwPos = GetMessagePos();
  CPoint point( LOWORD(dwPos), HIWORD(dwPos) );

  ScreenToClient(&point);

  LVHITTESTINFO lvinfo;
  lvinfo.pt = point;

  CRect rcCtrl;
  nItem = CListCtrl::SubItemHitTest(&lvinfo);//得到单击的点行号
  if (nItem == -1)
  {
    return;
  }
  nSubItem = lvinfo.iSubItem;//得到列号

  CListCtrl::GetSubItemRect(nItem,nSubItem,LVIR_LABEL,rcCtrl);//得到所在区域

  ShowEdit(TRUE,nItem,nSubItem,rcCtrl);

}

void CMyListCtrl::ShowEdit(bool bShow, int nItem, int nSubItem, CRect rcCtrl)

{

  if (m_Edit.m_hWnd == NULL)
  {
    m_Edit.Create(ES_AUTOHSCROLL|WS_CHILD|ES_LEFT|ES_WANTRETURN|WS_BORDER,CRect(0,0,0,0),this,0);
    m_Edit.ShowWindow(SW_HIDE);
    CFont tpFont;
    tpFont.CreateStockObject(DEFAULT_GUI_FONT);
    m_Edit.SetFont(&tpFont);
    tpFont.DeleteObject();
  }
  if (bShow == TRUE)
  {
    CString strItem = CListCtrl::GetItemText(nItem,nSubItem);
    m_Edit.MoveWindow(&rcCtrl);
    m_Edit.ShowWindow(SW_SHOW);
    m_Edit.SetWindowText(strItem);
    m_Edit.SetFocus();
    m_Edit.SetSel(-1);
  }
  else
  {
    m_Edit.ShowWindow(SW_HIDE);
  }

}

PS:单击列表控件本应该用afx_msg void OnLButtonDown(UINT nFlags, CPoint point);这里由于项目需要我用的是afx_msg void OnNMClickList(NMHDR *pNMHDR, LRESULT *pResult);有需要的可自行修改。后续会有通过快捷键来编辑列表以及列表内部项的拖动等。第一次写博客,不足之处望见谅,也希望各位博友一起改进!

MFC可编辑的ListCtrl的更多相关文章

  1. MFC控件:listctrl使用方法总结

    以下未经说明,listctrl默认view 风格为report 相关类及处理函数 MFC:CListCtrl类 SDK:以 “ListView_”开头的一些宏.如 ListView_InsertCol ...

  2. MFC可编辑ListBox控件CEditableListBox

    左击选中单元格,右击进入编辑状态. MFC自定义控件的添加方法C#自定义控件编译后就自动出现在工具箱里.MFC的自定义控件需要先拖个基类到对话框上,然后添加一个控件变量.再修改源代码中的控件名为扩展控 ...

  3. MFC:编辑区 Edit 的属性及使用

    Edit Control 编辑控件是 MFC 中使用较多的控件之一 1. Edit 的属性 Acccept Files -> True 控件接受拖放文件 Multiline -> True ...

  4. MFC图形编辑界面工具

    一.背景 喔,五天的实训终于结束了,学校安排的这次实训课名称叫高级程序设计实训,但在我看来,主要是学习了Visual C++ .NET所提供的MFC(Microsoft Foundation Clas ...

  5. MFC 可编辑文本框,MFC控件关联变量总结

    Edit Control控件,默认状态下,按回车会调用OnOK()关闭窗体.解决此bug可以,类视图中单击CMFCApplication3Dlg,下方重写OnOK(),注释掉其中的代码即可. Edit ...

  6. MFC中将编辑框文本转换成整数,从而实现两个整数相加。

    在头文件中,定义三个控件变量,如m_data1,m_data2,m_sum; void Cuse_demo_dllDlg::OnBnClickedButton1(){ CString data1; C ...

  7. MFC中 编辑框输入换行功能

    首先修改编辑框的属性: Multiline 设为true , Auto HScroll 设为true , Auto VScroll 设为 true . 然后响应PreTranslateMessage( ...

  8. MFC 中编辑框数字限制范围

    http://www.cnblogs.com/ziwuge/archive/2011/11/15/2249541.html void CSAAlt::OnEnChangeSlocp()//样本盘号输入 ...

  9. mfc 可编辑 list control

    维护到一个古老的gm工具的时候 需要这个功能 在网上找到一份很好用的代码 贴到这里 再次感谢那位同僚 #pragma once //#include "OrangeMessage.h&quo ...

随机推荐

  1. usaco 地震 && 奶牛观光

    Usaco 地震: Description 一场地震把约翰家的牧场摧毁了,坚强的约翰决心重建家园.约翰已经重建了N个牧场, 现在他希望能修建一些道路把它们连接起来.研究地形之后,约翰发现可供修建的道路 ...

  2. 普通用户从非80端口启动tomcat,通过端口转发监听80端口

    linux下小于1024的端口都需要root去绑定. root权限启动tomcat是不明智的,可以使用非root权限启动tomcat监听8080端口,然后利用端口转发实现对80端口的监听. 端口转发: ...

  3. YII 权限管理

    CREATE TABLE IF NOT EXISTS `admin_role` ( `id` ) unsigned NOT NULL auto_increment, `name` ) NOT NULL ...

  4. 解决Ubuntu Server 12.04换了网卡MAC地址后 网络不可用的问题.

    重装了系统,新建了一个ubuntu虚拟机,加载原来的镜像,结果启动后网络变得不正常了,提示信息 Waiting for network configuration...Waiting up to 60 ...

  5. HTML头部<head>学习

    元素是所有头部元素的容器. 元素包含了所有的头部标签元素.在 元素中你可以插入脚本(scripts), 样式文件(CSS),及各种meta信息. 以下标签都可以添加到 head 部分: 1.title ...

  6. SEO为什么要求网页设计师用DIV+CSS布局网页?

    问:SEO为什么要求网页设计师用DIV+CSS布局网页? 答:通常情况下,SEOer非常喜欢把一个网站做到最细节,在网页设计方面,有时与设计师沟通时,通常会问到:SEO为什么要求网页设计师用DIV+C ...

  7. UVa 872 - Ordering 输出全拓扑排序

    本题要求输出所有拓扑排序的序列. 还好本题的数据量不是非常大.限制在26个大写英文字母,故此能够使用递归法输出. 这个递归输出所有解在Leetcode非常多这种题目的,不小心的话,还是非常难调试的. ...

  8. oracle15 pl/sql 分页

    PL/SQL分页 编写分页过程 无返回值的存储过程 古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解.首先是掌握最简单的存储过程,无返回值的存储过程: ...

  9. fork和exec函数

    #include<unistd.h> pid_t fork(void); 返回:在子进程中为0,在父进程中为子进程IO,若出错则为- fork最困难之处在于调用它一次,它却返回两次.它在调 ...

  10. 如何设计一个更好的C++ ORM

    2016/11/26 "用C++的方式读写数据库,简直太棒了!" 上一篇相关文章:如何设计一个简单的C++ ORM (旧版代码)