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

📄 theaderctrlex.cpp

📁 VC实现word 和ACCESS数据库的连接
💻 CPP
字号:
/************************************
  REVISION LOG ENTRY
  Revision By: Mihai Filimon
  Revised on 5/22/98 9:21:13 AM
  Comments: THeaderCtrlEx.cpp : implementation file
 ************************************/

#include "stdafx.h"
#include "THeaderCtrlEx.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTHeaderCtrlEx

#define ORDERCOLUMN(b) ((BOOL)LOBYTE(b))
#define POSITIONCOLUMN(b) ((int)HIBYTE(b))


// Function name	: CTHeaderCtrlEx::CTHeaderCtrlEx
// Description	    : constructor
// Return type		: -
CTHeaderCtrlEx::CTHeaderCtrlEx()
{
	m_nLastPosition = 0;
}

// Function name	: CTHeaderCtrlEx::~CTHeaderCtrlEx
// Description	    : destructor
// Return type		: -
CTHeaderCtrlEx::~CTHeaderCtrlEx()
{
}


BEGIN_MESSAGE_MAP(CTHeaderCtrlEx, CHeaderCtrl)
	//{{AFX_MSG_MAP(CTHeaderCtrlEx)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTHeaderCtrlEx message handlers


// Function name	: CTHeaderCtrlEx::SignMoreSortColumns
// Description	    : Called from DrawItem, If position<4 will mark header columns with their respective positions
// Return type		: void 
// Argument         : CDC & dc
// Argument         : int nPosition
// Argument         : CRect& rectWhere
void CTHeaderCtrlEx::SignMoreSortColumns(CDC & dc, int nPosition,  CRect& rectWhere)
{
	if (nPosition < 4) 
	{
		const static dxSign = 1;
		const static dxSignDelay = 1;
		CRect sign = rectWhere;
		sign.right = sign.left + dxSign;
		sign.OffsetRect((rectWhere.Width() - (nPosition * dxSign + (nPosition - 1) * dxSignDelay)) / 2, 0);
		if (sign.left >=  rectWhere.left)
		{
			CBrush brush(RGB(0,0,0));
			for (int j = 0; j < nPosition; j++)
			{
				dc.FillRect(sign, &brush);
				sign.OffsetRect(dxSign + dxSignDelay, 0);
			}
		}
	}
}

