您的位置:首页 > 其它

ListCtrl的扩展类EditListCtrl

2016-07-09 22:57 399 查看

该类继承自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);
}
v
7ff7
oid 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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: