VC可编辑可变颜色的列表控件CListCtrl

标签:
可编辑可变颜色列表控件clistctrl |
分类: 代码天地 |
列表控件CListCtrl 使用很广泛,但自身无法编辑单元格的内容,无法改变前景和背景颜色。
通过加入相关的函数,借助编辑框输入文本,组合框选择项目等来实现文本编辑。
代码大部分来自网络,为了使用灵活使用,加入适当的代码,或者适当的改变。
比如:列的类型数组,列的组合框项目数组等。
修改的部分都使用红色标注。
主要 代码 如下 :
一 类头文件(3个类放到一个头文件内
) EditListCtrl.h
#if
!defined(AFX_EDITLISTCTRL_H__129EB9CC_D1CA_488B_A9E5_44793533DC86__INCLUDED_)
#define
AFX_EDITLISTCTRL_H__129EB9CC_D1CA_488B_A9E5_44793533DC86__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditListCtrl.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// EditListCtrl window
//1 CListCtrlEdit
class CListCtrlEdit : public CEdit
{
DECLARE_DYNAMIC(CListCtrlEdit)
public:
CListCtrlEdit();
virtual ~CListCtrlEdit();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKillFocus(CWnd* pNewWnd);
};
//2 CListCtrlCombo
class CListCtrlCombo : public CComboBox
{
DECLARE_DYNAMIC(CListCtrlCombo)
public:
CListCtrlCombo();
virtual ~CListCtrlCombo();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKillFocus(CWnd* pNewWnd);
};
//3 CEditableListCtrl
class CEditListCtrl : public CListCtrl
{
DECLARE_DYNAMIC(CEditListCtrl)
enum
{listCtrl_LABEL=0,listCtrl_EDIT=1,listCtrl_COMBO=2,listCtrl_STATIC=3};
public:
CEditListCtrl();
virtual ~CEditListCtrl();
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnHdnBegintrack(NMHDR *pNMHDR, LRESULT
*pResult);
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*
pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*
pScrollBar);
void ShowEdit(bool bShow, int nItem, int nSubItem, CRect
rcCtrl);
void ShowCombo(bool bShow, int nItem, int nSubItem, CRect
rcCtrl);
afx_msg LRESULT OnEditEnd(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnComboEnd(WPARAM wParam,LPARAM lParam);
private:
CListCtrlEdit m_edit;
CListCtrlCombo m_combo;
int nItem;
// 当前点击项
int nSubItem;
// 当前点击子项
bool m_bEditVisible; //
Edit是否可见
bool m_bComboVisible; //
ComboBox是否可见
//-----------------新增部分----------------------
public:
void column_type(int
nColumn=0);//初始化各列的类型
void column_string(int
nColumn=0);//初始化各列的选择数目项,主要针对组合框
void OnCustomdrawMyList ( NMHDR* pNMHDR, LRESULT* pResult )
;//1 自绘函数改变颜色声明
public:
int m_column_num;//列的个数
int *m_column_type;//列的类型, 区分是编辑框,组合框,还是普通的文本框
CString *m_column_string;//各个列的组合框的项目字符数足
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations
immediately before the previous line.
#endif //
!defined(AFX_EDITLISTCTRL_H__129EB9CC_D1CA_488B_A9E5_44793533DC86__INCLUDED_)
二 类 的实现文件(3个类放到一个实现文件内
) EditListCtrl.cpp
// EditListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "editList.h"
#include "EditListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//1
//#include "ListCtrlEdit.h"
#define WM_USER_EDIT_END WM_USER+101
// CListCtrlEdit
IMPLEMENT_DYNAMIC(CListCtrlEdit, CEdit)
CListCtrlEdit::CListCtrlEdit()
{
}
CListCtrlEdit::~CListCtrlEdit()
{
}
BEGIN_MESSAGE_MAP(CListCtrlEdit, CEdit)
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
// CListCtrlEdit message handlers
void CListCtrlEdit::OnKillFocus(CWnd* pNewWnd)
{
CEdit::OnKillFocus(pNewWnd);
// TODO: Add your message handler code here
CWnd *pParent = this->GetParent();
::PostMessage(pParent->GetSafeHwnd(), WM_USER_EDIT_END, 0,
0);
}
//2
//#include "ListCtrlCombo.h"
#define WM_USER_COMBO_END WM_USER+102
// CListCtrlCombo
IMPLEMENT_DYNAMIC(CListCtrlCombo, CComboBox)
CListCtrlCombo::CListCtrlCombo()
{
}
CListCtrlCombo::~CListCtrlCombo()
{
}
BEGIN_MESSAGE_MAP(CListCtrlCombo, CComboBox)
ON_WM_KILLFOCUS()
END_MESSAGE_MAP()
// CListCtrlCombo message handlers
void CListCtrlCombo::OnKillFocus(CWnd* pNewWnd)
{
CComboBox::OnKillFocus(pNewWnd);
// TODO: Add your message handler code here
CWnd *pParent = this->GetParent();
::PostMessage(pParent->GetSafeHwnd(), WM_USER_COMBO_END, 0,
0);
}
//3
//#include "EditableListCtrl.h"
#define WM_USER_EDIT_END WM_USER+101
#define WM_USER_COMBO_END WM_USER+102
// CEditListCtrl
IMPLEMENT_DYNAMIC(CEditListCtrl, CListCtrl)
CEditListCtrl::CEditListCtrl()
: m_bEditVisible(false), m_bComboVisible(false), nItem(-1),
nSubItem(-1)
{
m_column_string=NULL;
m_column_type=NULL;
}
CEditListCtrl::~CEditListCtrl()
{
if (m_column_type) delete
[]m_column_type;
for (int i=0;i
< m_column_num
;i++)
{
//if (m_column_string[i])
{
m_column_string[i]="";//.ReleaseBuffer();
// delete
[]m_column_string[i];
// m_column_string[i]=NULL;
}
//delete m_column_string;
}
m_column_string=NULL;
}
void CEditListCtrl::column_type(int
nColumn)//
{
if (nColumn==0)
{
nColumn=CEditListCtrl::GetHeaderCtrl()->GetItemCount();
}
m_column_num=nColumn;//列的个数
if (m_column_type) delete
[]m_column_type;
m_column_type=new int
[m_column_num];//列类型数组的声明
for (int i=0;i < m_column_num ;i++)
{
m_column_type[i]=0;
}
}
void CEditListCtrl::column_string(int
nColumn)//
{
if (nColumn==0)
{
nColumn=CEditListCtrl::GetHeaderCtrl()->GetItemCount();
}
m_column_num=nColumn;//列的个数
if (m_column_string)
{
for (int i=0;i < m_column_num ;i++)
{
// if (m_column_string[i])
{
m_column_string[i]="";
// delete
[]m_column_string[i];
// m_column_string[i]=NULL;
}
}
delete m_column_string;
m_column_string=NULL;
}
m_column_string=new CString
[m_column_num];
for (int i=0;i < m_column_num ;i++)
{
m_column_string[i]="";
}
}
void CEditListCtrl::ShowEdit(bool bShow, int nItem, int
nSubItem, CRect rcCtrl)
{
CRect(0,0,0,0), this, 1001);
}
void CEditListCtrl::ShowCombo(bool bShow, int nItem, int
nSubItem, CRect rcCtrl)
{
m_bComboVisible = bShow;
if (m_combo.m_hWnd == NULL)
{
m_combo.Create(ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_CHILD |
ES_LEFT | CBS_DROPDOWNLIST,
CRect(0,0,0,0), this, 1002);
m_combo.ShowWindow(SW_HIDE);
CFont tpFont;
tpFont.CreateStockObject(DEFAULT_GUI_FONT);
m_combo.SetFont(&tpFont);
tpFont.DeleteObject();
// m_combo.AddString(TEXT("Male"));
// m_combo.AddString(TEXT("Female"));
}
if (bShow == TRUE)
{
//1 根据本列实际的项目m_column_string[nSubItem],
来动态填充 组合框
CString
str1="",str2="",str3="";
int nPos=0;
str3="\n";//按换行符拆分,这样确保内容可以是各种字符
str1=m_column_string[nSubItem];
str1.TrimLeft();str1.TrimRight();
if
(str1!="")//!str1.IsEmpty())
{
nPos=str1.FindOneOf(str3);
while(nPos>=0)
{
str2=str1.Mid(0,nPos);
m_combo.AddString(str2);
str1=str1.Mid(nPos+1);
nPos=str1.FindOneOf(str3);
}
if (str1!="")
{str2=str1;m_combo.AddString(str2);}
}
m_combo.SetCurSel(-1);
CString cstrItem = GetItemText(nItem, nSubItem);
//2
根据组合框的(条目数+1),编辑区域占据一个所以+1,
来设置组合框的下拉大小
//
m_combo.MoveWindow(&rcCtrl);
CRect rect;
m_combo.GetDroppedControlRect(&rect
);
int
nn=m_combo.GetCount(),hh=rcCtrl.Height();
rect.SetRect(rcCtrl.left,rcCtrl.top ,
rcCtrl.right,rcCtrl.top+(nn+1)*hh);
m_combo.MoveWindow(&rect);
m_combo.ShowWindow(SW_SHOW);
m_combo.SetWindowText(cstrItem);
m_combo.SetFocus();
int nItems = m_combo.GetCount();
for (int i=0; i < nItems ; ++i)
{
CString cstrItemText;
m_combo.GetLBText(i, cstrItemText);
if (cstrItem == cstrItemText)
{
m_combo.SetCurSel(i);
break;
}
}
}
else
{//隐含时 清理组合框, 再次显示时, 根据实际的列
,动态填充
m_combo.ResetContent();//清理
m_combo.ShowWindow(SW_HIDE);
}
}
BEGIN_MESSAGE_MAP(CEditListCtrl, CListCtrl)
ON_WM_LBUTTONDBLCLK()
ON_NOTIFY(HDN_BEGINTRACKA, 0,
CEditListCtrl::OnHdnBegintrack)
ON_NOTIFY(HDN_BEGINTRACKW, 0,
CEditListCtrl::OnHdnBegintrack)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_MESSAGE(WM_USER_EDIT_END, OnEditEnd)
ON_MESSAGE(WM_USER_COMBO_END, OnComboEnd)
// ON_NOTIFY ( NM_CUSTOMDRAW,IDC_LIST, OnCustomdrawMyList )
//2 手工加入消息影射
END_MESSAGE_MAP()
// CEditListCtrl message handlers
////3
手工添加本函数,设置ListCtrl某行某列单元格的前景,背景颜色
void CEditListCtrl::OnCustomdrawMyList (
NMHDR* pNMHDR, LRESULT* pResult )
{
COLORREF
m_clrText,m_clrTextBk;//前景色,背景色
int nRow,nCol;//行 , 列
nRow = static_cast
(pLVCD->nmcd.dwItemSpec);
nCol=pLVCD->iSubItem;
// 获取ListCtrl当前单元格的文本
CString str = GetItemText(nRow
,nCol);//m_list.
m_clrText = pLVCD->clrText
;//设置前景文本色
m_clrTextBk =
pLVCD->clrTextBk;//设置背景色
if
(m_column_type[nCol]==3)//可变背景列
{
m_clrTextBk=(DWORD)atoi(str);
}
pLVCD->clrText =
m_clrText;//设置前景文本色
pLVCD->clrTextBk=m_clrTextBk;//设置背景色
*pResult = CDRF_DODEFAULT;
}
LRESULT CEditListCtrl::OnEditEnd(WPARAM wParam, LPARAM
lParam)
{
CString strText;
ShowEdit(false, -1, -1, CRect());
}
LRESULT CEditListCtrl::OnComboEnd(WPARAM wParam, LPARAM
lParam)
{
int nSel = m_combo.GetCurSel();
CString cstrTextSel;
m_combo.GetLBText(nSel, cstrTextSel);
ShowCombo(false, -1, -1, CRect());
}
void CEditListCtrl::OnLButtonDblClk(UINT nFlags, CPoint
point)
{
// TODO: Add your message handler code here and/or call
default
CRect rcCtrl;
LVHITTESTINFO lvhti;
lvhti.pt = point;
nItem = SubItemHitTest(&lvhti);
if (nItem == -1)
return;
nSubItem = lvhti.iSubItem;
GetSubItemRect(nItem, nSubItem, LVIR_LABEL, rcCtrl);
//查看列的类型
switch( m_column_type[lvhti.iSubItem])
{
case 0://listCtrl_LABEL
break;
case 1://listCtrl_EDIT
ShowEdit(TRUE, nItem, nSubItem, rcCtrl);
break;
case 2://listCtrl_COMBO
ShowCombo(TRUE, nItem, nSubItem, rcCtrl);
break;
case 3://listCtrl_STATIC
{
CString str = GetItemText(nItem
,nSubItem);
COLORREF
clr=atol(str);//RGB(255,0,0);
CColorDialog
dlg;
dlg.m_cc.lpCustColors=&clr;//原来颜色
if (IDOK==dlg.DoModal())
{
clr=dlg.GetColor();//新选择的颜色
str.Format("%ld",clr);
SetItemText(nItem
,nSubItem,str);//颜色数值设置为单元格的文本
this->Invalidate();//刷新列表
}
}
break;
default:
break;
}
CListCtrl::OnLButtonDblClk(nFlags, point);
}
void CEditListCtrl::OnHdnBegintrack(NMHDR *pNMHDR, LRESULT
*pResult)
{
LPNMHEADER phdr = reinterpret_cast(pNMHDR);
// TODO: Add your control notification handler code here
if (m_edit.m_hWnd != NULL && m_bEditVisible)
OnEditEnd(0, 0);
if (m_combo.m_hWnd != NULL && m_bComboVisible)
OnComboEnd(0, 0);
*pResult = 0;
}
void CEditListCtrl::OnHScroll(UINT nSBCode, UINT nPos,
CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call
default
if (m_edit.m_hWnd != NULL && m_bEditVisible)
OnEditEnd(0, 0);
if (m_combo.m_hWnd != NULL && m_bComboVisible)
OnComboEnd(0, 0);
CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CEditListCtrl::OnVScroll(UINT nSBCode, UINT nPos,
CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call
default
if (m_edit.m_hWnd != NULL && m_bEditVisible)
OnEditEnd(0, 0);
if (m_combo.m_hWnd != NULL && m_bComboVisible)
OnComboEnd(0, 0);
CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
三
对话框头文件中的代码
// editListDlg.h : header file
//
#if
!defined(AFX_EDITLISTDLG_H__6617E8B1_8F6A_4959_AAAA_D66822A926A5__INCLUDED_)
#define
AFX_EDITLISTDLG_H__6617E8B1_8F6A_4959_AAAA_D66822A926A5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "EditListCtrl.h"
/////////////////////////////////////////////////////////////////////////////
// CEditListDlg dialog
class CEditListDlg : public CDialog
{
// Construction
public:
CEditListDlg(CWnd* pParent = NULL); // standard
constructor
// Dialog Data
//{{AFX_DATA(CEditListDlg)
enum { IDD = IDD_EDITLIST_DIALOG };
CEditListCtrl m_listCtrl;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditListDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
support
//}}AFX_VIRTUAL
void OnCustomdrawMyList ( NMHDR* pNMHDR,
LRESULT* pResult ) ;//1
手工加入自绘函数声明
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CEditListDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations
immediately before the previous line.
#endif //
!defined(AFX_EDITLISTDLG_H__6617E8B1_8F6A_4959_AAAA_D66822A926A5__INCLUDED_)
四
对话框实现文件的主要代码
void CEditListDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CEditListDlg)
DDX_Control(pDX, IDC_LIST1,
m_listCtrl);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CEditListDlg, CDialog)
//{{AFX_MSG_MAP(CEditListDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY ( NM_CUSTOMDRAW,IDC_LIST1,
OnCustomdrawMyList ) //2 手工加入消息影射
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditListDlg message handlers
BOOL CEditListDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Style
DWORD dwStyle = ::GetWindowLong(m_listCtrl.GetSafeHwnd(),
GWL_STYLE);
dwStyle |= LVS_SINGLESEL;
//只可单行选中
dwStyle |= LVS_SHOWSELALWAYS; //Always show
selection
::SetWindowLong(m_listCtrl.GetSafeHwnd(), GWL_STYLE,
dwStyle);
// Extended Style
DWORD dwStyleEx = m_listCtrl.GetExtendedStyle();
dwStyleEx |= LVS_EX_GRIDLINES;
//网格线
dwStyleEx |= LVS_EX_FULLROWSELECT;
//整行高亮
dwStyleEx |= LVS_EX_CHECKBOXES;
//Item前生成check box
m_listCtrl.SetExtendedStyle(dwStyleEx);
// 插入列
m_listCtrl.InsertColumn(0, TEXT("姓名"), LVCFMT_LEFT,
100);
m_listCtrl.InsertColumn(1, TEXT("年龄"), LVCFMT_LEFT, 60);
m_listCtrl.InsertColumn(2, TEXT("性别"), LVCFMT_LEFT, 80);
m_listCtrl.InsertColumn(3, TEXT("上衣颜色"), LVCFMT_LEFT,
80);
//
int nItem = 0;
nItem = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(),
TEXT("张扬"), 0);
m_listCtrl.SetItemText(nItem, 1, TEXT("26"));
//子项从1开始,0代表主项
m_listCtrl.SetItemText(nItem, 2, TEXT("男"));
m_listCtrl.SetItemText(nItem, 3, TEXT("255"));//255 数值
代表背景的颜色值
nItem = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(),
TEXT("王艳"), 0);
m_listCtrl.SetItemText(nItem, 1, TEXT("24"));
m_listCtrl.SetItemText(nItem, 2, TEXT("女"));
m_listCtrl.SetItemText(nItem, 3,
TEXT("65280"));//255*256 数值 代表背景的颜色值
nItem = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(),
TEXT("李娜"), 0);
m_listCtrl.SetItemText(nItem, 1, TEXT("24"));
m_listCtrl.SetItemText(nItem, 2, TEXT("女"));
m_listCtrl.SetItemText(nItem, 3,
TEXT("65535"));//255+255*256 数值 代表背景的颜色值
//这些语句最好放到初始化的最后,至少要放到插入完列以后,否则需要传递列数
m_listCtrl.column_type();//获得列数,并初始化
各列的默认类型,不同的类型见下面的赋值语句
m_listCtrl.m_column_type[1]=1;//第2列编辑框
m_listCtrl.m_column_type[2]=2;//第3列组合框
m_listCtrl.m_column_type[3]=3;//第4列背景变色框,文本的数值为背景的颜色数值
m_listCtrl.column_string();//初始化各列的项目内容,
组合框列的项目要单独赋值,见下面语句
m_listCtrl.m_column_string[2]="男\n女\n";//第3列为性别,组合框的内容以换行符分割
return TRUE; // return TRUE
unless you set the focus to a control
}
void CEditListDlg::OnCustomdrawMyList ( NMHDR* pNMHDR,
LRESULT* pResult )
{
m_listCtrl.OnCustomdrawMyList (
pNMHDR, pResult )
;//调用控件类函数改变颜色
}
五
运行效果
前一篇:CToolBar的使用介绍[转]
后一篇:喜迎2018