⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysublistctrl.cpp

📁 可以让你同时选择多行
💻 CPP
字号:
// MyListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "RefeInfo.h"
#include "MysubListCtrl.h"

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

/////////////////////////////////////////////////////////////////////////////
// MyListCtrl

MyListCtrl::MyListCtrl()
{
	item=0;
	fItem=0;
	select=-1;
	str='a';
	width=0;
	reduce=0;
	m_nHighlight=0;
}

MyListCtrl::~MyListCtrl()
{
}


BEGIN_MESSAGE_MAP(MyListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(MyListCtrl)
	ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
	ON_WM_DRAWITEM()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// MyListCtrl message handlers
void MyListCtrl::InsertItem(int row,CString text,int col)
{
	if(row==item)
	{
		item++;
		fItem++;
		num[row]=fItem-1;
//		CListCtrl::InsertItem(fItem-1,text,col);

		CString fText,eText;
		int count;
		count=DivString(text,fText,eText,col,reduce);//截断字符串

		CListCtrl::InsertItem(fItem-1,fText,col);//插入字符串前段

		while(count)						//对字符串后段做相同处理
		{
			fItem++;
			num[row]++;
			text=eText;
			count=DivString(text,fText,eText,col,reduce);
			CListCtrl::InsertItem(fItem-1,fText,col);
		}
/*		if(eText.GetLength()>0)		//字符串后段不为空的话,将其插入
		{
			fItem++;
			num[row]++;
			CListCtrl::InsertItem(fItem,eText,col);
		}
*/
	}
	else 
	{
		AfxMessageBox(L"出错啦");
	}
}
void MyListCtrl::SetItemText(int row,int col,CString text)
{
	CString fText,eText;
	int count;
	count=DivString(text,fText,eText,col,reduce);//截断字符串

	int row2;
	if(row==0)row2=0;
	else row2=num[row-1]+1;
	CListCtrl::SetItemText(row2,col,fText);//插入字符串前段

	while(count)						//对字符串后段做相同处理
	{
		row2++;
		if(row2>=fItem)
		{
			CListCtrl::InsertItem(row2,L"",col);
			fItem++;
			num[item-1]++;
		}
		text=eText;
		count=DivString(text,fText,eText,col,reduce);
		CListCtrl::SetItemText(row2,col,fText);
	}
/*	if(eText.GetLength()>0)		//字符串后段不为空的话,将其插入
	{
		row2++;
		if(row2>=fItem)
		{
			CListCtrl::InsertItem(row2,L"",col);
			fItem++;
			num[item-1]++;
		}
		CListCtrl::SetItemText(row2,col,eText);
	}
*/
}
//分割字符串
int MyListCtrl::DivString(CString Text,CString& fText,CString &eText,int col,int reduce)
{
	int ColWidth=GetColumnWidth(col);//获取列宽
	int SpaceWidth=GetStringWidth(L" ");
	SpaceWidth=width/SpaceWidth;
	int TextWidth;
	fText="";
	eText="";
	int i,j,k;
	j=Text.GetLength();//获取字符串长度
	for(i=0;i<j;i++)
	{
		if(Text[i]=='\n'&&i>0)
		{
			break;
		}
		if(Text[i]==str&&width>0)
		{
			TextWidth=GetStringWidth(fText);
			if(TextWidth>width)
			{
				i--;
				for(k=0;k<SpaceWidth;k++)
					eText+=" ";
				break;
			}
			else
			{
				while(TextWidth<width)
				{
					fText+=" ";
					TextWidth=GetStringWidth(fText);
				}
			}
		}
		fText+=Text[i];
		TextWidth=GetStringWidth(fText);//获取字符串宽度
		if(TextWidth>ColWidth-reduce)//当字符串宽度超出列宽时截断
			break;
	}
	i++;
	for(i;i<j;i++)eText+=Text[i];
	TextWidth=GetStringWidth(eText);//剩余字符串宽度在列宽范围内则返回0,否则返回1
	if(TextWidth==0)return 0;
	else return 1;
}
void MyListCtrl::SetReduce(int r)
{
	reduce=r;
}
//设置特殊处理的字符
void MyListCtrl::SetChar(char str1,int width1)
{
	str=str1;
	width=width1;
}
int MyListCtrl::DeleteAllItems()
{
	item=0;
	fItem=0;
	return CListCtrl::DeleteAllItems();
}
int MyListCtrl::SetItemState(int nItem,UINT nState,UINT nMask)
{
	int i,last;
	if(item>0)
	{
		if(nItem==0)last=0;
		else last=num[nItem-1]+1;
		for(i=last;i<=num[nItem];i++)
		{
			CListCtrl::SetItemState(i,nState,nMask);//设置第i行选中,并去除虚线
		}
	}
	return 1;
}
//设置多行选中
void MyListCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	if(item>0)
	{
		//SetItemState(select,0,LVIS_SELECTED|LVIS_FOCUSED);//撤消第i行选中,并去除虚线
		int row=CListCtrl::GetSelectionMark();
		int i;
		for(i=0;i<item;i++)
			if(row<=num[i])break;
		select=i;
		SetItemState(select,LVIS_SELECTED,LVIS_SELECTED|LVIS_FOCUSED);//设置第i行选中,并去除虚线
	}
	*pResult = 0;

}

