CListCtrl自绘表格,2.程序运行界面(4个),4.源程序(8个 = 4个H + 4个CPP),资源文件(2个 = 1个H + 1个RC)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_40554560/article/details/100062382

CListCtrl自绘表格

1.程序开发环境
WIN7 32 Bits + VS 2013,经本机初步测试无错,无内存泄露。
关键字:CListCtrl自绘, 自绘程序示例, 鼠标动作, 绘图闪烁, 表格编辑, 剪贴板操作, Uncode编码, 鼠标位置Item, Item高度和宽度
2.程序运行界面(4个
程序初始界面(1)
在这里插入图片描述
选择文字界面(2)
在这里插入图片描述
编辑文字界面(3)
在这里插入图片描述
操作操作界面(4)
在这里插入图片描述
3.程序主要功能(14条)
(1)高度可调,包括表头和表体
(2)背景颜色可调,包括表头和表体
(3)文字对齐方式可调,包括表头和表体
(4)文字颜色可调,包括表头和表体
(5)支持图形文件和自绘方式,包括表头和表体
(6)奇偶行背景颜色不同
(7)每列背景颜色可不同
(8)表格内容可以编辑
(9)可以选择表格内的一个区域
(10)可以删除多行
(11)可以清除选择区域内的文字
(12)可以复制选择区域内的文字
(13)可以插入粘贴文字
(14)自动判断粘贴文字时,是否需要插入新行
4.源程序(8个 = 4个H + 4个CPP)
(1)CListCtrlUser.h
// this is file CListCtrlUser.h
#pragma once

#include “HeaderCtrlUser.h”
#include “afxcmn.h”

// CListCtrlUser

class CListCtrlUser : public CListCtrl
{
DECLARE_DYNAMIC(CListCtrlUser)

public:
CListCtrlUser();
virtual ~CListCtrlUser();

protected:
int m_fontHeight; // 字体高度
int m_fontWith; // 字体宽度
int m_nRowHeight ; // 行高

CPtrList m_ptrListCol;			//保存列颜色
CPtrList m_ptrListItem;			//保存Item颜色表
CPtrList m_colTextColor;		//保存列字体颜色
CPtrList m_ItemTextColor;		//保存单元格字体颜色

COLORREF m_color;

protected:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) ;
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) ;
virtual void PreSubclassWindow();

virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) ;

public:
CString *m_pStatic;
CHeaderCtrlUser m_Header; //如果换成动态创建,调试到此处,会发现pHeader一值为NULL,原因是,此时窗口还没创建。

void SetRowHeigt(int nHeight);
void WindowPosChanged();

void SetHeaderHeight(float Height);							//设置表头高度
void SetHeaderBKColor(int R, int G, int B, int Gradient);	// Gradient - 渐变系数,立体背景用,不用渐变设为0   
void SetHeaderFontHW(int nHeight, int nWith);				//设置表头字体大小   
void SetHeaderTextColor(COLORREF color);					//设置表头字体颜色
void Refresh( )	;

void SetItemSelectedStatus(int nItem, int nSubItem);
void SetSingleItemStatus(int nItem, int nSubItem);

CEdit *pEdit ;
void EditItemStart(int nItem, int nSubItem, CString strContent )	;
void EditItemEnd( )	;

bool	bDrawMode, bDrawAble;		// 自绘方式/普通方式
int		nRow, nColumn ;			// 整列变色显示
int		nRowEdit, nColEdit ;	// 正在编辑的单元,不能它用

int	nStartRowSelected, nStartColSelected, nEndRowSelected, nEndColSelected;

protected:
//{{AFX_MSG(CListCtrlUser)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnCopyFromList();
afx_msg void OnPasteToList();
afx_msg void OnDelFromList();
afx_msg void OnListctrlInsert();
afx_msg void OnMenuDelRow();
};

(2)ListCtrlUser.cpp
// ListCtrlUser.cpp : 实现文件//

#include “stdafx.h”
#include “test1.h”
#include “ListCtrlUser.h”
#include “HeaderCtrlUser.h”
#include “CommFunction.h”

// CListCtrlUser

IMPLEMENT_DYNAMIC(CListCtrlUser, CListCtrl)

CListCtrlUser::CListCtrlUser()
{
bDrawMode = false ;
bDrawAble = false;
m_nRowHeight = 40; // 行高
nColumn = -1 ; // 整列变色显示

pEdit = new CEdit();
nRowEdit = -1 ;				// using for editting item
nColEdit = -1 ;				// using for editting item

nStartRowSelected = nStartColSelected = nEndRowSelected = nEndColSelected = -1;

}

CListCtrlUser::~CListCtrlUser()
{
delete pEdit;
}

BEGIN_MESSAGE_MAP(CListCtrlUser, CListCtrl)
//{{AFX_MSG_MAP(CListCtrlUser)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
ON_WM_WINDOWPOSCHANGED()
ON_WM_MEASUREITEM_REFLECT()
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
//}}AFX_MSG_MAP
ON_WM_RBUTTONDOWN()
ON_COMMAND(ID_COPY_LIST, &CListCtrlUser::OnCopyFromList)
ON_COMMAND(ID_PASTE_LIST, &CListCtrlUser::OnPasteToList)
ON_COMMAND(ID_DEL_LIST, &CListCtrlUser::OnDelFromList)
ON_COMMAND(ID_LISTCTRL_INSERT, &CListCtrlUser::OnListctrlInsert)
ON_COMMAND(ID_Menu_DelRow, &CListCtrlUser::OnMenuDelRow)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

void CListCtrlUser::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
//return;
//AfxMessageBox(_T(“OnNMCustomdraw”));

//LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
LPNMLVCUSTOMDRAW	p = reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);

// 仅仅在非自绘方式下, 颜色更改有效
if (p->nmcd.dwDrawStage == CDDS_PREPAINT)
{
	*pResult = CDRF_NOTIFYITEMDRAW ;		// 必选设置
	return ;
}
	
int nCurItemIndex = p->nmcd.dwItemSpec;
if (nCurItemIndex % 2 == 0)
{
	//偶数行			
	p->clrTextBk = RGB(150, 150, 0);
	p->clrText = RGB(255, 255, 255);
}
else
{
	//奇数行 			
	p->clrTextBk = RGB(0,122, 0);
	p->clrText = RGB(255, 0, 0);
}

if (p->nmcd.uItemState == CDIS_SELECTED)
{
	//选中行			
	p->clrTextBk = RGB(0, 233, 0);			
	p->clrText = RGB(0,0,255);			
	::SetTextColor(p->nmcd.hdc,RGB(0,0,0));		
}

//*pResult = 0 ;
*pResult = CDRF_NEWFONT;		// 此返回代码无效

}

void CListCtrlUser::WindowPosChanged()
{
CRect rcwin;
WINDOWPOS wp;

GetWindowRect(rcwin);

wp.hwnd = m_hWnd;
wp.cx = rcwin.Width();
wp.cy = rcwin.Height();
wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;

//PostMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);	// 无效,Why ?
SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);

}

void CListCtrlUser::PreSubclassWindow()
{
ModifyStyle(0, LVS_OWNERDRAWFIXED); // 设置自绘方式

//AfxMessageBox(_T("PreSubclassWindow"));
//return;

CListCtrl::PreSubclassWindow();

}

//如何设置列背景色? 如何增加图标显示?
void CListCtrlUser::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//return ;
//AfxMessageBox(_T(“DrawItem”));

CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

LV_ITEM lvi = { 0 };
lvi.mask = LVIF_STATE | LVIF_TEXT ;		// |LVIF_IMAGE;    | LVIF_IMAGE | LVIF_STATE
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
lvi.iItem = lpDrawItemStruct->itemID;			// 行iItem, 列iSubItem

GetItem(&lvi);
//lvi.stateMask = 0;			// 显示不同的图片
//lvi.iImage = 00;

//高亮显示	
BOOL bHighlight = ((lvi.state & LVIS_DROPHILITED) || ((lvi.state & LVIS_SELECTED)
	&& ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS)))); 

//画文本背景 
CRect rcBack = lpDrawItemStruct->rcItem;
pDC->SetBkMode(TRANSPARENT);
if (bHighlight) //如果被选中
{
	//pDC->SetTextColor(RGB(255, 0, 0));            //文本颜色
	pDC->FillRect(rcBack, &CBrush(RGB(200, 200, 200)));//行背景色
}

//绘制文本
if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
{
	//循环处理
	CString szText;
	//得到列数
	int nCollumn = GetHeaderCtrl()->GetItemCount();
	for (int i = 0; i < GetHeaderCtrl()->GetItemCount(); i++)
	{
		CRect rcItem;
		if (!GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem))
			continue;

		CRect tempRect(rcItem);

		if (!bHighlight)
		{
			if (lvi.iItem %2 == 0)
				pDC->FillRect(rcItem, &CBrush(RGB(110, 180, 111))); //item景色
			else
				pDC->FillRect(rcItem, &CBrush(RGB(180, 101, 101))); //item景色
			if (i == 0 || i == 6)
			{
				rcItem.left -= 2;
				pDC->FillRect(rcItem, &CBrush(RGB(255, 255, 255))); //item景色
				rcItem.left += 2;
			}
		}
		szText = GetItemText(lpDrawItemStruct->itemID, i);
		rcItem.left += 5; rcItem.right -= 1;

		CFont nFont, *nOldFont;
		nFont.CreateFont(16, 0, 0, 0, 0, FALSE, FALSE, 0, 0, 0, 0, 0, 0, _TEXT("宋体"));		//创建字体 
		nOldFont = pDC->SelectObject(&nFont);
		
		if ( 0 == i )
		{
			pDC->FillRect(&tempRect, &CBrush(RGB(188, 188, 111)));
		}

		if (i == 5)
		{
			CRgn rgn;
			CBrush brush;
			if (szText == _T("R") )
				brush.CreateSolidBrush(RGB(255,0,0));
			if (szText == _T("G") )
				brush.CreateSolidBrush(RGB(0, 255,0));
			if (szText == _T("B") )
				brush.CreateSolidBrush(RGB(0, 0,255));
			if (szText == _T("Y") )
				brush.CreateSolidBrush( RGB(110, 110, 110));

			rgn.CreateEllipticRgn(tempRect.left + 8, tempRect.top + 4, tempRect.right - 8, tempRect.bottom - 4 );
			pDC->FillRgn(&rgn, &brush);
		}
		else
		if (i == 6)
		{
			CRgn rgn;
			CBrush brush;
			CString		strColor, strData ;

			strColor = GetItemText(lvi.iItem, 5);
			strData = GetItemText(lvi.iItem, 4);

			if (strColor == _T("R") )
				brush.CreateSolidBrush(RGB(255,0,0));
			if (strColor == _T("G") )
				brush.CreateSolidBrush(RGB(0, 255,0));
			if (strColor == _T("B") )
				brush.CreateSolidBrush(RGB(0, 0,255));
			if (strColor == _T("Y") )
				brush.CreateSolidBrush( RGB(110, 110, 110));

			int		scale = (int)((float)(_wtof(strData)/100.0f) * (float)tempRect.Width()) ;  
			rgn.CreateRectRgn( tempRect.left + 4, tempRect.top + 4, tempRect.left + 4 + scale, tempRect.bottom -4 );
			pDC->FillRgn(&rgn, &brush);
			brush.DeleteObject();		//释放   
			rgn.DeleteObject();			//释放
		}
		else
		{	
			UINT	nFormt = DT_VCENTER | DT_LEFT | DT_NOPREFIX | DT_SINGLELINE ;
			if (i == 0 || i == 2)
				nFormt =  DT_VCENTER | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE ;
			
			if (nColumn == i)
				pDC->FillRect(&tempRect, &CBrush(RGB(122, 111, 122)));

			tempRect.left += 4 ;
			//pDC->SetTextColor(RGB(0, 0, 0));                  //文本颜色
			pDC->DrawText(szText, lstrlen(szText), &tempRect,	// 第一列如果无法居中显示 则原因可能是有图标显示 
				nFormt );			// DT_CENTER | DT_LEFT |
		}

		pDC->SelectStockObject(SYSTEM_FONT);
	}
}

}

void CListCtrlUser::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
//AfxMessageBox(_T(“MeasureItem”));
if (m_nRowHeight>0) {
lpMeasureItemStruct->itemHeight = m_nRowHeight;
}
}

void CListCtrlUser::SetRowHeigt(int nHeight)
{
//AfxMessageBox(_T(“SetRowHeigt”));
m_nRowHeight = nHeight;
}

// Gradient - 渐变系数,立体背景用,不用渐变设为0
void CListCtrlUser::SetHeaderBKColor(int R, int G, int B, int Gradient)
{
m_Header.m_R = R;
m_Header.m_G = G;
m_Header.m_B = B;
m_Header.m_Gradient = Gradient;
}

//设置表头字体大小 void SetHeaderTextColor(COLORREF color);
void CListCtrlUser::SetHeaderFontHW(int nHeight, int nWith)
{
m_Header.m_fontHeight = nHeight;
m_Header.m_fontWith = nWith;
}

//设置头部字体颜色
void CListCtrlUser::SetHeaderTextColor(COLORREF color)
{
m_Header.m_color = color;
}

void CListCtrlUser::SetHeaderHeight(float Height) //设置表头高度
{
m_Header.m_Height = Height;
}

void CListCtrlUser::Refresh( ) //设置表头高度
{
//AfxMessageBox(_T(“Refresh( )”));

CHeaderCtrl *pHeader = GetHeaderCtrl();
if (!m_Header && pHeader)
{
	m_Header.SubclassWindow(pHeader->GetSafeHwnd());	//
	m_Header.m_pStatic = m_pStatic ;
}
WindowPosChanged();		// 在自绘方式下强制更改

Invalidate() ;

}

// 改变宽度,会出现文字重叠, 故需要在这里处理
BOOL CListCtrlUser::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
//AfxMessageBox(_T(“OnNotify( )”));
HD_NOTIFY pHDNotify = (HD_NOTIFY)lParam;

switch( pHDNotify->hdr.code ) 
{
case HDN_ITEMCHANGINGA:
case HDN_ITEMCHANGINGW:
case HDN_ENDTRACK:
	{			
		Invalidate() ;	
		break;
	}
} 
return CListCtrl::OnNotify(wParam,lParam,pResult);

}

void CListCtrlUser::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
{
//AfxMessageBox(_T(“VOnColumnclick”));
//return ;
EditItemEnd() ;

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

HDITEM hdi;
CString  lpBuffer;

hdi.mask = HDI_TEXT;
hdi.pszText =  lpBuffer.GetBuffer(256)  ;
hdi.cchTextMax = 256;

GetHeaderCtrl()->GetItem(pNMListView->iSubItem, &hdi);	// 列名

CString 	str ;	
str.Format(_T("当前第 %d 列:%s"), pNMListView->iSubItem,  hdi.pszText ) ;  
*m_pStatic = str ;
(CWnd*)GetParent()->UpdateData(FALSE) ;

if (pNMListView->iSubItem < 5)
	nColumn = pNMListView->iSubItem ;
else
	nColumn = -1 ;

//Invalidate() ;	
*pResult = 0;

}

void CListCtrlUser::EditItemStart(int nItem, int nSubItem, CString strContent )
{
EditItemEnd() ;
if (nSubItem > 4)
return ;

CRect rect;
if (!GetSubItemRect(nItem, nSubItem, LVIR_LABEL, rect))
	return ;

pEdit->Create( WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER|WS_EX_TOOLWINDOW, rect, this, 1);
pEdit->ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_DRAWFRAME);

pEdit->SetSel( 0, -1, true );    //全选
pEdit->ReplaceSel( strContent );        //替换
pEdit->SetSel(0);                //设置插入点为起始位置

nRowEdit = nItem ;
nColEdit = nSubItem ;

}

void CListCtrlUser::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
//AfxMessageBox(_T(“OnDblclk”));
//return ;
EditItemEnd() ;

NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

CString  lpBuffer = GetItemText(pNMListView->iItem, pNMListView->iSubItem );;

CString s ;
s.Format(_T("当前第 %d  %d 列:%s"), pNMListView->iItem, pNMListView->iSubItem, lpBuffer) ;
//AfxMessageBox( s );

EditItemStart(pNMListView->iItem, pNMListView->iSubItem, lpBuffer ) ;

*pResult = 0;

}

void CListCtrlUser::EditItemEnd( )
{
if (!(nRowEdit >= 0 && nColEdit >= 0))
return ;

CString text = _T("");
pEdit->GetWindowText( text );		//获取控件文本

SetItemText(nRowEdit, nColEdit, text); 
pEdit->DestroyWindow();

nRowEdit = -1 ;
nColEdit = -1 ;

}

void CListCtrlUser::OnMouseMove(UINT nFlags, CPoint point0)
{
if (!GetAsyncKeyState(VK_LBUTTON))
return;

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

ScreenToClient(&point);

LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;

int nItem, nSubItem;

nItem = SubItemHitTest(&lvinfo);
if (nItem != -1)
{
	nItem = lvinfo.iItem;
	nSubItem = lvinfo.iSubItem;
	
	SetItemSelectedStatus( nItem, nSubItem);

	CString		str;
	str.Format(_T("当前行, 列:(%d, %d) = %s"), nItem, nSubItem, GetItemText(nItem, nSubItem) );
	nEndRowSelected = nItem, nEndColSelected = nSubItem;
	*m_pStatic = str;
	(CWnd*)GetParent()->UpdateData(FALSE);
}

CListCtrl::OnMouseMove(nFlags, point);

}

void CListCtrlUser::OnLButtonUp(UINT nFlags, CPoint point)
{
int min = min(nStartRowSelected, nEndRowSelected);
int max = max(nStartRowSelected, nEndRowSelected);
nStartRowSelected = min, nEndRowSelected = max;
min = min(nStartColSelected, nEndColSelected);
max = max(nStartColSelected, nEndColSelected);
nStartColSelected = min, nEndColSelected = max;

CRect	rect, rectEnd;
GetItemRect(nStartRowSelected, &rect, LVIR_BOUNDS);		// 得到选择行位置
GetItemRect(nEndRowSelected, &rectEnd, LVIR_BOUNDS);	// 得到选择行位置

int i = 0;
for (i = 0; i < nStartColSelected; i++)				// 计算选择行 item 的rect
	rect.left += GetColumnWidth(i);
rect.right = rect.left + GetColumnWidth(i);

for (i = 0; i < nEndColSelected; i++)				// 计算选择行 item 的rect
	rectEnd.left += GetColumnWidth(i);
rectEnd.right = rectEnd.left + GetColumnWidth(i);

rect.right = rectEnd.right, rect.bottom = rectEnd.bottom;	// 选择区域

CPen pen;
CClientDC	dc(this);

pen.CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));//创建一个透明的画刷
CPen *pOldPen = dc.SelectObject(&pen);			//选择画刷
CBrush *pOldBrush = dc.SelectObject(pBrush);	//选择画刷

dc.SetBkMode(TRANSPARENT);
dc.Rectangle(&rect);							// 画透明色矩形框

dc.SelectObject(pOldPen);		//恢复以前的画笔
dc.SelectObject(pOldBrush);		//恢复以前的画刷
pen.DeleteObject();
pBrush->DeleteObject();

CListCtrl::OnLButtonUp(nFlags, point);

}

// 获得行,列号
void CListCtrlUser::OnLButtonDown(UINT nFlags, CPoint point0)
{
//AfxMessageBox(_T(“OnLButtonDown”));
//return ;
EditItemEnd();

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

ScreenToClient(&point);

LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;

int nItem, nSubItem;
CString		str;

nItem = SubItemHitTest(&lvinfo);
if (nItem != -1)
{
	nItem = lvinfo.iItem;
	nSubItem = lvinfo.iSubItem;

	str.Format(_T("当前行, 列:(%d, %d) = %s"), nItem, nSubItem, GetItemText(nItem, nSubItem));
	*m_pStatic = str;
	(CWnd*)GetParent()->UpdateData(FALSE);

	nStartRowSelected = nItem, nStartColSelected = nSubItem, nEndRowSelected = -1, nEndColSelected = -1;
}

nColumn = -1;
if (bDrawAble)
	Invalidate();
bDrawAble = false ;

CListCtrl::OnLButtonDown(nFlags, point);

}

void CListCtrlUser::SetItemSelectedStatus(int nItem, int nSubItem)
{
if (!GetAsyncKeyState(VK_LBUTTON)) // 是否真选择?
return;
if (nEndRowSelected == nItem && nEndColSelected == nSubItem) // 选择是否有变化
return;

if (nEndRowSelected < 0)
	SetSingleItemStatus(nItem, nSubItem);		// 第一次显示
else
{
	int maxRow = max(nStartRowSelected, nEndRowSelected);
	int minRow = min(nStartRowSelected, nEndRowSelected);
	int maxCol = max(nStartColSelected, nEndColSelected);
	int minCol = min(nStartColSelected, nEndColSelected);

	for (int row = minRow; row <= maxRow; row++)
	for (int col = minCol; col <= maxCol; col++)
		SetSingleItemStatus(row, col);		// 取消原显示

	minCol = min(nStartColSelected, nSubItem);
	maxRow = max(nStartRowSelected, nItem);
	minRow = min(nStartRowSelected, nItem);
	maxCol = max(nStartColSelected, nSubItem);

	for (int row = minRow; row <= maxRow; row++)
	for (int col = minCol; col <= maxCol; col++)
		SetSingleItemStatus(row, col);		// 变色提示显示
}
bDrawAble = true;
nEndRowSelected == nItem, nEndColSelected == nSubItem;

}

void CListCtrlUser::SetSingleItemStatus(int nItem, int nSubItem)
{
CRect rect;
CClientDC dc(this);
HDC memDC;

GetItemRect(nItem, &rect, LVIR_BOUNDS);		// 得到当前行位置

int i = 0;
for (i = 0; i < nSubItem; i++)				// 计算当前行 item 的rect
	rect.left += GetColumnWidth(i);
rect.right = rect.left + GetColumnWidth(i);

memDC = CreateCompatibleDC(dc.GetSafeHdc());	// 变色显示准备	
HBITMAP	hBitmap = CreateCompatibleBitmap(memDC, rect.Width(), rect.Height());
SelectObject(memDC, hBitmap);

CDC *pDC = CDC::FromHandle(memDC);
CRect rectTemp(0, 0, rect.Width(), rect.Height());		// 相对位置

pDC->FillRect(&rectTemp, &CBrush(RGB(210,45,15*7 )));	// 选择部分变色显示
BitBlt(dc, rect.left, rect.top, rect.Width(), rect.Height(), memDC, 0, 0, SRCINVERT);  //SRCINVERT SRCCOPY SRCAND

CBitmap *pBitmap = CBitmap::FromHandle(hBitmap);
pBitmap->DeleteObject();				// 释放内存
DeleteObject(memDC);

}

void CListCtrlUser::OnRButtonDown(UINT nFlags, CPoint point)
{
EditItemEnd();

LVHITTESTINFO lvinfo;
lvinfo.pt = point;
lvinfo.flags = LVHT_ABOVE;

nRow = SubItemHitTest(&lvinfo);
if (nRow == -1)
	return;
nColumn = lvinfo.iSubItem;

CMenu	menu;
ClientToScreen(&point);

menu.LoadMenuW(IDR_MENU1);
CMenu *pPopMenu = menu.GetSubMenu(0);
pPopMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);

return;
CListCtrl::OnRButtonDown(nFlags, point);

}

void CListCtrlUser::OnCopyFromList()
{
CString str = _T("");
for (int m = nStartRowSelected; m <= nEndRowSelected; m++)
{
for (int n = nStartColSelected; n <= nEndColSelected; n++)
str = str + GetItemText(m, n) + _T(" "); // 选择区域内文字
str = str + char(13)+ char(10) ;
}

WriteToClipboard(str);

}

void CListCtrlUser::OnPasteToList()
{
// return;
CString strTemp = _T("\r"), strInput = ReadFromClipboard();
if (strInput.IsEmpty() || strInput.GetLength() < 1)
return;

int	m = nRow, n = nColumn;
while (strInput.GetLength() > 1)
{
	int len = strInput.GetLength();
	int p = strInput.FindOneOf(_T("\t"));
	if (p < 1)
		break;
	if (m >= GetItemCount())
		InsertItem(GetItemCount(), _T(""));
	SetItemText(m, n, strInput.Left(p));
	n++;

	if (strInput.GetAt(p + 1) == strTemp)
	{
		m++;
		p+= 2;
		n = nColumn;
	}
	strInput = strInput.Mid(p + 1);
}

}

void CListCtrlUser::OnDelFromList()
{
// return;
for (int m = nStartRowSelected; m <= nEndRowSelected; m++)
for (int n = nStartColSelected; n <= nEndColSelected; n++)
{
SetItemText(m, n, _T(""));
}
}

void CListCtrlUser::OnListctrlInsert()
{
CString strTemp = _T("\r"), strInput = ReadFromClipboard();
if (strInput.IsEmpty() || strInput.GetLength() < 1)
return;

int	m = nRow, n = nColumn;
bool bNewRow = true;
while (strInput.GetLength() > 1)
{
	int len = strInput.GetLength();
	int p = strInput.FindOneOf(_T("\t"));
	if (p < 1)
		break;
	if (bNewRow)
		InsertItem(m, _T(""));
	SetItemText(m, n, strInput.Left(p));
	n++;

	bNewRow = false;
	if (strInput.GetAt(p + 1) == strTemp)
	{
		m++;
		p+=2;
		n = nColumn;
		bNewRow = true;
	}
	strInput = strInput.Mid(p + 1);
}

}

void CListCtrlUser::OnMenuDelRow()
{
for (int m = nStartRowSelected; m <= nEndRowSelected; m++)
{
DeleteItem( nStartRowSelected );
}
}

BOOL CListCtrlUser::OnEraseBkgnd(CDC* pDC)
{
return true ;

return CListCtrl::OnEraseBkgnd(pDC);

}

(3)HeaderCtrlUser.h
// this is file HeaderCtrlUser.h
#if !defined(AFX_HEADERCTRLUSER_H__4EE58E6B_349E_4D9B_B159_0797B737FE72__INCLUDED_)
#define AFX_HEADERCTRLUSER_H__4EE58E6B_349E_4D9B_B159_0797B737FE72__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// HeaderCtrlUser.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CHeaderCtrlUser window

class CHeaderCtrlUser : public CHeaderCtrl
{
public:
CHeaderCtrlUser();

public:
CString m_Format[ 10 ]; //表示对齐类型的整型数组,0表示左对齐,1表示中间对齐,2表示右对齐

int m_R;				// 表头立体背景颜色
int m_G;				// 表头立体背景颜色 
int m_B;				// 表头立体背景颜色 
int m_Gradient;			// 表头立体背景颜色,渐变系数

int m_fontHeight;		//字体高度
int m_fontWith;			//字体宽度

float m_Height ;		//表头高度,这是倍数;高度随文字大小如何自动适应?
COLORREF m_color;		//表头文字颜色

LRESULT OnLayout( WPARAM wParam, LPARAM lParam );

public:
CString *m_pStatic;

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHeaderCtrlUser)
//}}AFX_VIRTUAL

public:
virtual ~CHeaderCtrlUser();

// Generated message map functions

protected:
//{{AFX_MSG(CHeaderCtrlUser)
afx_msg void OnPaint();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_HEADERCTRLUSER_H__4EE58E6B_349E_4D9B_B159_0797B737FE72__INCLUDED_)
(4)HeaderCtrlUser.cpp
// HeaderCtrlUser.cpp : implementation file//

#include “stdafx.h”
#include “test1.h”
#include “HeaderCtrlUser.h”

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

/////////////////////////////////////////////////////////////////////////////
// CHeaderCtrlUser

CHeaderCtrlUser::CHeaderCtrlUser()
{

}

CHeaderCtrlUser::~CHeaderCtrlUser()
{

}

BEGIN_MESSAGE_MAP(CHeaderCtrlUser, CHeaderCtrl)
//{{AFX_MSG_MAP(CHeaderCtrlUser)
ON_WM_PAINT()
ON_MESSAGE(HDM_LAYOUT, OnLayout)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
void CHeaderCtrlUser::OnPaint()
{
//AfxMessageBox(_T(“CHeaderCtrlUser::OnPaint()”));
//return;
CPaintDC dc(this);

int		nItems;
nItems = GetItemCount();		//得到有几个单元   
for (int nCol = 0; nCol < nItems; nCol++)
{
	CRect	tRect;
	int		R = m_R, G = m_G, B = m_B;

	GetItemRect(nCol, &tRect);		//得到Item的尺寸	
	CRect nRect(tRect);				//拷贝尺寸到新的容器中   
	CRect tempRect(tRect);
	nRect.left++;					//留出分割线的地方   

	//绘制立体背景   
	for (int j = tRect.top; j <= tRect.bottom; j++)
	{
		CBrush _brush;
		
		_brush.CreateSolidBrush(RGB(R, G, B));		//创建画刷   
		nRect.bottom = nRect.top + 1;
		dc.FillRect(&nRect, &_brush);				//填充背景   
		_brush.DeleteObject();						//释放画刷   
	
		R -= m_Gradient; G -= m_Gradient; B -= m_Gradient;
		if (R < 0)R = 0;
		if (G < 0)G = 0;
		if (B < 0)B = 0;
		nRect.top = nRect.bottom;
	}
	
	TCHAR		buffer[256];
	HD_ITEM		hdItem;

	hdItem.pszText = buffer;
	hdItem.cchTextMax = 256;
	hdItem.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER;
	GetItem(nCol, &hdItem);

	//将文字显示在一个适合的高度位置  
	int				ofst = 0;
	TEXTMETRIC		metric;
	CFont nFont, *nOldFont;
	UINT nFormat = DT_CENTER;	//*	DT_LEFT, DT_CENTER, DT_RIGHT;

	dc.GetTextMetrics(&metric);
	ofst = tRect.Height() - metric.tmHeight;
	tRect.OffsetRect(0, ofst / 2);
	
	dc.SetBkMode(TRANSPARENT);		
	dc.SetTextColor(m_color);		// dc.SetTextColor(RGB(250, 0, 0));
	nFont.CreateFont(m_fontHeight, m_fontWith, 0, 0, 0, FALSE, FALSE, 0, 0, 0, 0, 0, 0, _TEXT("宋体"));//创建字体   
	nOldFont = dc.SelectObject(&nFont);
	nFont.DeleteObject();			//释放字体   

	//AfxMessageBox(hdItem.pszText);
	if (nCol == 5)
	{
		HICON m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON3);
		dc.DrawIcon(tRect.left+ 5, tRect.top - 8, m_hIcon) ;
	}
	else
		dc.DrawText(buffer, &tRect, nFormat);
	dc.SelectObject(nOldFont);
}

//画头部剩余部分(没有标题的那部分)  
CRect rtRect, clientRect;

GetItemRect(nItems - 1, rtRect);
GetClientRect(clientRect);			//当前(CHeaderCtrl)控件的大小  

rtRect.left = rtRect.right + 1;
rtRect.right = clientRect.right;

int R = m_R, G = m_G, B = m_B;
CRect nRect(rtRect);

//绘制立体背景 
for (int j = rtRect.top; j <= rtRect.bottom; j++)
{
	CBrush _brush;

	_brush.CreateSolidBrush(RGB(R, G, B));	//创建画刷   
	nRect.bottom = nRect.top + 1;
	dc.FillRect(&nRect, &_brush);			//填充背景   
	_brush.DeleteObject();					//释放画刷  

	R -= m_Gradient;	G -= m_Gradient;	B -= m_Gradient;
	if (R < 0)	R = 0;
	if (G < 0)	G = 0;
	if (B < 0)	B = 0;
	nRect.top = nRect.bottom;
}

// 不为绘图消息调用 
//CHeaderCtrl::OnPaint();

}

LRESULT CHeaderCtrlUser::OnLayout(WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = CHeaderCtrl::DefWindowProc(HDM_LAYOUT, 0, lParam);

HD_LAYOUT &hdl = *(HD_LAYOUT *)lParam;
RECT *prc = hdl.prc;
WINDOWPOS *pwpos = hdl.pwpos;

//动态修改表头高度, 表头高度为原来 m_Height 倍   
int nHeight = (int)(pwpos->cy * m_Height);
pwpos->cy = nHeight;
prc->top = nHeight;

return lResult;

}
(5)CommFunction.h

// CommFunction.h
#pragma once

#include “stdafx.h”
//#include “afxdialogex.h”

void SetCurrentDirectorySimple();

void UnicodeToAnsiSimple(CString &strData);

void trans_Unicode_To_Ansi(CString &strData, CString &strDest);
void trans_Ansi_To_Unicode(CString &strData, CString &strDest);

void ClearClipboardContent();
void WriteToClipboard(CString m_editRead);
void AddToClipboard(CString m_editRead);
char * ReadFromClipboard();

(6)CommFunction.cpp
/// “CommFunction.cpp”

#include “stdafx.h”
//#include “afxcmn.h”
#include “CommFunction.h”

void SetCurrentDirectorySimple()
{
CString strPath;

GetModuleFileName(NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH);
strPath.ReleaseBuffer();

int		pos;
pos = strPath.ReverseFind('\\');
strPath = strPath.Left(pos);
SetCurrentDirectory(strPath);

}

void trans_Unicode_To_Ansi(CString &strData, CString &strDest){
// 输入必须是Unicode,否则,输出编码会出错
if (!strData) return;

//int nLen = WideCharToMultiByte(CP_ACP, 0, strData.GetBuffer(), -1, NULL, 0, NULL, NULL);
int nLen = WideCharToMultiByte(NULL, 0, strData.GetBuffer(), -1, NULL, 0, NULL, NULL);
strDest.GetBuffer(nLen + 1);

LPSTR	lpwstr = (LPSTR)(LPCTSTR)strDest.GetBuffer();
LPCWCH	lpcch = (LPCWCH)(LPCTSTR)strData.GetBuffer();
WideCharToMultiByte(NULL, 0, lpcch, -1, lpwstr, nLen, NULL, FALSE);
//lpwstr[nLen] = '\0';

}

void UnicodeToAnsiSimple(CString &strData){
CString strDest;

trans_Unicode_To_Ansi(strData, strDest);

strData = strDest;

}

void ExecuteApp(CString strParaGraph, CString strKeyName){
CString strPath, strIniFile, strAppFile;

GetModuleFileName(NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH);
strPath.ReleaseBuffer();

int		pos;
pos = strPath.ReverseFind('\\');
strIniFile = strPath.Left(pos) + _T("\\SystemConfig.ini");

//AfxMessageBox(strParaGraph + _T(" ") + strKeyName + _T(" ") + strIniFile + _T(" ") + strAppFile);
SetCurrentDirectorySimple();
GetPrivateProfileString(strParaGraph.GetBuffer(), strKeyName.GetBuffer(), CString("NOTEPAD.EXE"), strAppFile.GetBuffer(MAX_PATH), MAX_PATH, strIniFile.GetBuffer());

UnicodeToAnsiSimple(strAppFile);

WinExec((LPCSTR)strAppFile.GetString(), SW_SHOW);

}

// paste Clp
char * ReadFromClipboard()
{
//打开剪贴板
if (!OpenClipboard(NULL))
return ("");

HANDLE hData = GetClipboardData(CF_TEXT);

char * pBuffer = (char*)GlobalLock(hData);
GlobalUnlock(hData);
CloseClipboard();

return pBuffer;

}

void AddToClipboard(CString m_editRead)
{
if (!OpenClipboard(AfxGetMainWnd()->GetSafeHwnd()))
return;

m_editRead.ReleaseBuffer();
if (m_editRead.IsEmpty() || m_editRead.GetLength() < 1)
	return;

m_editRead = _T("\t") + m_editRead;
CString		strTemp = m_editRead;
UnicodeToAnsiSimple(strTemp);
m_editRead.ReleaseBuffer();
int nNewLen = strlen((char *)strTemp.GetBuffer());

HANDLE hClipMemory = GetClipboardData(CF_TEXT);
char * lpClipMemory = (char *)GlobalLock(hClipMemory);

int nOldLen = 0;
if (lpClipMemory)
	nOldLen = strlen(lpClipMemory);

//AfxMessageBox( strSource ) ;

HGLOBAL hglbCopy = GlobalAlloc(GMEM_DDESHARE, (nOldLen + nNewLen + 1));
char *  lptstrCopy = (char *)GlobalLock(hglbCopy);

if (nOldLen > 0)
	memcpy(lptstrCopy, lpClipMemory, nOldLen);
if (nNewLen > 0)
		memcpy(lptstrCopy + nOldLen, strTemp, nNewLen);
EmptyClipboard(); 
lptstrCopy[nOldLen + nNewLen] = 0;

GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT, hglbCopy);

CloseClipboard();

}

void ClearClipboardContent()
{
if (!OpenClipboard(AfxGetMainWnd()->GetSafeHwnd()))
return;

EmptyClipboard();

CloseClipboard();

}

void WriteToClipboard(CString m_editRead)
{
m_editRead.ReleaseBuffer();
if (m_editRead.IsEmpty() || m_editRead.GetLength() < 1)
return;

CString		strTemp = m_editRead;
UnicodeToAnsiSimple(strTemp);
int nNewLen = strlen((char *)strTemp.GetBuffer());
if (!nNewLen)
	return;

if (!OpenClipboard(AfxGetMainWnd()->GetSafeHwnd()))
	return;

HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (nNewLen + 1));
char *  lptstrCopy = (char *)GlobalLock(hglbCopy);

memcpy(lptstrCopy, (char *)strTemp.GetBuffer(), nNewLen );
EmptyClipboard();
lptstrCopy[nNewLen] = 0;

GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT, hglbCopy);

CloseClipboard();

}

void trans_Ansi_To_Unicode(CString &strData, CString &strDest){
// 输入必须是Ansi,否则,输出编码会出错. 待测试… …
char *p = (char *)strData.GetBuffer();
if (p == 0 || *p == 0) return;

int nLenOfData = strlen(p), nLenOfDest = (nLenOfData + 1) * sizeof(TCHAR);
strDest.GetBuffer(nLenOfDest);

LPWSTR	lpwstr = (LPWSTR)(LPCTSTR)strDest.GetBuffer();
LPCCH	lpcch = (LPCCH)(LPCTSTR)strData.GetBuffer();
MultiByteToWideChar(NULL, 0, lpcch, -1, lpwstr, nLenOfDest);

}
(7)test1Dlg.h
// this is file test1Dlg.h : header file
//
#include “ListCtrlUser.h”
#include “afxcmn.h”

#if !defined(AFX_TEST1DLG_H__1B5075B6_CB4D_4DB9_9ECD_A4D7606C6CAC__INCLUDED_)
#define AFX_TEST1DLG_H__1B5075B6_CB4D_4DB9_9ECD_A4D7606C6CAC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CTest1Dlg dialog

class CTest1Dlg : public CDialog
{
// Construction
public:
CTest1Dlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CTest1Dlg)
enum { IDD = IDD_TEST1_DIALOG };
CListCtrlUser m_listCtrl;
CString m_Static;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTest1Dlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
void InitListCtrl(void) ;

public:

protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CTest1Dlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnRadio1();
afx_msg void OnRadio2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TEST1DLG_H__1B5075B6_CB4D_4DB9_9ECD_A4D7606C6CAC__INCLUDED_)

(8)test1Dlg.cpp
// test1Dlg.cpp : implementation file
//

#include “stdafx.h”
#include “test1.h”
#include “test1Dlg.h”
#include “ListCtrlUser.h”
#include “afxcmn.h”

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

/////////////////////////////////////////////////////////////////////////////
// CTest1Dlg dialog

CTest1Dlg::CTest1Dlg(CWnd* pParent / =NULL/)
CDialog(CTest1Dlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTest1Dlg)
m_Static = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTest1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTest1Dlg)
DDX_Control(pDX, IDC_LIST1, m_listCtrl);
DDX_Text(pDX, IDC_STATIC1, m_Static);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTest1Dlg, CDialog)
//{{AFX_MSG_MAP(CTest1Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTest1Dlg message handlers

BOOL CTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
	CString strAboutMenu;
	strAboutMenu.LoadString(IDS_ABOUTBOX);
	if (!strAboutMenu.IsEmpty())
	{
		pSysMenu->AppendMenu(MF_SEPARATOR);
		pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);			// Set big icon
SetIcon(m_hIcon, FALSE);		// Set small icon

// TODO: Add extra initialization here
// 默认自绘风格
((CButton *)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE); 

InitListCtrl() ;

return TRUE;  // return TRUE  unless you set the focus to a control

}

void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CTest1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

	SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

	// Center icon in client rectangle
	int cxIcon = GetSystemMetrics(SM_CXICON);
	int cyIcon = GetSystemMetrics(SM_CYICON);
	CRect rect;
	GetClientRect(&rect);
	int x = (rect.Width() - cxIcon + 1) / 2;
	int y = (rect.Height() - cyIcon + 1) / 2;

	// Draw the icon
	dc.DrawIcon(x, y, m_hIcon);
}
else
{
	CDialog::OnPaint();
}

}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTest1Dlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CTest1Dlg::InitListCtrl(void){
DWORD dwStyle = m_listCtrl.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT; // 选中某行使整行高亮(仅仅适用与report 风格的listctrl )
dwStyle |= LVS_EX_GRIDLINES; // 网格线(仅仅适用与report 风格的listctrl )
//dwStyle |= LVS_EX_CHECKBOXES; // item 前生成checkbox 控件, 自绘方式无此属性
dwStyle |= LVS_EX_SUBITEMIMAGES; // 支持图标显示
//dwStyle |= LVS_EDITLABELS; // 支持编辑
//设置列表控件的报表显示方式
m_listCtrl.ModifyStyle(LVS_ICON | LVS_SMALLICON | LVS_LIST, LVS_REPORT);
m_listCtrl.SetExtendedStyle(dwStyle); // 设置扩展风格

//在列表控件中插入列
m_listCtrl.InsertColumn(0, _T("BIN #"), LVCFMT_CENTER, 80);		// LVCFMT_CENTER, LVCFMT_LEFT, LVCFMT_RIGHT, 
m_listCtrl.InsertColumn(1, _T("BIN NAME"), LVCFMT_CENTER, 200);
m_listCtrl.InsertColumn(2, _T("P/F"), LVCFMT_CENTER, 40);
m_listCtrl.InsertColumn(3, _T("COUNT"), LVCFMT_CENTER, 100);
m_listCtrl.InsertColumn(4, _T("%"), LVCFMT_CENTER, 100);
m_listCtrl.InsertColumn(5, _T("PIC"), LVCFMT_CENTER, 40);
m_listCtrl.InsertColumn(6, _T("SCALE"), LVCFMT_CENTER, 300);

CString	arrayBin[] = {_T("1.1"), _T("2.2"), _T("3.2"), _T("4.2"), _T("5.2"), _T("6.2"), _T("7.2"), _T("8.2"), _T("0.0")} ;
CString	arrayBinName[] = { _T("Pass"), _T("OS_fail"), _T("Icc_fail"), _T("Vfloat_pre_fail"), _T("Vfloat_aft_fail"), _T("Lcc3_fail"), _T("IBAT1_fail"), _T("ITRIKL_fail"), _T("SysMsg:Undefined")} ;
CString	arrayState[] = {_T("P"), _T("F"), _T("F"), _T("F"), _T("F"), _T("F"), _T("F"), _T("F"), _T("/")} ;
CString	arrayCount[] = {_T("6350"), _T("33"), _T("48"), _T("72"), _T("103"), _T("7"), _T("1"), _T("71"), _T("0")} ;
CString	arrayRatio[] = {_T("94.99"), _T("0.49"), _T("0.72"), _T("1.08"), _T("1.54"), _T("0.10"), _T("0.01"), _T("1.06"), _T("0.00")} ;
CString	arrayPic[] = { _T("G"), _T("R"), _T("R"), _T("R"), _T("B"), _T("R"), _T("R"), _T("R"), _T("Y")} ;

//在列表控件中插入行 sizeof(arrayBin)
for (int m = 0; m < sizeof(arrayBin)/sizeof(arrayBin[0]); m++)
{
	CString strItem = _T("");
	strItem.Format(_T("%d"), m);
	m_listCtrl.InsertItem(m, strItem);

	m_listCtrl.SetItemText(m, 0, _T("Bin ") + arrayBin[m]);
	m_listCtrl.SetItemText(m, 1, arrayBinName[m]);
	m_listCtrl.SetItemText(m, 2, arrayState[m]);
	m_listCtrl.SetItemText(m, 3, arrayCount[m]);
	m_listCtrl.SetItemText(m, 4, arrayRatio[m]);
	m_listCtrl.SetItemText(m, 5, arrayPic[m]);
}

m_listCtrl.SetRowHeigt( 28 );
m_listCtrl.SetHeaderHeight( 2.2f );
m_listCtrl.SetHeaderFontHW( 16, 0);					//设置头部字体高度,和宽度,0表示缺省,自适应 
m_listCtrl.SetHeaderTextColor(RGB(255, 11, 11));	//设置头部字体颜色
m_listCtrl.SetHeaderBKColor(188, 188, 111, 0 );		//设置头部背景色

m_listCtrl.m_pStatic = &m_Static ;
m_listCtrl.Refresh( ) ;

}

