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

📄 mylistctrl1.cpp

📁 电力监控系统 实时告警处理程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "stdafx.h"
#include "MyListCtrl1.h"
#include "evtdb.h"
#include "resource.h"

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

UINT NEAR WM_MyListCtrl1_COMBO_SELECTION  = ::RegisterWindowMessage(_T("WM_MyListCtrl1_COMBO_SELECTION"));
UINT NEAR WM_MyListCtrl1_CHECKBOX_CLICKED = ::RegisterWindowMessage(_T("WM_MyListCtrl1_CHECKBOX_CLICKED"));

/////////////////////////////////////////////////////////////////////////////
// CMyListCtrl1

BEGIN_MESSAGE_MAP(CMyListCtrl1, CListCtrl)
//{{AFX_MSG_MAP(CMyListCtrl1)
ON_NOTIFY_REFLECT_EX(NM_CLICK, OnClick)
ON_NOTIFY_REFLECT_EX(LVN_COLUMNCLICK, OnColumnClick)
ON_WM_CREATE()
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP

#ifndef NO_MyListCtrl1_TOOL_TIPS
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
#endif
END_MESSAGE_MAP()


///////////////////////////////////////////////////////////////////////////////
// ctor
CMyListCtrl1::CMyListCtrl1()
{
	
	
	m_dwExtendedStyleX      = 0;
	m_bHeaderIsSubclassed   = FALSE;
	
	m_cr3DFace              = ::GetSysColor(COLOR_3DFACE);
	m_cr3DHighLight         = ::GetSysColor(COLOR_3DHIGHLIGHT);
	m_cr3DShadow            = ::GetSysColor(COLOR_3DSHADOW);
	m_crBtnFace             = ::GetSysColor(COLOR_BTNFACE);
	m_crBtnShadow           = ::GetSysColor(COLOR_BTNSHADOW);
	m_crBtnText             = ::GetSysColor(COLOR_BTNTEXT);
	m_crGrayText            = ::GetSysColor(COLOR_GRAYTEXT);
	m_crHighLight           = ::GetSysColor(COLOR_HIGHLIGHT);
	m_crHighLightText       = ::GetSysColor(COLOR_HIGHLIGHTTEXT);
	m_crWindow              = ::GetSysColor(COLOR_WINDOW);
	m_crWindowText          = ::GetSysColor(COLOR_WINDOWTEXT);
}

///////////////////////////////////////////////////////////////////////////////
// dtor
CMyListCtrl1::~CMyListCtrl1()
{
	
}

///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
void CMyListCtrl1::PreSubclassWindow()
{
	CListCtrl::PreSubclassWindow();
	
	// for Dialog based applications, this is a good place
	// to subclass the header control because the OnCreate()
	// function does not get called.
	
	SubclassHeaderControl();
}

///////////////////////////////////////////////////////////////////////////////
// OnCreate
int CMyListCtrl1::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CListCtrl::OnCreate(lpCreateStruct) == -1)
	{
		ASSERT(FALSE);
		return -1;
	}
	
	// When the CMyListCtrl1 object is created via a call to Create(), instead
	// of via a dialog box template, we must subclass the header control
	// window here because it does not exist when the PreSubclassWindow()
	// function is called.
	
	SubclassHeaderControl();
	
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// SubclassHeaderControl
void CMyListCtrl1::SubclassHeaderControl()
{
	if (m_bHeaderIsSubclassed)
		return;
	
	// if the list control has a header control window, then
	// subclass it
	
	// Thanks to Alberto Gattegno and Alon Peleg牋and their article
	// "A Multiline Header Control Inside a CListCtrl" for easy way
	// to determine if the header control exists.
	
	CHeaderCtrl* pHeader = GetHeaderCtrl();
	if (pHeader)
	{
		VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd));
		m_bHeaderIsSubclassed = TRUE;
	}
}

///////////////////////////////////////////////////////////////////////////////
// OnClick
BOOL CMyListCtrl1::OnClick(NMHDR*, LRESULT* pResult)
{
	
	*pResult = 0;
	return FALSE;		// return FALSE to send message to parent also -
	// NOTE:  MSDN documentation is incorrect
}

///////////////////////////////////////////////////////////////////////////////
// OnCustomDraw
void CMyListCtrl1::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
	
	// Take the default processing unless we set this to something else below.
	*pResult = CDRF_DODEFAULT;
	
	// First thing - check the draw stage. If it's the control's prepaint
	// stage, then tell Windows we want messages for every item.
	
	if (pLVCD->nmcd.dwDrawStage == CDDS_PREPAINT)
	{
		*pResult = CDRF_NOTIFYITEMDRAW;
	}
	else if (pLVCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT)
	{
		// This is the notification message for an item.  We'll request
		// notifications before each subitem's prepaint stage.
		
		*pResult = CDRF_NOTIFYSUBITEMDRAW;
	}
	else if (pLVCD->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM))
	{
		// This is the prepaint stage for a subitem. Here's where we set the
		// item's text and background colors. Our return value will tell
		// Windows to draw the subitem itself, but it will use the new colors
		// we set here.
		
		int nItem = static_cast<int> (pLVCD->nmcd.dwItemSpec);
		int nSubItem = pLVCD->iSubItem;
		
		MyListCtrl1DATA *pXLCD = (MyListCtrl1DATA *) pLVCD->nmcd.lItemlParam;
		ASSERT(pXLCD);
		
		COLORREF crText  = m_crWindowText;
		COLORREF crBkgnd = m_crWindow;
		
		if (pXLCD)
		{
			crText  = pXLCD[nSubItem].crText;
			crBkgnd = pXLCD[nSubItem].crBackground;
			
			if (!pXLCD[0].bEnabled)
				crText = m_crGrayText;
		}
		
		// store the colors back in the NMLVCUSTOMDRAW struct
		pLVCD->clrText = crText;
		pLVCD->clrTextBk = crBkgnd;
		
		CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
		CRect rect;
		GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
		
		
		if (pXLCD && (pXLCD[nSubItem].nCheckedState != -1))
		{
			DrawCheckbox(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			
			*pResult = CDRF_SKIPDEFAULT;	// We've painted everything.
		}
		else
		{
			rect.left += DrawImage(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			
			DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			
			*pResult = CDRF_SKIPDEFAULT;	// We've painted everything.
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// DrawCheckbox
void CMyListCtrl1::DrawCheckbox(int nItem,
								int nSubItem,
								CDC *pDC,
								COLORREF crText,
								COLORREF crBkgnd,
								CRect& rect,
								MyListCtrl1DATA *pXLCD)
{
	ASSERT(pDC);
	ASSERT(pXLCD);
	
	GetDrawColors(nItem, nSubItem, crText, crBkgnd);
	
	pDC->FillSolidRect(&rect, crBkgnd);
	
	CRect chkboxrect;
	chkboxrect = rect;
	chkboxrect.bottom -= 1;
	chkboxrect.left += 9;		// line up checkbox with header checkbox
	chkboxrect.right = chkboxrect.left + chkboxrect.Height();	// width = height
	
	CString str;
	str = GetItemText(nItem, nSubItem);
	
	if (str.IsEmpty())
	{
		// center the checkbox
		
		chkboxrect.left = rect.left + rect.Width()/2 - chkboxrect.Height()/2 - 1;
		chkboxrect.right = chkboxrect.left + chkboxrect.Height();
	}
	
	// fill rect around checkbox with white
	pDC->FillSolidRect(&chkboxrect, m_crWindow);
	
	chkboxrect.left += 1;
	
	// draw border
	pDC->DrawEdge(&chkboxrect, EDGE_SUNKEN, BF_RECT);
	
	if (pXLCD[nSubItem].nCheckedState == 1)
	{
		CPen *pOldPen = NULL;
		
		CPen graypen(PS_SOLID, 1, m_crGrayText);
		CPen blackpen(PS_SOLID, 1, RGB(0,0,0));
		
		if (pXLCD[0].bEnabled)
			pOldPen = pDC->SelectObject(&blackpen);
		else
			pOldPen = pDC->SelectObject(&graypen);
		
		// draw the checkmark
		int x = chkboxrect.left + 9;
		ASSERT(x < chkboxrect.right);
		int y = chkboxrect.top + 3;
		int i;
		for (i = 0; i < 4; i++)
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x, y+3);
			x--;
			y++;
		}
		for (i = 0; i < 3; i++)
		{
			pDC->MoveTo(x, y);
			pDC->LineTo(x, y+3);
			x--;
			y--;
		}
		
		if (pOldPen)
			pDC->SelectObject(pOldPen);
	}
	
	if (!str.IsEmpty())
	{
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(crText);
		pDC->SetBkColor(crBkgnd);
		CRect textrect;
		textrect = rect;
		textrect.left = chkboxrect.right + 4;
		
		pDC->DrawText(str, &textrect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
	}
}

///////////////////////////////////////////////////////////////////////////////
// GetDrawColors
void CMyListCtrl1::GetDrawColors(int nItem,
								 int nSubItem,
								 COLORREF& colorText,
								 COLORREF& colorBkgnd)
{
	DWORD dwStyle    = GetStyle();
	DWORD dwExStyle  = GetExtendedStyle();
	
	COLORREF crText  = colorText;
	COLORREF crBkgnd = colorBkgnd;
	
	if (GetItemState(nItem, LVIS_SELECTED))
	{
		if (dwExStyle & LVS_EX_FULLROWSELECT)
		{
			// selected?  if so, draw highlight background
			crText  = m_crHighLightText;
			crBkgnd = m_crHighLight;
			
			// has focus?  if not, draw gray background
			if (m_hWnd != ::GetFocus())
			{
				if (dwStyle & LVS_SHOWSELALWAYS)
				{
					crText  = m_crWindowText;
					crBkgnd = m_crBtnFace;
				}
				else
				{
					crText  = colorText;
					crBkgnd = colorBkgnd;
				}
			}
		}
		else	// not full row select
		{
			if (nSubItem == 0)
			{
				// selected?  if so, draw highlight background
				crText  = m_crHighLightText;
				crBkgnd = m_crHighLight;
				
				// has focus?  if not, draw gray background
				if (m_hWnd != ::GetFocus())
				{
					if (dwStyle & LVS_SHOWSELALWAYS)
					{
						crText  = m_crWindowText;
						crBkgnd = m_crBtnFace;
					}
					else
					{
						crText  = colorText;
						crBkgnd = colorBkgnd;
					}
				}
			}
		}
	}
	
	colorText = crText;
	colorBkgnd = crBkgnd;
}

///////////////////////////////////////////////////////////////////////////////
// DrawImage
int CMyListCtrl1::DrawImage(int nItem,
							int nSubItem,
							CDC* pDC,
							COLORREF crText,
							COLORREF crBkgnd,
							CRect rect,
							MyListCtrl1DATA *pXLCD)
{
	GetDrawColors(nItem, nSubItem, crText, crBkgnd);
	
	pDC->FillSolidRect(&rect, crBkgnd);
	
	int nWidth = 0;
	rect.left += m_HeaderCtrl.GetSpacing();
	
	CImageList* pImageList = GetImageList(LVSIL_SMALL);
	if (pImageList)
	{
		SIZE sizeImage;
		sizeImage.cx = sizeImage.cy = 0;
		IMAGEINFO info;
		
		int nImage = -1;
		if (pXLCD)
			nImage = pXLCD[nSubItem].nImage;
		
		if (nImage == -1)
			return 0;
		
		if (pImageList->GetImageInfo(nImage, &info))
		{
			sizeImage.cx = info.rcImage.right - info.rcImage.left;
			sizeImage.cy = info.rcImage.bottom - info.rcImage.top;
		}
		
		if (nImage >= 0)
		{
			if (rect.Width() > 0)
			{
				POINT point;
				
				point.y = rect.CenterPoint().y - (sizeImage.cy >> 1);
				point.x = rect.left;
				
				SIZE size;
				size.cx = rect.Width() < sizeImage.cx ? rect.Width() : sizeImage.cx;
				size.cy = rect.Height() < sizeImage.cy ? rect.Height() : sizeImage.cy;
				
				// save image list background color
				COLORREF rgb = pImageList->GetBkColor();
				
				// set image list background color
				pImageList->SetBkColor(crBkgnd);
				pImageList->DrawIndirect(pDC, nImage, point, size, CPoint(0, 0));
				pImageList->SetBkColor(rgb);
				
				nWidth = sizeImage.cx + m_HeaderCtrl.GetSpacing();
			}
		}
	}
	
	return nWidth;
}

///////////////////////////////////////////////////////////////////////////////
// DrawText
void CMyListCtrl1::DrawText(int nItem,
							int nSubItem,
							CDC *pDC,
							COLORREF crText,
							COLORREF crBkgnd,
							CRect& rect,
							MyListCtrl1DATA *pXLCD)
{
	ASSERT(pDC);
	ASSERT(pXLCD);
	
	GetDrawColors(nItem, nSubItem, crText, crBkgnd);
	
	pDC->FillSolidRect(&rect, crBkgnd);
	
	CString str;
	str = GetItemText(nItem, nSubItem);
	
	if (!str.IsEmpty())
	{
		// get text justification
		HDITEM hditem;
		hditem.mask = HDI_FORMAT;
		m_HeaderCtrl.GetItem(nSubItem, &hditem);
		int nFmt = hditem.fmt & HDF_JUSTIFYMASK;
		UINT nFormat = DT_VCENTER | DT_SINGLELINE;
		if (nFmt == HDF_CENTER)
			nFormat |= DT_CENTER;
		else if (nFmt == HDF_LEFT)
			nFormat |= DT_LEFT;
		else
			nFormat |= DT_RIGHT;
		
		CFont *pOldFont = NULL;
		CFont boldfont;
		
		// check if bold specified for subitem
		if (pXLCD && pXLCD[nSubItem].bBold)
		{
			CFont *font = pDC->GetCurrentFont();
			if (font)
			{
				LOGFONT lf;
				font->GetLogFont(&lf);
				lf.lfWeight = FW_BOLD;
				boldfont.CreateFontIndirect(&lf);
				pOldFont = pDC->SelectObject(&boldfont);
			}
		}
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(crText);
		pDC->SetBkColor(crBkgnd);
		pDC->DrawText(str, &rect, nFormat);
		if (pOldFont)
			pDC->SelectObject(pOldFont);
	}
}

///////////////////////////////////////////////////////////////////////////////
// GetSubItemRect
BOOL CMyListCtrl1::GetSubItemRect(int nItem,
								  int nSubItem,
								  int nArea,
								  CRect& rect)
{
	ASSERT(nItem >= 0);
	ASSERT(nItem < GetItemCount());
	if ((nItem < 0) || nItem >= GetItemCount())
		return FALSE;
	ASSERT(nSubItem >= 0);
	ASSERT(nSubItem < GetColumns());
	if ((nSubItem < 0) || nSubItem >= GetColumns())
		return FALSE;
	
	BOOL bRC = CListCtrl::GetSubItemRect(nItem, nSubItem, nArea, rect);
	
	// if nSubItem == 0, the rect returned by CListCtrl::GetSubItemRect
	// is the entire row, so use left edge of second subitem
	
	if (nSubItem == 0)
	{
		if (GetColumns() > 1)
		{
			CRect rect1;
			bRC = GetSubItemRect(nItem, 1, LVIR_BOUNDS, rect1);
			rect.right = rect1.left;
		}
	}
	
	return bRC;
}

///////////////////////////////////////////////////////////////////////////////
// OnLButtonDown
void CMyListCtrl1::OnLButtonDown(UINT nFlags, CPoint point)
{
	
	int nItem = -1;
	CRect rect;
	int i;
	for (i = 0; i < GetItemCount(); i++)
	{
		if (CListCtrl::GetItemRect(i, &rect, LVIR_BOUNDS))
		{
			if (rect.PtInRect(point))
			{
				nItem = i;
				break;
			}
		}
	}
	
	if (nItem == -1)
	{
		
	}
	else
	{
		MyListCtrl1DATA *pXLCD = (MyListCtrl1DATA *) CListCtrl::GetItemData(nItem);
		if (!pXLCD)
		{
			return;
		}
		
		//		if (!pXLCD[0].bEnabled)4.16
		//			return;
		
		CRect rect;
		
		int nSubItem = -1;
		
		// check if a subitem checkbox was clicked
		

⌨️ 快捷键说明

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