void MyListCtrl::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
	CRect rcItem(lpDrawItemStruct->rcItem);
	int nItem = lpDrawItemStruct->itemID;
	CImageList* pImageList;

	// Save dc state
	int nSavedDC = pDC->SaveDC();

	// Get item image and state info
	LV_ITEM lvi;
	lvi.mask = LVIF_IMAGE | LVIF_STATE;
	lvi.iItem = nItem;
	lvi.iSubItem = 0;
	lvi.stateMask = 0xFFFF;		// get all state flags
	GetItem(&lvi);

	// Should the item be highlighted
	BOOL bHighlight =((lvi.state & LVIS_DROPHILITED)||((lvi.state & LVIS_SELECTED)&&((GetFocus() == this)||
		(GetStyle() & LVS_SHOWSELALWAYS))));

	// Get rectangles for drawing
	CRect rcBounds, rcLabel, rcIcon;
	GetItemRect(nItem, rcBounds, LVIR_BOUNDS);
	GetItemRect(nItem, rcLabel, LVIR_LABEL);
	GetItemRect(nItem, rcIcon, LVIR_ICON);
	CRect rcCol( rcBounds ); 

	CString sLabel = GetItemText(nItem, 0 );

	// Labels are offset by a certain amount  
	// This offset is related to the width of a space character
	int offset = pDC->GetTextExtent(_T(" "), 1 ).cx*2;

	CRect rcHighlight;
	CRect rcClient;
	int nExt;
	switch(m_nHighlight)
	{
	case 0: 
		nExt=pDC->GetOutputTextExtent(sLabel).cx + offset;
		rcHighlight = rcLabel;
			
    	if( m_bitmap.m_hObject != NULL )
		{
   		    CDC tempDC;
			tempDC.CreateCompatibleDC(pDC);
			tempDC.SelectObject( &m_bitmap );

			GetClientRect(&rcClient);

			CRgn rgnBitmap;
			CRect rcTmpBmp( rcItem );
		
			rcTmpBmp.right = rcClient.right;

			// We also need to check whether it is the last item
			// The update region has to be extended to the bottom if it is
			if( nItem == GetItemCount() - 1 )	
				rcTmpBmp.bottom = rcClient.bottom;

			rgnBitmap.CreateRectRgnIndirect(&rcTmpBmp);
			pDC->SelectClipRgn(&rgnBitmap);
			rgnBitmap.DeleteObject();

			CRect rcFirstItem;
			GetItemRect(0, rcFirstItem, LVIR_BOUNDS);

			for (int i = rcFirstItem.left; i < rcTmpBmp.right; i += m_cxBitmap)
				for (int j = rcFirstItem.top; j < rcTmpBmp.bottom; j += m_cyBitmap)
					pDC->BitBlt(i, j, m_cxBitmap, m_cyBitmap, &tempDC, 0, 0, SRCCOPY);

		}
	}
	// Draw the background color
	if( bHighlight )
	{
		pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
		pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));