void CTest1Dlg::OnRadio2()
{
// TODO: Add your control notification handler code here
m_listCtrl.bDrawMode = false ;
m_listCtrl.ModifyStyle(LVS_OWNERDRAWFIXED, 0); // 取消自绘方式

m_listCtrl.Refresh( ) ;	

}

void CTest1Dlg::OnRadio1()
{
// TODO: Add your control notification handler code here
m_listCtrl.bDrawMode = true ;
m_listCtrl.ModifyStyle(0, LVS_OWNERDRAWFIXED); // 设置自绘方式

m_listCtrl.Refresh( ) ;	

}

5.资源文件(2个 = 1个H + 1个RC)
(1)resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 test1.rc 使用
//
#define IDM_ABOUTBOX 0x0010
#define IDS_ABOUTBOX 101
#define IDD_TEST1_DIALOG 102
#define IDR_MAINFRAME 128
#define IDI_ICON1 131
#define IDI_ICON2 132
#define IDI_ICON3 133
#define IDR_MENU1 134
#define IDC_LIST1 1000
#define IDC_RADIO1 1002
#define IDC_RADIO2 1003
#define IDC_STATIC1 1004
#define ID_32771 32771
#define ID_32772 32772
#define ID_32773 32773
#define ID_DEL_LIST 32774
#define ID_PASTE_LIST 32775
#define ID_COPY_LIST 32776
#define ID_LISTCTRL32777 32777
#define ID_LISTCTRL_INSERT 32778
#define ID_Menu 32779
#define ID_Menu_DelRow 32780

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 135
#define _APS_NEXT_COMMAND_VALUE 32781
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
(2)test1.rc

// Microsoft Visual C++ generated resource script.
//
#include “resource.h”

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include “afxres.h”

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE
BEGIN
“resource.h\0”
END

2 TEXTINCLUDE
BEGIN
“#include ““afxres.h””\r\n”
“\0”
END

3 TEXTINCLUDE
BEGIN
“#define _AFX_NO_SPLITTER_RESOURCES\r\n”
“#define _AFX_NO_OLE_RESOURCES\r\n”
“#define _AFX_NO_TRACKER_RESOURCES\r\n”
“#define _AFX_NO_PROPERTY_RESOURCES\r\n”
“\r\n”
“#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n”
“#ifdef _WIN32\r\n”
“LANGUAGE 4, 2\r\n”
“#pragma code_page(936)\r\n”
“#endif //_WIN32\r\n”
"#include ““res\test1.rc2"” // non-Microsoft Visual C++ edited resources\r\n”
“#include ““l.chs\afxres.rc”” // Standard components\r\n”
“#endif\r\n”
“\0”
END

#endif // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON “res\test1.ico”
IDI_ICON3 ICON “res\ico02.ico”

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_TEST1_DIALOG DIALOGEX 0, 0, 648, 428
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_APPWINDOW
CAPTION “ListCtrl自绘方式实例 ( VC6.0, 编者:贺昌锋,微信:13087561830)”
FONT 9, “宋体”, 0, 0, 0x1
BEGIN
DEFPUSHBUTTON “确定”,IDOK,493,407,50,14
PUSHBUTTON “取消”,IDCANCEL,591,407,50,14
LTEXT “It is so for the VC program developer’ world.”,IDC_STATIC1,7,7,191,8
CONTROL “List1”,IDC_LIST1,“SysListView32”,LVS_LIST | LVS_EDITLABELS | WS_BORDER,7,22,634,383
CONTROL “自绘方式”,IDC_RADIO1,“Button”,BS_AUTORADIOBUTTON | BS_FLAT,268,8,48,10
CONTROL “标准方式”,IDC_RADIO2,“Button”,BS_AUTORADIOBUTTON,217,8,48,10
END

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK “StringFileInfo”
BEGIN
BLOCK “080404B0”
BEGIN
VALUE “FileDescription”, “test1 Microsoft 基础类应用程序”
VALUE “FileVersion”, “1, 0, 0, 1”
VALUE “InternalName”, “test1”
VALUE “LegalCopyright”, “版权所有 © 2019”
VALUE “OriginalFilename”, “test1.EXE”
VALUE “ProductName”, “test1 应用程序”
VALUE “ProductVersion”, “1, 0, 0, 1”
END
END
BLOCK “VarFileInfo”
BEGIN
VALUE “Translation”, 0x804, 1200
END
END

/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_TEST1_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 641
TOPMARGIN, 7
BOTTOMMARGIN, 421
END
END
#endif // APSTUDIO_INVOKED

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MENU1 MENU
BEGIN
POPUP “ListCtrl快捷菜单”
BEGIN
MENUITEM “复制”, ID_COPY_LIST
MENUITEM “粘贴 - 替换”, ID_PASTE_LIST
MENUITEM “清除”, ID_DEL_LIST
MENUITEM “删除行”, ID_Menu_DelRow
MENUITEM “插入行”, ID_LISTCTRL_INSERT
END
END

/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
IDS_ABOUTBOX “关于 test1(&A)…”
END

#endif // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE 4, 2
#pragma code_page(936)
#endif //_WIN32
#include “res\test1.rc2” // non-Microsoft Visual C++ edited resources
#include “l.chs\afxres.rc” // Standard components
#endif

/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
6.其它
其它文件,像ICO文件等省略。

猜你喜欢

转载自blog.csdn.net/weixin_40554560/article/details/100062382