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

📄 flatheaderctrl.cpp

📁 版本更新了一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:

        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 + -