//		rcHighlight.right=rcClient.right;//背景绘制扩展到整行
//		pDC->FillRect(rcHighlight, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
		CBrush tBrush(::GetSysColor(COLOR_HIGHLIGHT));
		if(text_bitmap.m_hObject!=NULL)
			tBrush.CreatePatternBrush(&text_bitmap);
		pDC->FillRect(rcClient, &tBrush);
	}

	else if( m_bitmap.m_hObject == NULL )
		pDC->FillRect(rcHighlight, &CBrush(::GetSysColor(COLOR_WINDOW)));
	
	// Set clip region
	rcCol.right = rcCol.left + GetColumnWidth(0);
	CRgn rgn;
	rgn.CreateRectRgnIndirect(&rcCol);
	pDC->SelectClipRgn(&rgn);
	rgn.DeleteObject();

	// Draw state icon
	if (lvi.state & LVIS_STATEIMAGEMASK)
	{
		int nImage = ((lvi.state & LVIS_STATEIMAGEMASK)>>12) - 1;
		pImageList = GetImageList(LVSIL_STATE);
		if (pImageList)
		{
			pImageList->Draw(pDC, nImage,
				CPoint(rcCol.left, rcCol.top), ILD_TRANSPARENT);
		}
	}
	
	// Draw normal and overlay icon
	pImageList = GetImageList(LVSIL_SMALL);
	if (pImageList)
	{
		UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
		pImageList->Draw(pDC, lvi.iImage, 
			CPoint(rcIcon.left, rcIcon.top),
			(bHighlight?ILD_BLEND50:0) | ILD_TRANSPARENT | nOvlImageMask );
	}

	
	
	// Draw item label - Column 0
	rcLabel.left += offset/2;
	rcLabel.right -= offset;

	pDC->DrawText(sLabel,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP 
				| DT_VCENTER | DT_END_ELLIPSIS);


	// Draw labels for remaining columns
	LV_COLUMN lvc;
	lvc.mask = LVCF_FMT | LVCF_WIDTH;
/*
	//如果只是第一行选中时高亮显示,则重新设置颜色
	if( m_nHighlight == 0 )		// Highlight only first column
	{
		pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
		pDC->SetBkColor(::GetSysColor(COLOR_WINDOW));
	}
*/	
	rcBounds.right = rcHighlight.right > rcBounds.right ? rcHighlight.right :
							rcBounds.right;
	rgn.CreateRectRgnIndirect(&rcBounds);
	pDC->SelectClipRgn(&rgn);
				   
	for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
	{
		rcCol.left = rcCol.right;
		rcCol.right += lvc.cx;

		// Draw the background if needed&& m_nHighlight == HIGHLIGHT_NORMAL
		if( m_bitmap.m_hObject == NULL  )
			pDC->FillRect(rcCol, &CBrush(::GetSysColor(COLOR_WINDOW)));

		sLabel = GetItemText(nItem, nColumn);
		if (sLabel.GetLength() == 0)
			continue;


		// Get the text justification
		UINT nJustify = DT_LEFT;
		switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
		{
		case LVCFMT_RIGHT:
			nJustify = DT_RIGHT;
			break;
		case LVCFMT_CENTER:
			nJustify = DT_CENTER;
			break;
		default:
			break;
		}

		rcLabel = rcCol;
		rcLabel.left += offset;
		rcLabel.right -= offset;

		pDC->DrawText(sLabel, -1, rcLabel, nJustify | DT_SINGLELINE 
				| DT_NOPREFIX | DT_VCENTER | DT_END_ELLIPSIS);
	}
/*
	//显示虚线框
	// Draw focus rectangle if item has focus
	if (lvi.state & LVIS_FOCUSED && (GetFocus() == this))		
		pDC->DrawFocusRect(rcHighlight);
*/
	// Restore dc
	pDC->RestoreDC( nSavedDC );
}

BOOL MyListCtrl::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	CRect rcclient;
	GetClientRect(&rcclient);
	if( m_bitmap.m_hObject!=NULL)
	{
		pDC->FillRect(rcclient,&brush);
		return TRUE;
	}
	else
		return CListCtrl::OnEraseBkgnd(pDC);
}
//设置背景图片
void MyListCtrl::SetBkImage(int nID)
{
	m_bitmap.LoadBitmap(nID);
	BITMAP bm;
	m_bitmap.GetBitmap(&bm);
	m_cxBitmap = bm.bmWidth;
	m_cyBitmap = bm.bmHeight;
	brush.CreatePatternBrush(&m_bitmap);
}
void MyListCtrl::SetTextImage(int nID)
{
	text_bitmap.LoadBitmap(nID);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -