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

📄 xlistctrl.cpp

📁 电力监控系统 实时告警处理程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// XListCtrl.cpp 
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "XListCtrl.h"
#include "evtdb.h"
#include "resource.h"
#include "RealEvView.h"
#include "DlgSetEvtOpt.h"

//#include "mainfrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

UINT NEAR WM_XLISTCTRL_COMBO_SELECTION  = ::RegisterWindowMessage(_T("WM_XLISTCTRL_COMBO_SELECTION"));
//UINT NEAR WM_XLISTCTRL_CHECKBOX_CLICKED = ::RegisterWindowMessage(_T("WM_XLISTCTRL_CHECKBOX_CLICKED"));

/////////////////////////////////////////////////////////////////////////////
// CXListCtrl

BEGIN_MESSAGE_MAP(CXListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CXListCtrl)
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()
	ON_COMMAND(ID_SET_OPTINFO, OnSetOptinfo)
	ON_WM_MOUSEMOVE()
	ON_WM_VSCROLL()
	ON_COMMAND(ID_SET_OPTSHOW, OnSetOptshow)
	ON_UPDATE_COMMAND_UI(ID_SET_OPTSHOW, OnUpdateSetOptshow)
	//}}AFX_MSG_MAP
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
ON_WM_TIMER()
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_VK_ESCAPE, OnComboEscape)
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_VK_RETURN, OnComboReturn)
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_KEYDOWN, OnComboKeydown)
ON_REGISTERED_MESSAGE(WM_XCOMBOLIST_LBUTTONUP, OnComboLButtonUp)
#endif
#ifndef NO_XLISTCTRL_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
CXListCtrl::CXListCtrl()
{
	m_bTitleTips=0;
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
	m_bComboIsClicked       = FALSE;
	m_nComboItem            = 0;
	m_nComboSubItem         = 0;
	m_pListBox              = NULL;
	m_bFontIsCreated        = FALSE;
	m_strInitialComboString = _T("");
#endif
	
	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);
	/*	m_font.CreateFont(-15,0,0,0,400,0,0,0,1,OUT_DEFAULT_PRECIS,
	CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
	DEFAULT_PITCH,"宋体" );*/
}

///////////////////////////////////////////////////////////////////////////////
// dtor
CXListCtrl::~CXListCtrl()
{
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
	if (m_pListBox)
		delete m_pListBox;
#endif
}

///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
void CXListCtrl::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 CXListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CListCtrl::OnCreate(lpCreateStruct) == -1)
	{
		ASSERT(FALSE);
		return -1;
	}
	
	// When the CXListCtrl 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 CXListCtrl::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 CXListCtrl::OnClick(NMHDR*, LRESULT* pResult)
{
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
	UnpressComboButton();
#endif
	*pResult = 0;
	return FALSE;		// return FALSE to send message to parent also -
	// NOTE:  MSDN documentation is incorrect
}

///////////////////////////////////////////////////////////////////////////////
// OnCustomDraw
void CXListCtrl::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;
		
		XLISTCTRLDATA *pXLCD = (XLISTCTRLDATA *) 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 =COLORREF(RGB(255,255,255));//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].bShowProgress))
		{
			DrawProgress(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			
			*pResult = CDRF_SKIPDEFAULT;	// We've painted everything.
		}
#ifndef DO_NOT_INCLUDE_XCOMBOLIST
		else if (pXLCD && (pXLCD[nSubItem].bCombo))
		{
			if (GetItemState(nItem, LVIS_SELECTED))
				DrawComboBox(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			else
				DrawText(nItem, nSubItem, pDC, crText, crBkgnd, rect, pXLCD);
			
			*pResult = CDRF_SKIPDEFAULT;	// We've painted everything.
		}
#endif
		else 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.
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
// DrawProgress
void CXListCtrl::DrawProgress(int nItem,
							  int nSubItem,
							  CDC *pDC,
							  COLORREF crText,
							  COLORREF crBkgnd,
							  CRect& rect,
							  XLISTCTRLDATA *pXLCD)
{
	UNUSED_ALWAYS(nItem);
	
	ASSERT(pDC);
	ASSERT(pXLCD);
	
	rect.bottom -= 1;
	rect.left += 1;		// leave margin in case row is highlighted
	rect.right -= 2;
	
	// draw border
	
	CPen graypen(PS_SOLID, 1, m_crBtnShadow);
	CPen *pOldPen = pDC->SelectObject(&graypen);
	
	pDC->MoveTo(rect.left, rect.bottom);
	pDC->LineTo(rect.right+1, rect.bottom);
	
	pDC->MoveTo(rect.left, rect.top);
	pDC->LineTo(rect.right, rect.top);
	
	pDC->MoveTo(rect.left, rect.top);
	pDC->LineTo(rect.left, rect.bottom);
	
	pDC->MoveTo(rect.right, rect.top);
	pDC->LineTo(rect.right, rect.bottom);
	
	// fill interior with light gray
	CRect InteriorRect;
	InteriorRect = rect;
	InteriorRect.left += 1;
	InteriorRect.top += 1;
	pDC->FillSolidRect(InteriorRect, RGB(224,224,224));
	
	// finish drawing border
	CPen blackpen(PS_SOLID, 1, RGB(0,0,0));
	pDC->SelectObject(&blackpen);
	
	pDC->MoveTo(rect.left+1, rect.top+1);
	pDC->LineTo(rect.right, rect.top+1);
	
	pDC->MoveTo(rect.left+1, rect.top+1);
	pDC->LineTo(rect.left+1, rect.bottom);
	
	pDC->SelectObject(pOldPen);
	
	if (pXLCD[nSubItem].nProgressPercent > 0)
	{
		// draw progress bar and text
		
		CRect LeftRect, RightRect;
		LeftRect = rect;
		LeftRect.left += 2;
		LeftRect.top += 2;
		RightRect = LeftRect;
		int w = (LeftRect.Width() * pXLCD[nSubItem].nProgressPercent) / 100;
		LeftRect.right = LeftRect.left + w;
		RightRect.left = LeftRect.right + 1;
		pDC->FillSolidRect(LeftRect, m_crHighLight);
		
		if (pXLCD[nSubItem].bShowProgressMessage)
		{
			CString str, format;
			format = pXLCD[nSubItem].strProgressMessage;
			if (format.IsEmpty())
				str.Format(_T("%d%%"), pXLCD[nSubItem].nProgressPercent);
			else
				str.Format(format, pXLCD[nSubItem].nProgressPercent);
			
			pDC->SetBkMode(TRANSPARENT);
			
			CRect TextRect;
			TextRect = rect;
			TextRect.DeflateRect(1, 1);
			TextRect.top += 1;
			
			CRgn rgn;
			rgn.CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
			pDC->SelectClipRgn(&rgn);
			pDC->SetTextColor(crBkgnd);
			pDC->DrawText(str, &TextRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
			
			rgn.DeleteObject();
			rgn.CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
			pDC->SelectClipRgn(&rgn);
			pDC->SetTextColor(crText);
			pDC->DrawText(str, &TextRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
			rgn.DeleteObject();
			pDC->SelectClipRgn(NULL);
		}
	}
}

#ifndef DO_NOT_INCLUDE_XCOMBOLIST
							  
							  ///////////////////////////////////////////////////////////////////////////////
							  // DrawComboBox
							  void CXListCtrl::DrawComboBox(int nItem,
								  int nSubItem,
								  CDC *pDC,
								  COLORREF crText,
								  COLORREF crBkgnd,
								  CRect& rect,
								  XLISTCTRLDATA *pXLCD)
							  {
								  UNUSED_ALWAYS(crText);
								  UNUSED_ALWAYS(crBkgnd);
								  
								  ASSERT(pDC);
								  ASSERT(pXLCD);
								  
#ifdef _DEBUG
								  DWORD dwExStyle = GetExtendedStyle();
								  if ((dwExStyle & LVS_EX_FULLROWSELECT) == 0)
								  {
									  ASSERT(FALSE);
								  }
#endif
								  
								  rect.bottom += 1;	// bottom edge is white, so this doesn't matter
								  rect.left += 1;		// leave margin in case row is highlighted
								  rect.right -= 2;
								  
								  // draw border
								  
								  CPen pen(PS_SOLID, 1, m_crBtnShadow);
								  CPen *pOldPen = pDC->SelectObject(&pen);
								  
								  pDC->MoveTo(rect.left, rect.bottom-2);
								  pDC->LineTo(rect.right, rect.bottom-2);
								  
								  pDC->MoveTo(rect.left, rect.top);
								  pDC->LineTo(rect.right, rect.top);
								  
								  pDC->MoveTo(rect.left, rect.top);
								  pDC->LineTo(rect.left, rect.bottom-2);
								  
								  pDC->MoveTo(rect.right, rect.top);
								  pDC->LineTo(rect.right, rect.bottom-1);
								  
								  CPen blackpen(PS_SOLID, 1, RGB(0,0,0));
								  pDC->SelectObject(&blackpen);
								  
								  // fill interior with white
								  CRect InteriorRect;
								  InteriorRect = rect;
								  InteriorRect.DeflateRect(2, 2);
								  pDC->FillSolidRect(InteriorRect, RGB(255,255,255));
								  
								  // set arrow rect
								  CRect ArrowRect;
								  ArrowRect = rect;
								  ArrowRect.right += 1;
								  ArrowRect.left = ArrowRect.right - ArrowRect.Height();
								  ArrowRect.DeflateRect(2, 2);
								  
								  CString str;
								  str = GetItemText(nItem, nSubItem);
								  
								  if (str.IsEmpty())
								  {
									  // subitem text is empty, try to get from listbox strings
									  if (pXLCD[nSubItem].psa)
									  {
										  int index = 0;
										  if ((pXLCD[nSubItem].nInitialComboSel >= 0) &&
											  (pXLCD[nSubItem].psa->GetSize() > pXLCD[nSubItem].nInitialComboSel))
										  {
											  index = pXLCD[nSubItem].nInitialComboSel;
											  str = pXLCD[nSubItem].psa->GetAt(index);
											  SetItemText(nItem, nSubItem, str);
										  }
									  }
								  }
								  
								  if (!str.IsEmpty())
								  {
									  // draw text
									  CRect TextRect;
									  TextRect = rect;
									  TextRect.top -= 1;
									  TextRect.left += 2;
									  TextRect.right = ArrowRect.left - 1;
									  
									  pDC->SetBkMode(TRANSPARENT);
									  COLORREF cr = m_crWindowText;
									  if (!pXLCD[0].bEnabled)
										  crText =COLORREF(RGB(255,255,255));//m_crGrayText;JYY
									  pDC->SetTextColor(cr);
									  pDC->SetBkColor(m_crWindow);
									  UINT nFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
									  pDC->DrawText(str, &TextRect, nFormat);
								  }
								  
								  if (!pXLCD[nSubItem].bComboIsClicked)
								  {
									  // draw depressed combobox
									  pDC->DrawEdge(&ArrowRect, EDGE_RAISED, BF_RECT);
									  ArrowRect.DeflateRect(2, 2);
									  pDC->FillSolidRect(ArrowRect, m_crBtnFace);
									  
									  // draw the downarrow using blackpen
									  int x = ArrowRect.left + 1;
									  int y = ArrowRect.top + 2;
									  int k = 5;
									  for (int i = 0; i < 3; i++)
									  {
										  pDC->MoveTo(x, y);

⌨️ 快捷键说明

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