www.pudn.com > SkinListDone.rar > SkinListCtrl.cpp
// SkinListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "SkinListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*****************************************************************
** credits for the custom highlight color bar
** using custom draw technique goes to Michael Dunn
**
** Neat Stuff to do in List Controls Using Custom Draw
** By Michael Dunn
** http://www.codeproject.com/listctrl/lvcustomdraw.asp?print=true
******************************************************************/
/////////////////////////////////////////////////////////////////////////////
// CSkinListCtrl
CSkinListCtrl::CSkinListCtrl()
{
g_MyClrBgHi = RGB(115,123,165);
g_MyClrFgHi = RGB(229,229,229);
}
CSkinListCtrl::~CSkinListCtrl()
{
}
BEGIN_MESSAGE_MAP(CSkinListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CSkinListCtrl)
ON_WM_NCCALCSIZE()
ON_WM_MOUSEWHEEL()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
//}}AFX_MSG_MAP
ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomDrawList )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSkinListCtrl message handlers
void CSkinListCtrl::PreSubclassWindow()
{
//use our custom CHeaderCtrl
m_SkinHeaderCtrl.SubclassWindow(GetHeaderCtrl()->m_hWnd);
CListCtrl::PreSubclassWindow();
}
void CSkinListCtrl::OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult )
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast( pNMHDR );
static bool bHighlighted = false;
// 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 ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
{
int iRow = (int)pLVCD->nmcd.dwItemSpec;
bHighlighted = IsRowHighlighted(m_hWnd, iRow);
if (bHighlighted)
{
pLVCD->clrText = g_MyClrFgHi; // Use my foreground hilite color
pLVCD->clrTextBk = g_MyClrBgHi; // Use my background hilite color
// Turn off listview highlight otherwise it uses the system colors!
EnableHighlighting(m_hWnd, iRow, false);
}
// We want item post-paint notifications, so...
*pResult = CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT;
}
else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
{
if (bHighlighted)
{
int iRow = (int)pLVCD->nmcd.dwItemSpec;
// Turn listview control's highlighting back on now that we have
// drawn the row in the colors we want.
EnableHighlighting(m_hWnd, iRow, true);
}
*pResult = CDRF_DODEFAULT;
}
}
void CSkinListCtrl::EnableHighlighting(HWND hWnd, int row, bool bHighlight)
{
ListView_SetItemState(hWnd, row, bHighlight? 0xff: 0, LVIS_SELECTED);
}
bool CSkinListCtrl::IsRowSelected(HWND hWnd, int row)
{
return ListView_GetItemState(hWnd, row, LVIS_SELECTED) != 0;
}
bool CSkinListCtrl::IsRowHighlighted(HWND hWnd, int row)
{
// We check if row is selected.
// We also check if window has focus. This was because the original listview
// control I created did not have style LVS_SHOWSELALWAYS. So if the listview
// does not have focus, then there is no highlighting.
return IsRowSelected(hWnd, row) /*&& (::GetFocus() == hWnd)*/;
}
void CSkinListCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
/*****************************************************************
** credits for this method of removing horz and vert
** scrollbars goes to Filbert Fox. He posted this solution
** on the www.codeguru.com discussion boards
******************************************************************/
//ensure the scrollbars are hidden
//ModifyStyle( WS_HSCROLL | WS_VSCROLL, 0 );
UpdateWindow();
CListCtrl::OnNcCalcSize(bCalcValidRects, lpncsp);
}
BOOL CSkinListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
m_SkinVerticleScrollbar.UpdateThumbPosition();
m_SkinHorizontalScrollbar.UpdateThumbPosition();
return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
}
void CSkinListCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
m_SkinVerticleScrollbar.UpdateThumbPosition();
m_SkinHorizontalScrollbar.UpdateThumbPosition();
CListCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CSkinListCtrl::Init()
{
//another way to hide scrollbars
InitializeFlatSB(this->m_hWnd);
FlatSB_EnableScrollBar(this->m_hWnd, SB_BOTH, ESB_DISABLE_BOTH);
//GetSystemMetrics to find out height difference of the
//titlebar so we can position scrollbars properly without
//having to worry about windows appearances affecting it
CWnd* pParent = GetParent();
CRect windowRect;
GetWindowRect(&windowRect);
int nTitleBarHeight = 0;
if(pParent->GetStyle() & WS_CAPTION)
nTitleBarHeight = GetSystemMetrics(SM_CYSIZE);
int nDialogFrameHeight = 0;
int nDialogFrameWidth = 0;
if((pParent->GetStyle() & WS_BORDER))
{
nDialogFrameHeight = GetSystemMetrics(SM_CYDLGFRAME);
nDialogFrameWidth = GetSystemMetrics(SM_CYDLGFRAME);
}
if(pParent->GetStyle() & WS_THICKFRAME)
{
nDialogFrameHeight+=1;
nDialogFrameWidth+=1;
}
//Create scrollbars at runtime
m_SkinVerticleScrollbar.Create(NULL, WS_CHILD|SS_LEFT|SS_NOTIFY|WS_VISIBLE|WS_GROUP,CRect(windowRect.right-nDialogFrameWidth,windowRect.top-nTitleBarHeight-nDialogFrameHeight-1,windowRect.right+12-nDialogFrameWidth,windowRect.bottom+11-nTitleBarHeight-nDialogFrameHeight), pParent);
m_SkinHorizontalScrollbar.Create(NULL, WS_CHILD|SS_LEFT|SS_NOTIFY|WS_VISIBLE|WS_GROUP,CRect(windowRect.left-nDialogFrameWidth,windowRect.bottom-nTitleBarHeight-nDialogFrameHeight-1,windowRect.right+1-nDialogFrameWidth,windowRect.bottom+11-nTitleBarHeight-nDialogFrameHeight), pParent);
m_SkinVerticleScrollbar.pList = this;
m_SkinHorizontalScrollbar.pList = this;
}
void CSkinListCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
m_SkinVerticleScrollbar.UpdateThumbPosition();
m_SkinHorizontalScrollbar.UpdateThumbPosition();
CListCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}
BOOL CSkinListCtrl::OnEraseBkgnd(CDC* pDC)
{
m_SkinVerticleScrollbar.UpdateThumbPosition();
m_SkinHorizontalScrollbar.UpdateThumbPosition();
return FALSE;
//return CListCtrl::OnEraseBkgnd(pDC);
}
void CSkinListCtrl::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CMemDC memDC(&dc, rect);
CRect headerRect;
GetDlgItem(0)->GetWindowRect(&headerRect);
ScreenToClient(&headerRect);
dc.ExcludeClipRect(&headerRect);
CRect clip;
memDC.GetClipBox(&clip);
memDC.FillSolidRect(clip, RGB(76,85,118));
SetTextBkColor(RGB(76,85,118));
m_SkinVerticleScrollbar.UpdateThumbPosition();
m_SkinHorizontalScrollbar.UpdateThumbPosition();
DefWindowProc(WM_PAINT, (WPARAM)memDC->m_hDC, (LPARAM)0);
}