THeaderCtrlEx.cpp
上传用户:maicowu
上传日期:2007-01-02
资源大小:87k
文件大小:9k
- /************************************
- 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();
- }