// Function name	: CTHeaderCtrlEx::DrawItem
// Description	    : Call for ownerdraw item.
// Return type		: void 
// Argument         : LPDRAWITEMSTRUCT lpDrawItemStruct
void CTHeaderCtrlEx::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
	CDC dc;

	dc.Attach( lpDrawItemStruct->hDC );

	// Get the column rect
	CRect rcLabel( lpDrawItemStruct->rcItem );

	// Save DC
	int nSavedDC = dc.SaveDC();

	// Set clipping region to limit drawing within column
	CRgn rgn;
	rgn.CreateRectRgnIndirect( &rcLabel );
	dc.SelectObject( &rgn );
	rgn.DeleteObject();

	// Labels are offset by a certain amount  
	// This offset is related to the width of a space character
	int offset = dc.GetTextExtent(_T("X"), 1 ).cx * 1;


	// Get the column text and format
	TCHAR buf[256];
	HD_ITEM hditem;
	
	hditem.mask = HDI_TEXT | HDI_FORMAT;
	hditem.pszText = buf;
	hditem.cchTextMax = 255;

	GetItem( lpDrawItemStruct->itemID, &hditem );

	// Determine format for drawing column label
	UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER;

	if( hditem.fmt & HDF_CENTER)
		uFormat |= DT_CENTER;
	else if( hditem.fmt & HDF_RIGHT)
		uFormat |= DT_RIGHT;
	else
		uFormat |= DT_LEFT;

	// Adjust the rect if the mouse button is pressed on it
	if( lpDrawItemStruct->itemState == ODS_SELECTED )
	{
		rcLabel.left++;
		rcLabel.top += 2;
		rcLabel.right++;
	}

	BOOL bAsc = true;
	int nPosition = 0;
	BOOL bIsSortColumn = GetColumnOrder(lpDrawItemStruct->itemID, bAsc, nPosition);
	int dxRectArrow = bIsSortColumn ? 2*offset : 0;
	// Adjust the rect further if Sort arrow is to be displayed
	rcLabel.right -= dxRectArrow;

	rcLabel.left += offset;
	rcLabel.right -= offset;

	// Draw column label
	if( rcLabel.left < rcLabel.right )
		dc.DrawText(buf,-1,rcLabel, uFormat);

	// Draw the Sort arrow
	if( bIsSortColumn )
	{
		
		rcLabel.right += offset;
		CRect rectArrow = rcLabel;
		int dyRectArrow = (int)((double)rectArrow.Height() / 5 * 2);
		rectArrow.OffsetRect(0, (rectArrow.Height() - dyRectArrow) / 2);
		rectArrow.bottom = rectArrow.top + dyRectArrow;
		rectArrow.left = rcLabel.right;
		rectArrow.right = rectArrow.left + dyRectArrow;

		// Set up pens to use for drawing the triangle
		CPen penLight(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
		CPen penShadow(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
		CPen *pOldPen = dc.SelectObject( &penLight );
		CRect rectSign = rectArrow;

		if (rectSign.left > rcLabel.left)
		/* In this version do not exist SelectClipRgn, Wait for new version...*/
		{
			if (bAsc)
				for (int i = 0; i < 2; i++)
				{
					dc.MoveTo(rectArrow.TopLeft());
					dc.LineTo(rectArrow.right,rectArrow.top);
					dc.LineTo((rectArrow.left + rectArrow.right) / 2,rectArrow.bottom);
					dc.LineTo(rectArrow.TopLeft());
					dc.SelectObject( &penShadow );
					rectArrow.OffsetRect(-2,-1);
				}
			else
				for (int i = 0; i < 2; i++)
				{
					dc.MoveTo(rectArrow.left,rectArrow.bottom);
					dc.LineTo((rectArrow.left + rectArrow.right) / 2,rectArrow.top);
					dc.LineTo(rectArrow.BottomRight());
					dc.LineTo(rectArrow.left,rectArrow.bottom);
					dc.SelectObject( &penShadow );
					rectArrow.OffsetRect(-2,-1);
				}

		
				rectSign.left = (rectArrow.left + rectArrow.right) / 2 - offset;
				rectSign.right = rectSign.left + 2 * offset;
				rectSign.top = rectArrow.bottom;
				rectSign.bottom = rectSign.top + 4;

				if (m_mapSortColumns.GetCount() > 1)
					SignMoreSortColumns(dc, nPosition, rectSign);
		}

		// Restore the pen
		dc.SelectObject( pOldPen );
	}

	// Restore dc
	dc.RestoreDC( nSavedDC );

	// Detach the dc before returning
	dc.Detach();
}

// Function name	: CTHeaderCtrlEx::SetColumnFormat
// Description	    : Set or reset format of item iColumn from header
// Return type		: void 
// Argument         : int iColumn
// Argument         : int format
// Argument         : BOOL bOr
void CTHeaderCtrlEx::SetColumnFormat(int iColumn, int format, BOOL bOr)
{
	// Change the item to (not)owner drawn
	HD_ITEM hditem;
	hditem.mask = HDI_FORMAT;
	if (GetItem( iColumn, &hditem ))
	{
		hditem.fmt = bOr ? hditem.fmt | format : hditem.fmt & ~format;
		SetItem( iColumn, &hditem );
	}
}

// Function name	: CTHeaderCtrlEx::GetPositionColumn
// Description	    : 
// Return type		: BOOL ; Return TRUE, if exist sort column with position nPosition
// Argument         : int nPosition
// Argument         : BOOL & bAsc ; Set bAsc and nColumn with sort column found.
// Argument         : int & nColumn
BOOL CTHeaderCtrlEx::GetPositionColumn(int nPosition, BOOL & bAsc, int & nColumn) const
{
	POSITION position = m_mapSortColumns.GetStartPosition();
	while (position)
	{
		WORD value;
		m_mapSortColumns.GetNextAssoc(position, nColumn, value);
		if (POSITIONCOLUMN(value) == nPosition)
		{
			bAsc = ORDERCOLUMN(value);
			return TRUE;
		}
	}
	return FALSE;
}

// Function name	: CTHeaderCtrlEx::GetColumnOrder
// Description	    : 
// Return type		: BOOL ; Return TRUE if sort column nColumn exist
// Argument         : int nColumn 
// Argument         : BOOL & bAsc ; sort column found
// Argument         : int& nPosition
BOOL CTHeaderCtrlEx::GetColumnOrder(int nColumn, BOOL & bAsc, int& nPosition) const
{
	WORD value;
	BOOL result = m_mapSortColumns.Lookup(nColumn, value);
	if (result)
	{
		bAsc = ORDERCOLUMN(value);
		nPosition = POSITIONCOLUMN(value);
	}
	return result;
}

// Function name	: CTHeaderCtrlEx::SetColumnOrder
// Description	    : Set column iColumn as sort column ascending or descending
// Return type		: BOOL ; always TRUE for now
// Argument         : int iColumn ; column to set
// Argument         : BOOL bAsc ; sorting direction: ascendent or descendent
BOOL CTHeaderCtrlEx::SetColumnOrder(int iColumn, BOOL bAsc)
{
	BYTE position = NULL;
	WORD value = NULL;
	if (m_mapSortColumns.Lookup(iColumn, value))
		position = POSITIONCOLUMN(value);
	else
		position = ++m_nLastPosition;

	m_mapSortColumns[iColumn] = MAKEWORD(bAsc, position);
	SetColumnFormat(iColumn, HDF_OWNERDRAW, SET);

	// Invalidate header control so that it gets redrawn
	Invalidate();
	return TRUE;
}

// Function name	: CTHeaderCtrlEx::DeleteColumnOrder
// Description	    : Delete sort column iColumn
// Return type		: void 
// Argument         : int iColumn ; column number
void CTHeaderCtrlEx::DeleteColumnOrder(int iColumn)
{
	SetColumnFormat(iColumn, HDF_OWNERDRAW, REMOVE);
	BOOL bAscRemove; int nPositionRemove;
	if (GetColumnOrder(iColumn, bAscRemove, nPositionRemove))
	{
		m_mapSortColumns.RemoveKey(iColumn);
		POSITION position = m_mapSortColumns.GetStartPosition();
		while (position)
		{
			WORD value;
			int column;
			m_mapSortColumns.GetNextAssoc(position, column, value);
			if (POSITIONCOLUMN(value) > nPositionRemove)
				m_mapSortColumns[column] = MAKEWORD(ORDERCOLUMN(value),POSITIONCOLUMN(value) - 1);
		}
		m_nLastPosition--;
		Invalidate();
	}
}

// Function name	: CTHeaderCtrlEx::ResetSortColumns
// Description	    : Remove all sort columns
// Return type		: void 
// Argument         : BOOL bInvalidate ; If TRUE force to invalidate header
void CTHeaderCtrlEx::ResetSortColumns(BOOL bInvalidate)
{
	m_mapSortColumns.RemoveAll();
	m_nLastPosition = 0;
	for (int i = 0; i < GetItemCount(); i++)
		SetColumnFormat(i,HDF_OWNERDRAW, REMOVE );
	if (bInvalidate)
		Invalidate();
}

⌨️ 快捷键说明

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