📄 flatheaderctrl.cpp
字号:
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:
iWidth = DrawImage(pDC, rect, hditem, FALSE);
if (iWidth)
rect.left += (iWidth + m_iSpacing);
// if (hditem.fmt & HDF_IMAGE && !iWidth)
// break;
if (bSort)
rect.right -= m_iSpacing + m_sizeArrow.cx;
iWidth = DrawText(pDC, rect, hditem);
if (iWidth)
rect.left += (iWidth + m_iSpacing);
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:
iWidth = DrawImage(pDC, rect, hditem, FALSE);
if (iWidth)
rect.left += (iWidth + m_iSpacing);
// if (hditem.fmt & HDF_IMAGE && !iWidth)
// break;
if (bSort)
rect.left += (m_iSpacing + m_sizeArrow.cx);
iWidth = DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, TRUE);
if (iWidth)
rect.right -= (iWidth + m_iSpacing);
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))
{
iWidth = DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, FALSE);
if (iWidth)
rect.left += (iWidth + m_iSpacing);
}
iWidth = DrawImage(pDC, rect, hditem, FALSE);
if (iWidth)
rect.left += (iWidth + m_iSpacing);
// if (hditem.fmt & HDF_IMAGE && !iWidth)
// break;
if (bSort && hditem.fmt & HDF_BITMAP_ON_RIGHT)
rect.left += (m_iSpacing + m_sizeArrow.cx);
if (hditem.fmt & HDF_BITMAP_ON_RIGHT)
{
iWidth = DrawBitmap(pDC, rect, hditem, pBitmap, &BitmapInfo, TRUE);
if (iWidth)
rect.right -= (iWidth + m_iSpacing);
}
if (bSort)
{
if (hditem.fmt & HDF_BITMAP_ON_RIGHT)
rect.left -= (m_iSpacing + m_sizeArrow.cx);
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)
{
POINT point;
point.y = rect.CenterPoint().y - ((info.rcImage.bottom - info.rcImage.top) >> 1);
if (bRight)
point.x = rect.right - iWidth;
else
point.x = rect.left;
pImageList->Draw(pDC, hditem.iImage, point, ILD_NORMAL);
}
else
iWidth = 0;
}
}
return iWidth;
}
INT CFlatHeaderCtrl::DrawBitmap(CDC* pDC, CRect rect, HDITEM /*hditem*/, CBitmap* pBitmap, BITMAP* pBitmapInfo, BOOL bRight)
{
INT iWidth = 0;
if (pBitmap)
{
iWidth = pBitmapInfo->bmWidth;
if (iWidth <= rect.Width() && rect.Width() > 0)
{
POINT point;
point.y = rect.CenterPoint().y - (pBitmapInfo->bmHeight >> 1);
if (bRight)
point.x = rect.right - iWidth;
else
point.x = rect.left;
CDC dc;
if (dc.CreateCompatibleDC(pDC))
{
VERIFY(dc.SelectObject(pBitmap));
if (!pDC->BitBlt(point.x, point.y,
pBitmapInfo->bmWidth,
pBitmapInfo->bmHeight,
&dc, 0, 0, SRCCOPY))
{
iWidth = 0;
}
}
else
iWidth = 0;
}
else
iWidth = 0;
}
return iWidth;
}
INT CFlatHeaderCtrl::DrawText(CDC* pDC, CRect rect, HDITEM hditem)
{
CSize size;
if (rect.Width() > 0 && hditem.mask & HDI_TEXT && hditem.fmt & HDF_STRING)
{
size = pDC->GetTextExtent(hditem.pszText);
switch (hditem.fmt & HDF_JUSTIFYMASK)
{
case HDF_LEFT:
case HDF_LEFT | HDF_RTLREADING:
pDC->DrawText(hditem.pszText, -1, rect, DT_LEFT | DT_END_ELLIPSIS |
DT_SINGLELINE | DT_VCENTER);
break;
case HDF_CENTER:
case HDF_CENTER | HDF_RTLREADING:
pDC->DrawText(hditem.pszText, -1, rect, DT_CENTER | DT_END_ELLIPSIS |
DT_SINGLELINE | DT_VCENTER);
break;
case HDF_RIGHT:
case HDF_RIGHT | HDF_RTLREADING:
pDC->DrawText(hditem.pszText, -1, rect, DT_RIGHT | DT_END_ELLIPSIS |
DT_SINGLELINE | DT_VCENTER);
break;
}
}
size.cx = (rect.Width() > size.cx) ? size.cx : rect.Width();
return ((size.cx > 0) ? size.cx : 0);
}
INT CFlatHeaderCtrl::DrawArrow(CDC* pDC, CRect rect, BOOL bSortAscending, BOOL bRight)
{
INT iWidth = 0;
if (rect.Width() > 0 && m_sizeArrow.cx <= rect.Width())
{
iWidth = m_sizeArrow.cx;
rect.top += (rect.Height() - m_sizeArrow.cy - 1) >> 1;
rect.bottom = rect.top + m_sizeArrow.cy - 1;
rect.left = bRight ? (rect.right - m_sizeArrow.cy) : rect.left;
// Set up pens to use for drawing the triangle
CPen penLight(PS_SOLID, 1, m_cr3DHighLight);
CPen penShadow(PS_SOLID, 1, m_cr3DShadow);
CPen *pPen = pDC->SelectObject(&penLight);
if (bSortAscending)
{
// Draw triangle pointing upwards
pDC->MoveTo(rect.left + ((m_sizeArrow.cx - 1) >> 1) + 1, rect.top);
pDC->LineTo(rect.left + (m_sizeArrow.cx - 1), rect.top + m_sizeArrow.cy - 1);
pDC->LineTo(rect.left, rect.top + m_sizeArrow.cy - 1);
pDC->SelectObject(&penShadow);
pDC->MoveTo(rect.left + ((m_sizeArrow.cx - 1) >> 1), rect.top);
pDC->LineTo(rect.left, rect.top + m_sizeArrow.cy - 1);
}
else
{
// Draw triangle pointing downwards
pDC->MoveTo(rect.left + ((m_sizeArrow.cx - 1) >> 1) + 1, rect.top + m_sizeArrow.cy - 1);
pDC->LineTo(rect.left + (m_sizeArrow.cx - 1), rect.top);
pDC->SelectObject(&penShadow);
pDC->MoveTo(rect.left + ((m_sizeArrow.cx - 1) >> 1), rect.top + m_sizeArrow.cy - 1);
pDC->LineTo(rect.left, rect.top);
pDC->LineTo(rect.left + m_sizeArrow.cx, rect.top);
}
// Restore the pen
pDC->SelectObject(pPen);
}
return iWidth;
}
/////////////////////////////////////////////////////////////////////////////
// CHeaderCtrl message handlers
LRESULT CFlatHeaderCtrl::OnInsertItem(WPARAM wParam, LPARAM /*lParam*/)
{
HDITEMEX hditemex;
hditemex.m_iMinWidth = 0;
hditemex.m_iMaxWidth = -1;
ASSERT((INT)wParam <= m_arrayHdrItemEx.GetSize());
m_arrayHdrItemEx.InsertAt(wParam, hditemex);
return Default();
}
LRESULT CFlatHeaderCtrl::OnDeleteItem(WPARAM wParam, LPARAM /*lParam*/)
{
ASSERT((INT)wParam < m_arrayHdrItemEx.GetSize());
m_arrayHdrItemEx.RemoveAt(wParam);
return Default();
}
LRESULT CFlatHeaderCtrl::OnSetHotDivider(WPARAM wParam, LPARAM lParam)
{
if (wParam)
{
HDHITTESTINFO hdhti;
hdhti.pt.x = LOWORD(lParam);
hdhti.pt.y = HIWORD(lParam);
ScreenToClient(&hdhti.pt);
m_iHotDivider = SendMessage(HDM_HITTEST, 0, (LPARAM)(&hdhti));
if (m_iHotDivider >= 0)
{
CRect rectItem;
VERIFY(GetItemRect(m_iHotDivider, rectItem));
if (hdhti.pt.x > rectItem.CenterPoint().x)
m_iHotDivider++;
}
}
else
m_iHotDivider = (INT)lParam;
Invalidate();
return (LRESULT)m_iHotDivider;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -