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

📄 flatheaderctrl.cpp

📁 磁盘容量扫描、但界面和程序结构非常不错
💻 CPP
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////
//	File:		CFlatHeaderCtrl.cpp
//	Version:	1.0.1.0
//
//	Author:		Maarten Hoeben
//	E-mail:		hoeben@nwn.com
//
//	Implementation of the CFlatHeaderCtrl and associated classes.
//
//	You are free to use, distribute or modify this code
//	as long as the header is not removed or modified.
//
//	Version history
//
//	1.0.0.1	- Initial release
//	1.0.1.0 - Fixed FHDragWnd destroy warning (thanks Philippe Terrier)
//			- Fixed double sent HDN_ITEMCLICK
//			- Added a property that adjusts for ListCtrls that use a static
//			  border for flat look.
//
////////////////////////////////////////////////////////////////////////////


// FlatHeaderCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "FlatHeaderCtrl.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFHDragWnd

CFHDragWnd::CFHDragWnd()
{
	// Register the window class if it has not already been registered.
	WNDCLASS wndclass;
	HINSTANCE hInst = AfxGetInstanceHandle();

	if(!(::GetClassInfo(hInst, FHDRAGWND_CLASSNAME, &wndclass)))
	{
		// otherwise we need to register a new class
		wndclass.style = CS_SAVEBITS ;
		wndclass.lpfnWndProc = ::DefWindowProc;
		wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
		wndclass.hInstance = hInst;
		wndclass.hIcon = NULL;
		wndclass.hCursor = LoadCursor( hInst, IDC_ARROW );
		wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); 
		wndclass.lpszMenuName = NULL;
		wndclass.lpszClassName = FHDRAGWND_CLASSNAME;
		if (!AfxRegisterClass(&wndclass))
			AfxThrowResourceException();
	}
}

CFHDragWnd::~CFHDragWnd()
{
}


BEGIN_MESSAGE_MAP(CFHDragWnd, CWnd)
	//{{AFX_MSG_MAP(CFHDragWnd)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CFHDragWnd message handlers

BOOL CFHDragWnd::Create(CRect rect, CFlatHeaderCtrl* pFlatHeaderCtrl, INT iItem)
{
	ASSERT_VALID(pFlatHeaderCtrl);
	ASSERT(pFlatHeaderCtrl->IsKindOf(RUNTIME_CLASS(CFlatHeaderCtrl)));

	m_pFlatHeaderCtrl = pFlatHeaderCtrl;
	m_iItem = iItem;

	DWORD dwStyle = WS_POPUP|WS_DISABLED;
	DWORD dwExStyle = WS_EX_TOPMOST|WS_EX_TOOLWINDOW ;

	return CreateEx(dwExStyle, FHDRAGWND_CLASSNAME, NULL, dwStyle, 
		rect.left, rect.top, rect.Width(), rect.Height(),
		NULL, NULL, NULL );
}


void CFHDragWnd::OnPaint() 
{
	CPaintDC dc(this);
	
    if(m_pFlatHeaderCtrl->m_bNoFlicker)
    {
        CMemDC MemDC(&dc);
        OnDraw(&MemDC);
    }
    else
        OnDraw(&dc);
}

BOOL CFHDragWnd::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}

void CFHDragWnd::OnDraw(CDC* pDC)
{
	CRect rect;
	GetClientRect(rect);

    pDC->FillSolidRect(rect, m_pFlatHeaderCtrl->m_cr3DFace);
	pDC->Draw3dRect(rect, m_pFlatHeaderCtrl->m_cr3DHighLight, m_pFlatHeaderCtrl->m_cr3DShadow);

	CPen* pPen = pDC->GetCurrentPen();
	CFont* pFont = pDC->SelectObject(m_pFlatHeaderCtrl->GetFont());

	pDC->SetBkColor(m_pFlatHeaderCtrl->m_cr3DFace);
	pDC->SetTextColor(m_pFlatHeaderCtrl->m_crText);

	rect.DeflateRect(m_pFlatHeaderCtrl->m_iSpacing, 0);
	m_pFlatHeaderCtrl->DrawItem(
		pDC,
		rect,
		m_pFlatHeaderCtrl->m_hditemHotItem,
		m_pFlatHeaderCtrl->m_iSortColumn == m_iItem,
		m_pFlatHeaderCtrl->m_bSortAscending
	);

	pDC->SelectObject(pFont);
	pDC->SelectObject(pPen);
}

void CFHDragWnd::PostNcDestroy() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CWnd::PostNcDestroy();
	delete this;
}

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl

IMPLEMENT_DYNCREATE(CFlatHeaderCtrl, CHeaderCtrl)

CFlatHeaderCtrl::CFlatHeaderCtrl()
{
	m_bNoFlicker = TRUE;
	m_iSpacing = 6;
	m_sizeArrow.cx = 8;
	m_sizeArrow.cy = 8;
	m_bStaticBorder = FALSE;

	m_iHotIndex = -1;
	m_bHotItemResizable = TRUE;

	m_bResizing = FALSE;

	m_iHotDivider = -1;
	m_crHotDivider = 0x000000FF;

	m_bDragging = FALSE;
	m_pDragWnd = NULL;

	m_nClickFlags = 0;

	m_bSortAscending = FALSE;
	m_iSortColumn = -1;
	m_arrayHdrItemEx.SetSize(0, 8);

	m_cr3DHighLight = ::GetSysColor(COLOR_3DHIGHLIGHT);
	m_cr3DShadow = ::GetSysColor(COLOR_3DSHADOW);
	m_cr3DFace = ::GetSysColor(COLOR_3DFACE);
	m_crText = ::GetSysColor(COLOR_BTNTEXT);
}

CFlatHeaderCtrl::~CFlatHeaderCtrl()
{
	if(m_pDragWnd != NULL)
	{
		m_pDragWnd->DestroyWindow();
		m_pDragWnd = NULL;
	}
}

BEGIN_MESSAGE_MAP(CFlatHeaderCtrl, CHeaderCtrl)
	//{{AFX_MSG_MAP(CFlatHeaderCtrl)
	ON_MESSAGE(HDM_INSERTITEMA, OnInsertItem)
	ON_MESSAGE(HDM_INSERTITEMW, OnInsertItem)
	ON_MESSAGE(HDM_DELETEITEM, OnDeleteItem)
	ON_MESSAGE(HDM_SETHOTDIVIDER, OnSetHotDivider)
	ON_MESSAGE(HDM_LAYOUT, OnLayout)
	ON_WM_NCHITTEST()
	ON_WM_SETCURSOR()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_PAINT()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_ERASEBKGND()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl attributes

BOOL CFlatHeaderCtrl::ModifyProperty(WPARAM wParam, LPARAM lParam)
{
	switch(wParam)
	{
	case FH_PROPERTY_SPACING:
		m_iSpacing = (INT)lParam;
		break;

	case FH_PROPERTY_ARROW:
		m_sizeArrow.cx = LOWORD(lParam);
		m_sizeArrow.cy = HIWORD(lParam);
		break;

	case FH_PROPERTY_STATICBORDER:
		m_bStaticBorder = (BOOL)lParam;
		break;

	default:
		return FALSE;
	}

	Invalidate();
	return TRUE;
}

BOOL CFlatHeaderCtrl::GetItemEx(INT iPos, HDITEMEX* phditemex) const
{
	if(iPos>=m_arrayHdrItemEx.GetSize())
		return FALSE;

	*phditemex = m_arrayHdrItemEx[iPos];
	return TRUE;
}

BOOL CFlatHeaderCtrl::SetItemEx(INT iPos, HDITEMEX* phditemex)
{
	if(iPos>=m_arrayHdrItemEx.GetSize())
		return FALSE;

	if(phditemex->m_iMinWidth<=phditemex->m_iMaxWidth)
	{
		HDITEM hditem;
		hditem.mask = HDI_WIDTH;
		if(!GetItem(iPos, &hditem))
			return FALSE;

		if(hditem.cxy < phditemex->m_iMinWidth)
			hditem.cxy = phditemex->m_iMinWidth;

		if(hditem.cxy > phditemex->m_iMaxWidth)
			hditem.cxy = phditemex->m_iMaxWidth;

		SetItem(iPos, &hditem);
	}

	m_arrayHdrItemEx.SetAt(iPos, *phditemex);
	return TRUE;
}

void CFlatHeaderCtrl::SetSortColumn(INT iPos, BOOL bSortAscending)
{
	ASSERT(iPos < GetItemCount());

	m_bSortAscending = bSortAscending;
	m_iSortColumn = iPos;
	Invalidate();
}

INT CFlatHeaderCtrl::GetSortColumn(BOOL* pbSortAscending)
{
	if(pbSortAscending)
		*pbSortAscending = m_bSortAscending;

	return m_iSortColumn;
}

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl implementation

void CFlatHeaderCtrl::DrawCtrl(CDC* pDC)
{
	CRect rectClip;
	if (pDC->GetClipBox(&rectClip) == ERROR)
		return;

	CRect rectClient, rectItem;
	GetClientRect(&rectClient);

    pDC->FillSolidRect(rectClip, m_cr3DFace);

	INT iItems = GetItemCount();
	ASSERT(iItems >= 0);

	CPen penHighLight(PS_SOLID, 1, m_cr3DHighLight);
	CPen penShadow(PS_SOLID, 1, m_cr3DShadow);
	CPen* pPen = pDC->GetCurrentPen();

	CFont* pFont = pDC->SelectObject(GetFont());

	pDC->SetBkColor(m_cr3DFace);
	pDC->SetTextColor(m_crText);

	INT iWidth = 0;

	for(INT i=0;i<iItems;i++)
	{
		INT iItem = OrderToIndex(i);

		TCHAR szText[FLATHEADER_TEXT_MAX];

		HDITEM hditem;
		hditem.mask = HDI_WIDTH|HDI_FORMAT|HDI_TEXT|HDI_IMAGE|HDI_BITMAP;
		hditem.pszText = szText;
		hditem.cchTextMax = sizeof(szText);
		VERIFY(GetItem(iItem, &hditem));

		VERIFY(GetItemRect(iItem, rectItem));

		if (rectItem.right >= rectClip.left || rectItem.left <= rectClip.right)
		{
			if(hditem.fmt&HDF_OWNERDRAW)
			{
				DRAWITEMSTRUCT disItem;
				disItem.CtlType = ODT_BUTTON;
				disItem.CtlID = GetDlgCtrlID();
				disItem.itemID = iItem;
				disItem.itemAction = ODA_DRAWENTIRE;
				disItem.itemState = 0;
				disItem.hwndItem = m_hWnd;
				disItem.hDC = pDC->m_hDC;
				disItem.rcItem = rectItem;
				disItem.itemData = 0;

				DrawItem(&disItem);
			}
			else
			{
				rectItem.DeflateRect(m_iSpacing, 0);
				DrawItem(pDC, rectItem, hditem, iItem == m_iSortColumn, m_bSortAscending);
				rectItem.InflateRect(m_iSpacing, 0);

				if(m_nClickFlags&MK_LBUTTON && m_iHotIndex == iItem && m_hdhtiHotItem.flags&HHT_ONHEADER)
					pDC->InvertRect(rectItem);
			}

			if(i < iItems-1)
			{
				pDC->SelectObject(&penShadow);
				pDC->MoveTo(rectItem.right-1, rectItem.top+2);
				pDC->LineTo(rectItem.right-1, rectItem.bottom-2);

				pDC->SelectObject(&penHighLight);
				pDC->MoveTo(rectItem.right, rectItem.top+2);
				pDC->LineTo(rectItem.right, rectItem.bottom-2);
			}
		}

		iWidth += hditem.cxy;
	}

	if(iWidth > 0)
	{
		rectClient.right = rectClient.left + iWidth + 1;
		pDC->Draw3dRect(rectClient, m_cr3DHighLight, m_cr3DShadow);
	}

	if(m_iHotDivider>=0)
	{
		INT iOffset;
		
		if(m_iHotDivider<iItems)
		{
			GetItemRect(OrderToIndex(m_iHotDivider), rectItem);
			iOffset = rectItem.left - 1;
		}
		else
		{
			GetItemRect(OrderToIndex(iItems-1), rectItem);
			iOffset = rectItem.right;
		}

		CPoint points[3];

		CPen penDivider(PS_SOLID, 1, m_crHotDivider);
		pDC->SelectObject(&penDivider);

		CBrush brushDivider(m_crHotDivider);
		pDC->SelectObject(&brushDivider);

		points[0] = CPoint(iOffset - 4, rectClient.bottom-1);
		points[1] = CPoint(iOffset, rectClient.bottom - 5);
		points[2] = CPoint(iOffset + 4, rectClient.bottom-1);

		pDC->Polygon(points, 3);

		points[0] = CPoint(iOffset - 4, 0);
		points[1] = CPoint(iOffset, 4);
		points[2] = CPoint(iOffset + 4, 0);

		pDC->Polygon(points, 3);
	}


	pDC->SelectObject(pFont);
	pDC->SelectObject(pPen);
}

void CFlatHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT)
{
	ASSERT(FALSE);  // must override for self draw header controls
}

void CFlatHeaderCtrl::DrawItem(CDC* pDC, CRect rect, HDITEM hditem, BOOL bSort, BOOL bSortAscending)
{
	ASSERT(hditem.mask&HDI_FORMAT);

	INT iWidth = 0;

	CBitmap* pBitmap = NULL;
	BITMAP BitmapInfo;
	if(hditem.fmt&HDF_BITMAP)
	{
		ASSERT(hditem.mask&HDI_BITMAP);
		ASSERT(hditem.hbm);

		pBitmap = CBitmap::FromHandle(hditem.hbm);
		if(pBitmap)
			VERIFY(pBitmap->GetObject(sizeof(BITMAP), &BitmapInfo));
	}

	switch(hditem.fmt&HDF_JUSTIFYMASK)
	{
	case HDF_LEFT:
		rect.left += (iWidth = DrawImage(pDC, rect, hditem, FALSE)) ? iWidth+m_iSpacing : 0;
		if(hditem.fmt&HDF_IMAGE && !iWidth)
			break;
		rect.right -= bSort ? m_iSpacing+m_sizeArrow.cx : 0;
		rect.left += (iWidth = DrawText(pDC, rect, hditem)) ? iWidth+m_iSpacing*3 : 0;
		if(bSort)
		{
			rect.right += m_iSpacing+m_sizeArrow.cx;
			rect.left += DrawArrow(pDC, rect, bSortAscending, FALSE)+m_iSpacing;
		}
		DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, TRUE);
		break;

	case HDF_CENTER:
		rect.left += (iWidth = DrawImage(pDC, rect, hditem, FALSE)) ? iWidth+m_iSpacing : 0;
		if(hditem.fmt&HDF_IMAGE && !iWidth)
			break;

		rect.left += bSort ? m_iSpacing+m_sizeArrow.cx : 0;
		rect.right -= (iWidth=DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, TRUE)) ? iWidth+m_iSpacing:0;
		if(bSort)
		{
			rect.left -= m_iSpacing+m_sizeArrow.cx;
			rect.right -= DrawArrow(pDC, rect, bSortAscending, TRUE)+2*m_iSpacing;
		}
		DrawText(pDC, rect, hditem);
		break;

	case HDF_RIGHT:
		if(!(hditem.fmt&HDF_BITMAP_ON_RIGHT))
			rect.left += (iWidth=DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, FALSE)) ? iWidth+m_iSpacing:0;

		rect.left += (iWidth = DrawImage(pDC, rect, hditem, FALSE)) ? iWidth+m_iSpacing : 0;
		if(hditem.fmt&HDF_IMAGE && !iWidth)
			break;

		rect.left += bSort && (hditem.fmt&HDF_BITMAP_ON_RIGHT) ? m_iSpacing+m_sizeArrow.cx : 0;
		if(hditem.fmt&HDF_BITMAP_ON_RIGHT)
			rect.right -= (iWidth=DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, TRUE)) ? iWidth+m_iSpacing:0;
		if(bSort)
		{
			rect.left -= (hditem.fmt&HDF_BITMAP_ON_RIGHT) ? m_iSpacing+m_sizeArrow.cx:0;
			rect.right -= DrawArrow(pDC, rect, bSortAscending, TRUE)+2*m_iSpacing;
		}
		DrawText(pDC, rect, hditem);
		break;
	}
}

INT CFlatHeaderCtrl::DrawImage(CDC* pDC, CRect rect, HDITEM hditem, BOOL bRight)
{
	CImageList* pImageList = GetImageList();
	INT iWidth = 0;

	if(hditem.fmt&HDF_IMAGE)
	{
		ASSERT(hditem.mask&HDI_IMAGE);
		ASSERT(pImageList);
		ASSERT(hditem.iImage>=0 && hditem.iImage<pImageList->GetImageCount());

		IMAGEINFO info;
		if(pImageList->GetImageInfo(hditem.iImage, &info))
		{
			iWidth = info.rcImage.right - info.rcImage.left;

			if(iWidth<=rect.Width() && rect.Width()>0)

⌨️ 快捷键说明

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