ListCtrl的扩展类EditListCtrl

该类继承自MFC的CListCtrl类;

实现列可选,多单元格可选,单击选中单元格并能双击编辑,同时也可以设定某一列是否能进行编辑等等。

功能强大,欢迎使用。

<p><span style="font-family: Arial, Helvetica, sans-serif;">头文件:</span></p><p>CEditListCtrl.h</p>
class CEditListCtrl : public CListCtrl
{
	// Construction
public:
	CEditListCtrl();

	// Attributes
public:
	CEdit* m_edit;//指向编辑框
	BOOL m_panduan1;
	UINT Idfrom;
	BOOL * m_isedit;//数组 表明可编辑列号
	//	CEdit* m_edit;//指向编辑框
	int m_subitem;
	int m_item;
	int m_old_item;//在LButtonDown中用来保存起点行数
	int m_old_subitem;//在LButtonDown中用来保存起点列数
	int m_now_item;
	int m_now_subitem;
	//	BOOL DestroyWindow();
	using CListCtrl::DestroyWindow;//重载函数
	BOOL DestroyWindow();
	void SetEditColomn(int col,BOOL edit);

	// Operations
public:
	BOOL m_downmove;
	BOOL m_bCustomDraw;
	int m_nNumberOfRows;
	int m_nNumberOfCols;
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CEditListCtrl)
	//}}AFX_VIRTUAL

	// Implementation
public:
	virtual ~CEditListCtrl();

	// Generated message map functions
protected:
	//{{AFX_MSG(CEditListCtrl)
	afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnSetfocus(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult);
	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnClose();
	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()
private:
	void invalidate_grid(int row,int col);
	afx_msg void custom_draw_funtion(NMHDR *pNMHDR, LRESULT *pResult);
};

源文件:

CEditListCtrl.cpp

// EditListCtrl.cpp : implementation file
//

#include "stdafx.h"
//#include "CEditListDlg.h"
#include "EditListCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////Doctor.W////////////////////////////
// CEditListCtrl
CEditListCtrl::CEditListCtrl()
{
	m_bCustomDraw=TRUE;
	m_now_subitem=-1;
	m_now_item=-1;
	m_old_subitem=-1;
	m_old_item=-1;
	m_nNumberOfRows=0;
	m_nNumberOfCols=0;
	m_downmove=FALSE;
	m_item=-1;
	m_subitem=-1;
	m_edit=NULL;
	m_isedit=NULL;
}

CEditListCtrl::~CEditListCtrl()
{
	if(m_isedit)
		delete [] m_isedit;
	if(m_edit)
		delete m_edit;
}

BEGIN_MESSAGE_MAP(CEditListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(CEditListCtrl)
	ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
	ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
	ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_NOTIFY_REFLECT(NM_SETFOCUS, OnSetfocus)
	ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus)
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,custom_draw_funtion)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEditListCtrl message handlers

void CEditListCtrl::custom_draw_funtion(NMHDR *pNMHDR, LRESULT *pResult)
{

	NMLVCUSTOMDRAW* nmcd=(NMLVCUSTOMDRAW*)pNMHDR;
	*pResult=CDRF_DODEFAULT;

	int row;
	int col;

	switch(nmcd->nmcd.dwDrawStage)
	{
	case CDDS_PREPAINT:
		if(m_bCustomDraw)
			*pResult=CDRF_NOTIFYITEMDRAW; // else CDRF_DODEFAULT which stops notyfication messages
		return;

	case CDDS_ITEMPREPAINT:
		*pResult=CDRF_NOTIFYSUBITEMDRAW;
		return;

	case CDDS_SUBITEM|CDDS_ITEMPREPAINT:
		{
			*pResult=0;

			row=nmcd->nmcd.dwItemSpec;
			col=nmcd->iSubItem;

			CString str=GetItemText(row,col);

			CRect rect;
			CDC* pDC=CDC::FromHandle(nmcd->nmcd.hdc);

			if(col>0)
				GetSubItemRect(row,col,LVIR_BOUNDS,rect);
			else
				GetItemRect(row,&rect,LVIR_LABEL);

			UINT uCode=DT_LEFT;
			int olditem,oldsub,nowitem,nowsub;
			olditem=m_old_item;
			nowitem=m_now_item;
			oldsub=m_old_subitem;
			nowsub=m_now_subitem;
			if (m_old_item>m_now_item)
			{
				olditem=m_now_item;
				nowitem=m_old_item;
			}
			if (m_old_subitem>m_now_subitem)
			{
				oldsub=m_now_subitem;
				nowsub=m_old_subitem;
			}
			if( (row>=olditem&&row<=nowitem)&&(col>=oldsub&&col<=nowsub))
			{
				COLORREF kolor=0xffff5f;//0x004e98;//0xffff00;//lanse
				if(0==col || 1==col || 3==col)
				{
					kolor=0xFFA500;//0xc0c0c0;
					if(GetFocus()==this)
						kolor=0xFFBBFF;//0xaa00aa;
					CBrush brush(kolor);
					pDC->FillRect(&rect,&brush);
				}
				else
				{
					if(GetFocus()==this)
						kolor=0xFFA500;//0xff0000;//shenlan;
				}
				CBrush brush(kolor);
				pDC->FillRect(&rect,&brush);
			}
			else
			{
				if(0==col || 1==col || 3==col)
				{
					COLORREF kolor=0xc0c0c0;
					CBrush brush(kolor);
					pDC->FillRect(&rect,&brush);
				}
				else
				{

					COLORREF kolor=0xC1FFC1;//0xfae9d0;//豆沙绿
					CBrush brush(kolor);
					pDC->FillRect(&rect,&brush);
				}

			}
			rect.OffsetRect(5,0);
			if (col==3)
			{
				pDC->DrawText(str,&rect,DT_CENTER);
			}
			else
				pDC->DrawText(str,&rect,uCode);

			*pResult=CDRF_SKIPDEFAULT;

			break;
		}
	}
}

void CEditListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMITEMACTIVATE* nm=(NMITEMACTIVATE*)pNMHDR;

	m_downmove=FALSE;
	Invalidate();

	if(!m_isedit) return;
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	if(!m_edit)
	{
		m_subitem=pNMListView->iSubItem;
		if(pNMListView->iItem!=m_item)
		{
			m_item=pNMListView->iItem;//标志被单击的项目
			// return;
		}
	}

	*pResult = 0;
}

void CEditListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMLVKEYDOWN* nmkd = (NMLVKEYDOWN*)pNMHDR;

	switch(nmkd->wVKey)
	{
	case VK_LEFT:
		m_old_subitem--;
		if(m_old_subitem<0)
			m_old_subitem=0;
		invalidate_grid(m_old_item,m_old_subitem+1);
		Invalidate();
		break;
	case VK_RIGHT:
		m_old_subitem++;
		if(m_old_subitem>GetHeaderCtrl()->GetItemCount()-1)
			m_old_subitem=GetHeaderCtrl()->GetItemCount()-1;
		invalidate_grid(m_old_item,m_old_subitem-1);
		Invalidate();
		break;

	case VK_UP:
		m_old_item--;
		if(m_old_item<0)
			m_old_item=0;
		invalidate_grid(m_old_item+1,m_old_subitem);
		break;

	case VK_DOWN:
		m_old_item++;
		if(m_old_item>GetItemCount()-1)
			m_old_item=GetItemCount()-1;
		invalidate_grid(m_old_item-1,m_old_subitem);
		break;
	case VK_PRIOR:
		invalidate_grid(m_old_item,m_old_subitem);
		m_old_item=0;
		break;
	case VK_NEXT:
		invalidate_grid(m_old_item,m_old_subitem);
		m_old_item=GetItemCount()-1;
		break;
	case VK_HOME:
		invalidate_grid(m_old_item,m_old_subitem);
		m_old_subitem=0;

		if(GetKeyState(VK_CONTROL)<0)
			m_old_item=0;

		SetItemState(m_old_item,LVIS_FOCUSED,LVIS_FOCUSED);
		*pResult = CDRF_SKIPDEFAULT;
		invalidate_grid(m_old_item,m_old_subitem);
		return;
		break;
	case VK_END:
		invalidate_grid(m_old_item,m_old_subitem);
		m_old_subitem=GetHeaderCtrl()->GetItemCount()-1;
		if(GetKeyState(VK_CONTROL)<0)
			m_old_item=GetItemCount()-1;

		SetItemState(m_old_item,LVIS_FOCUSED,LVIS_FOCUSED);

		*pResult=CDRF_SKIPDEFAULT;
		invalidate_grid(m_old_item,m_old_subitem);
		return;
	}

	*pResult = 0;
}

void CEditListCtrl::invalidate_grid(int row, int col)
{
	CRect r;

	if(col==0 || col==1 || col==3)
		GetItemRect(row,&r,LVIR_LABEL);
	else
		GetSubItemRect(row,col,LVIR_BOUNDS,r);
	m_now_item=m_old_item;
	m_now_subitem=m_old_subitem;
	InvalidateRect(&r);
}

void CEditListCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if (m_downmove)
	{
		POINT pt=point;
		UINT flags;
		//	ClientToScreen(&pt);
		//	CImageList::DragMove(pt);
		LVHITTESTINFO lvhti;
		lvhti.pt=point;
		m_now_item=HitTest(pt,&flags);
		m_now_subitem=SubItemHitTest(&lvhti);
		m_now_subitem=lvhti.iSubItem;
		Invalidate();
	}
	CListCtrl::OnMouseMove(nFlags, point);
}

void CEditListCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	m_downmove=FALSE;

	CListCtrl::OnLButtonUp(nFlags, point);
}

void CEditListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	//	invalidate_grid(m_item,m_subitem);

	m_downmove=TRUE;
	POINT pt=point;
	UINT flags;
	//	ClientToScreen(&pt);
	//	CImageList::DragMove(pt);
	m_old_item=HitTest(pt,&flags);
	LVHITTESTINFO lvhti;
	lvhti.pt=point;
	m_old_subitem=SubItemHitTest(&lvhti);
	m_old_subitem=lvhti.iSubItem;
	m_now_item=m_old_item;
	m_now_subitem=m_old_subitem;

	if(m_edit)
	{
		m_edit->DestroyWindow();
		m_edit=NULL;
	}

	//m_edit->ShowWindow(SW_HIDE);
	CListCtrl::OnLButtonDown(nFlags, point);
}
void CEditListCtrl::OnSetfocus(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: Add your control notification handler code here
	if(m_edit)
	{//将编辑框中的数据写回对应的子项目中
		UpdateData( );
		CString str;
		m_edit->GetWindowText(str);
		// MessageBox(str);
		SetItemText(m_item,m_subitem,str);
		delete m_edit;
		m_edit=NULL;
	}
	*pResult = 0;
}
void CEditListCtrl::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: Add your control notification handler code here

	Invalidate();
	*pResult = 0;
}

void CEditListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default

	//水平滚动时,移动已显示的编辑框
	CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
	LRESULT* pResult=new LRESULT;
	if(m_edit)  OnClick((NMHDR*)this,pResult) ;

}

void CEditListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default

	//垂直滚动时,移动已显示的编辑框。
	CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
	LRESULT* pResult=new LRESULT;
	if(m_edit)
	{
		RECT m_itemrect,m_headrect;
		GetItemRect(m_item ,&m_itemrect,2);
		GetHeaderCtrl()->GetWindowRect(&m_headrect);
		if(m_itemrect.top<m_headrect.bottom-m_headrect.top)
		{
			RECT m_rect;
			m_edit->GetWindowRect(&m_rect);
			m_edit->MoveWindow(m_rect.left,-(m_rect.bottom-m_rect.top),m_rect.right,0);
		}
		else
		{
			OnClick((NMHDR*)this,pResult) ;
		}
	}
}

void CEditListCtrl::SetEditColomn(int col, BOOL edit)
{
	//设置允许直接进行编辑的列
	if(!m_isedit)
	{
		int len=GetHeaderCtrl()->GetItemCount();
		m_isedit=new BOOL[len];
		for(int i=0;i<len;i++)//初始化m_isedit。
			m_isedit[i]=FALSE;
	}
	m_isedit[col]=edit;
}
void CEditListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: Add your control notification handler code here
	int i;
	if(!m_isedit) return;
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	if(!m_edit)
	{
		m_subitem=pNMListView->iSubItem;
		if(pNMListView->iItem!=m_item)
		{
			m_item=pNMListView->iItem;//标志被单击的项目
			// return;
		}
	}
	if(!m_isedit[m_subitem])//若当前列不允许直接编辑,则返回
		return;
	RECT m_itemrect,m_r;
	GetItemRect(m_item ,&m_itemrect,2);
	GetItemRect(0 ,&m_r,2);
	int m_height=m_itemrect.bottom -m_itemrect.top ;
	int x=m_r.left ,y=m_r.top,cx,cy;//(x,y,cx,cy)为编辑框显示的位置
	for(i=0;i< m_item;i++)
		y+=m_height;
	cy=y+m_height;
	for(i=0;i<m_subitem;i++)
		x+=GetColumnWidth(i);
	cx=x+GetColumnWidth(i);
	if(m_edit)//若编辑框已存在。
	{
		CString s1;
		s1.Format (_T("%d %d %d %d"),x,y,cx,cy);
		m_edit->MoveWindow(x-4,y,cx-x-4,cy-y);//移动到当前子项目的位置。
		Invalidate();//刷新屏幕。
		return;
	}
	//若编辑框不存在,则创建编辑框,并在当前子项目处显示编辑框。
	CRect rect(x-4,y,cx-4,cy);
	m_edit=new CEdit();
	m_edit->Create (WS_CHILD|WS_VISIBLE|WS_BORDER,rect,this,ID_LISTEDIT);
	SetWindowLong(m_edit->m_hWnd, GWL_STYLE,GetWindowLong(m_edit->m_hWnd, GWL_STYLE) | ES_NUMBER);//控制只允许输入数字
	CString str=GetItemText (pNMListView->iItem,pNMListView->iSubItem);
	m_edit->UpdateData(0);
	m_edit->SetWindowText(str);
	DWORD  dwSel = m_edit->GetSel();
	m_edit->SetSel(HIWORD(dwSel), -1);
	m_edit->ShowWindow (SW_SHOW);//显示编辑框。
	m_edit->SetFocus ();

	*pResult = 0;
}

