?? mylistctrl1.cpp
字號(hào):
#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
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -