#include "stdafx.h" #include "SortHeaderCtrl.h" CSortHeaderCtrl::CSortHeaderCtrl(): m_nSortColumn( -1 ), m_bSortAscending( TRUE ) { m_bPressMoused = FALSE; //m_clrColumText = RGB(255,255,255); //m_clr3DHighLight = RGB(220, 220, 220); //::GetSysColor(COLOR_3DHIGHLIGHT); //m_clr3DShadow = RGB(35, 35, 35); //::GetSysColor(COLOR_3DSHADOW); //m_clr3DFace = RGB(128, 128, 128); //::GetSysColor(COLOR_3DFACE); m_clrColumText = RGB(7,30,129); m_clr3DHighLight = RGB(107, 201, 255); //::GetSysColor(COLOR_3DHIGHLIGHT); m_clr3DShadow = RGB(37, 121, 176); //::GetSysColor(COLOR_3DSHADOW); m_clr3DFace = RGB(105, 201, 255); //::GetSysColor(COLOR_3DFACE); } CSortHeaderCtrl::~CSortHeaderCtrl() { } BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl) ON_WM_PAINT() ON_WM_ERASEBKGND() END_MESSAGE_MAP() /************************************************************************/ /* 函数:SetSortArrow[10/20/2016 IT]; /* 描述:设置要排序的列以及排序方式(升序或降序); /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void CSortHeaderCtrl::SetSortArrow( IN const int nSortColumn, IN const BOOL bSortAscending ) { m_nSortColumn = nSortColumn; m_bSortAscending = bSortAscending; // 设置项自绘风格; HD_ITEM hditem; hditem.mask = HDI_FORMAT; // 获取列信息; VERIFY( GetItem( nSortColumn, &hditem ) ); // 设置自绘风格; hditem.fmt |= HDF_OWNERDRAW; // 设置列信息; VERIFY( SetItem( nSortColumn, &hditem ) ); // 更新表头以便重绘; Invalidate(); } BOOL CSortHeaderCtrl::OnEraseBkgnd(CDC* pDC) { return TRUE; } void CSortHeaderCtrl::OnPaint() { CPaintDC dc(this); // device context for painting int nItems = GetItemCount(); ASSERT(nItems >= 0); dc.SetBkColor(m_clr3DFace); dc.SetTextColor(m_clrColumText); CRect rectClip; if (dc.GetClipBox(&rectClip) == ERROR) return; dc.FillSolidRect(rectClip, m_clr3DFace); // 获取当前鼠标位置; POINT point; GetCursorPos(&point); ScreenToClient(&point); CRect rectItem; for(int i = 0; i < nItems; i++) { TCHAR szText[256]; HD_ITEM hditem; hditem.mask = HDI_TEXT | HDI_FORMAT | HDI_ORDER; hditem.pszText = szText; hditem.cchTextMax = 255; GetItem( i, &hditem ); DRAWITEMSTRUCT DrawItemStruct; GetItemRect(i, &rectItem); DrawItemStruct.CtlType = ODT_BUTTON; DrawItemStruct.hDC = dc.GetSafeHdc(); DrawItemStruct.itemAction = ODA_DRAWENTIRE; DrawItemStruct.hwndItem = GetSafeHwnd(); DrawItemStruct.rcItem = rectItem; DrawItemStruct.itemID = i; if ( rectItem.PtInRect(point) && m_bPressMoused ) DrawItemStruct.itemState = ODS_SELECTED; DrawItemEx(&DrawItemStruct); } } /************************************************************************/ /* 函数:DrawItemEx[10/19/2016 IT]; /* 描述:自绘函数; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void CSortHeaderCtrl::DrawItemEx( IN LPDRAWITEMSTRUCT lpDrawItemStruct ) { // 定义设备上下文; CDC dc; // 附加设备上下文句柄; VERIFY( dc.Attach( lpDrawItemStruct->hDC ) ); // 保存设备上下文; const int nSavedDC = dc.SaveDC(); // 获取当前列区域; CRect rc( lpDrawItemStruct->rcItem ); // 实现列单元格3D效果; dc.Draw3dRect(rc, m_clr3DHighLight, m_clr3DShadow); rc.InflateRect(-1,-1); dc.FillSolidRect(rc, m_clr3DFace); dc.SetBkMode(TRANSPARENT); // 设置文本颜色; dc.SetTextColor(m_clrColumText); // 恢复原大小; rc = lpDrawItemStruct->rcItem; // 获取当前的列的项目信息; TCHAR szText[ 256 ]; HD_ITEM hditem; hditem.mask = HDI_TEXT | HDI_FORMAT; hditem.pszText = szText; hditem.cchTextMax = 255; VERIFY( GetItem( lpDrawItemStruct->itemID, &hditem ) ); // 设置列的文本绘制格式; UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ; if( hditem.fmt & HDF_CENTER) uFormat |= DT_CENTER; else if( hditem.fmt & HDF_RIGHT) uFormat |= DT_RIGHT; else uFormat |= DT_LEFT; // 如果鼠标在列区域按下,则重新调整列区域; if( lpDrawItemStruct->itemState == ODS_SELECTED ) { rc.left++; rc.top += 2; rc.right++; // 释放鼠标按下标志; m_bPressMoused = FALSE; } // 箭头图标区域(rcIcon); CRect rcIcon( lpDrawItemStruct->rcItem ); const int nOffset = ( rcIcon.bottom - rcIcon.top ) / 4; // adjust the rect further if the sort arrow is to be displayed. if( lpDrawItemStruct->itemID == (UINT)m_nSortColumn ) rc.right -= 3 * nOffset; rc.left += nOffset; rc.right -= nOffset; // 绘制列文本; if( rc.left < rc.right ) dc.DrawText( szText, -1, rc, uFormat ); // 绘制排序箭头; if( lpDrawItemStruct->itemID == (UINT)m_nSortColumn ) { // 定义绘制箭头的画笔; CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) ); CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) ); CPen* pOldPen = dc.SelectObject( &penLight ); if( m_bSortAscending ) { // 绘制向上的箭头; dc.MoveTo( rcIcon.right - 2 * nOffset, nOffset); dc.LineTo( rcIcon.right - nOffset, rcIcon.bottom - nOffset - 1 ); dc.LineTo( rcIcon.right - 3 * nOffset - 2, rcIcon.bottom - nOffset - 1 ); dc.SelectObject( &penShadow ); dc.MoveTo( rcIcon.right - 3 * nOffset - 1, rcIcon.bottom - nOffset - 1 ); dc.LineTo( rcIcon.right - 2 * nOffset, nOffset - 1); } else { // 绘制向下的箭头; dc.MoveTo( rcIcon.right - nOffset - 1, nOffset ); dc.LineTo( rcIcon.right - 2 * nOffset - 1, rcIcon.bottom - nOffset ); dc.SelectObject( &penShadow ); dc.MoveTo( rcIcon.right - 2 * nOffset - 2, rcIcon.bottom - nOffset ); dc.LineTo( rcIcon.right - 3 * nOffset - 1, nOffset ); dc.LineTo( rcIcon.right - nOffset - 1, nOffset ); } // 恢复原来选择的画笔; dc.SelectObject( pOldPen ); } // 恢复之前的设备上下文; VERIFY( dc.RestoreDC( nSavedDC ) ); // 返回之前,分离设备上下文句柄; dc.Detach(); } /************************************************************************/ /* 函数:[10/20/2016 IT]; /* 描述:; /* 参数:; /* [IN] :; /* [OUT] :; /* [IN/OUT] :; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void CSortHeaderCtrl::Serialize( CArchive& ar ) { try { if( ar.IsStoring() ) { const int nItemCount = GetItemCount(); if( nItemCount != -1 ) { ar << nItemCount; HD_ITEM hdItem = { 0 }; hdItem.mask = HDI_WIDTH | HDI_ORDER; for( int i = 0; i < nItemCount; i++ ) { VERIFY( GetItem( i, &hdItem ) ); ar << hdItem.cxy; ar << hdItem.iOrder; } } } else { int nItemCount; ar >> nItemCount; if( GetItemCount() != nItemCount ) TRACE( _T("Different number of columns in registry.") ); else { HD_ITEM hdItem = { 0 }; hdItem.mask = HDI_WIDTH | HDI_ORDER; for( int i = 0; i < nItemCount; i++ ) { ar >> hdItem.cxy; ar >> hdItem.iOrder; VERIFY( SetItem( i, &hdItem ) ); } } } } catch(...) { } } BOOL CSortHeaderCtrl::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 if ( pMsg->message == WM_LBUTTONDOWN ) { m_bPressMoused = TRUE; } return CHeaderCtrl::PreTranslateMessage(pMsg); } /************************************************************************/ /* 函数:SetTextFont[3/6/2017 Jeff]; /* 描述:设置文本字体; /* 参数:; /* [IN] nTextFontSize:字体大小; /* [IN] bBold:是否粗体; /* [IN] bItalic:是否斜体; /* [IN] strTextFontName:字体名称,如楷体; /* 返回:void; /* 注意:; /* 示例:; /* /* 修改:; /* 日期:; /* 内容:; /************************************************************************/ void CSortHeaderCtrl::SetListFont(IN CString strFontName, IN int nFontSize, IN BOOL bBold, IN BOOL bItalic) { LOGFONT lf; CClientDC dc(this); int dpy = GetDeviceCaps(dc, LOGPIXELSY); // Pixel per inch lf.lfHeight = -MulDiv(nFontSize, dpy, 72); lf.lfWeight = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; if (bBold) lf.lfWeight = FW_BLACK; else lf.lfWeight = FW_NORMAL; lf.lfItalic = bItalic; lf.lfUnderline = FALSE; lf.lfStrikeOut = 0; lf.lfCharSet = ANSI_CHARSET; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = DEFAULT_PITCH | FF_ROMAN; _tcscpy_s(lf.lfFaceName, strFontName); // 创建字体; //m_cfont = GetFont();// 局部变量会导致字体设置失败,必须是全局或成员变量; VERIFY(m_cfont.CreateFontIndirect(&lf)); // 选入字体; this->SetFont(&m_cfont); }