BOOL CEditListCtrl::DestroyWindow()
{
	delete [] m_isedit;
	return CListCtrl::DestroyWindow();
}

void CEditListCtrl::OnClose()
{
	// TODO: Add your message handler code here and/or call default
	if(m_edit)
		delete m_edit;
	delete [] m_isedit;
	CListCtrl::OnClose();
}

ListCtrl的扩展类EditListCtrl

时间: 2024-08-30 06:30:50

ListCtrl的扩展类EditListCtrl的相关文章

ios 中Category类别(扩展类)专题总结

原创地址   http://www.code4blog.com/archives/294 类别 类别是一种为现有的类添加新方法的方式. 利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为任何类添加新的方法,包括那些没有源代码的类. 类别使得无需创建对象类的子类就能完成同样的工作 一.创建类别 1.声明类别 声明类别与声明类的形式很相似 @interface  NSString(NumberConvenienc

UI(UGUI)框架(二)-------------UIManager单例模式与开发BasePanel面板基类/UIManage统一管理UI面板的实例化/开发字典扩展类

UIManage单实例: 1 /// 单例模式的核心 2 /// 1,定义一个静态的对象 在外界访问 在内部构造 3 /// 2,构造方法私有化 4 5 private static UIManager _instance; 6 7 public static UIManager Instance 8 { 9 get 10 { 11 if (_instance == null) 12 { 13 _instance = new UIManager(); 14 } 15 return _instan

PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载 &amp;&amp; Linux下的ZipArchive配置开启压缩

PHP ZipArchive 是PHP自带的扩展类,可以轻松实现ZIP文件的压缩和解压,使用前首先要确保PHP ZIP 扩展已经开启,具体开启方法就不说了,不同的平台开启PHP扩增的方法网上都有,如有疑问欢迎交流.这里整理一下常用的示例供参考. 一.解压缩zip文件 ? 1 2 3 4 5 6 7 8 9 10 11 $zip = new ZipArchive;//新建一个ZipArchive的对象 /* 通过ZipArchive的对象处理zip文件 $zip->open这个方法的参数表示处理的

NSJSONSerialization(category)的一个扩展类

.h文件 // // NSJSONSerialization+Manage.h // SVPullToRefreshDemo // // Created by Fuer on 14-7-4. // Copyright (c) 2014年 Home. All rights reserved. // #import <Foundation/Foundation.h> /** * The domain for NSErrors generated by the NSJSONSerialization

HTML扩展类的所有方法都有2个参数:

——摘自Rocky Ren 以textbox为例子 public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, IDictionary<string, Object> htmlAttributes ) public static string TextBox( this HtmlHelper htmlHelper, string name, Object value, Object h

“XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题

“XXX.Index”不扩展类“System.Web.UI.Page”,因此此处不允许的问题 原因:设计页面继承的路径和后台.cs页面类的路径不一致造成的 看下图 这个是设计页面的样式 这个是后台cs文件代码 如果这两地方的路径不一致则会导致上述错误出现 解决方法:将这两个地方的路径统一即可解决

Thinkphp编辑器扩展类kindeditor使用方法

一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp网站项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们复制到你的网站项目的ThinkPHP\Lib\ORG\Net 文件夹下. 2,editor文件夹是kindeditor的核心包.将其复制到你项目的Public文件夹下(和入口文件同级的那个Public),并在Public下再建立一个Upload文件夹,用于存放使用编辑器上传的图片. 3,KeditorAction.clas

基于Thinkphp3.2的qq第三方oauth认证登录扩展类

基于Thinkphp3.2的qq第三方oauth认证登录扩展类,由于腾讯oauth sdk写的太多,不能与thinkphp和好的结合,最终想法讲腾讯oauth sdk写成tp的扩展类先看代码,将代码保存在/library/org/util/Qqconnect.class.php文件中在__construct方法中你可以直接写你的app_id.app_key和回调地址也可以根据自己的喜好,改一下代码传参或者写到配置文件.调用方法:1. 在qq的登录按钮的方法中调用getAuthCode方法例如:$

python学习:扩展类的方法

一:先看一段小程序 <span style="font-size:18px;"><strong>class person: def __init__(self): print "new person" self.name = "lyl" def setName(self,name): self.name = name def printName(self): print self.name p = person(); p.