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

📄 flatheaderctrl.cpp

📁 版本更新了一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////
//  File:       CFlatHeaderCtrl.cpp
//  Version:    1.0.1.0
//
//  Author:     Maarten Hoeben
//  E-mail:     hoeben@nwn.com
//
//  Implementation of the CFlatHeaderCtrl and associated classes.
//
//  You are free to use, distribute or modify this code
//  as long as the header is not removed or modified.
//
//  Version history
//
//  1.0.0.1 - Initial release
//  1.0.1.0 - Fixed FHDragWnd destroy warning (thanks Philippe Terrier)
//          - Fixed double sent HDN_ITEMCLICK
//          - Added a property that adjusts for ListCtrls that use a static
//            border for flat look.
//  ?       - Fixed some problems with resizing (sami@tolvanen.com). See below.
//
////////////////////////////////////////////////////////////////////////////


// FlatHeaderCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "FlatHeaderCtrl.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFHDragWnd

CFHDragWnd::CFHDragWnd()
{
    // Register the window class if it has not already been registered.
    WNDCLASS wndclass;
    HINSTANCE hInst = AfxGetInstanceHandle();

    if (!(::GetClassInfo(hInst, FHDRAGWND_CLASSNAME, &wndclass)))
    {
        // otherwise we need to register a new class
        wndclass.style          = CS_SAVEBITS ;
        wndclass.lpfnWndProc    = ::DefWindowProc;
        wndclass.cbClsExtra     = wndclass.cbWndExtra = 0;
        wndclass.hInstance      = hInst;
        wndclass.hIcon          = NULL;
        wndclass.hCursor        = LoadCursor(hInst, IDC_ARROW);
        wndclass.hbrBackground  = (HBRUSH)(COLOR_3DFACE + 1);
        wndclass.lpszMenuName   = NULL;
        wndclass.lpszClassName  = FHDRAGWND_CLASSNAME;

        if (!AfxRegisterClass(&wndclass))
            AfxThrowResourceException();
    }
}

CFHDragWnd::~CFHDragWnd()
{
}


BEGIN_MESSAGE_MAP(CFHDragWnd, CWnd)
    //{{AFX_MSG_MAP(CFHDragWnd)
    ON_WM_PAINT()
    ON_WM_ERASEBKGND()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CFHDragWnd message handlers

BOOL CFHDragWnd::Create(CRect rect, CFlatHeaderCtrl* pFlatHeaderCtrl, INT iItem)
{
    ASSERT_VALID(pFlatHeaderCtrl);
    ASSERT(pFlatHeaderCtrl->IsKindOf(RUNTIME_CLASS(CFlatHeaderCtrl)));

    m_pFlatHeaderCtrl = pFlatHeaderCtrl;
    m_iItem = iItem;

    DWORD dwStyle = WS_POPUP|WS_DISABLED;
    DWORD dwExStyle = WS_EX_TOPMOST|WS_EX_TOOLWINDOW ;

    return CreateEx(dwExStyle, FHDRAGWND_CLASSNAME, NULL, dwStyle,
                    rect.left, rect.top, rect.Width(), rect.Height(),
                    NULL, NULL, NULL);
}


void CFHDragWnd::OnPaint()
{
    CPaintDC dc(this);

    /*if (m_pFlatHeaderCtrl->m_bNoFlicker)
    {*/
        CMemDC MemDC(&dc);
        OnDraw(&MemDC);
    /*}
    else
        OnDraw(&dc);*/
}

BOOL CFHDragWnd::OnEraseBkgnd(CDC* /*pDC*/)
{
    return TRUE;
}

void CFHDragWnd::OnDraw(CDC* pDC)
{
    CRect rect;
    GetClientRect(rect);

    pDC->FillSolidRect(rect, m_pFlatHeaderCtrl->m_cr3DFace);
    pDC->Draw3dRect(rect, m_pFlatHeaderCtrl->m_cr3DHighLight, m_pFlatHeaderCtrl->m_cr3DShadow);

    CPen* pPen = pDC->GetCurrentPen();
    CFont* pFont = pDC->SelectObject(m_pFlatHeaderCtrl->GetFont());

    pDC->SetBkColor(m_pFlatHeaderCtrl->m_cr3DFace);
    pDC->SetTextColor(m_pFlatHeaderCtrl->m_crText);

    rect.DeflateRect(m_pFlatHeaderCtrl->m_iSpacing, 0);
    m_pFlatHeaderCtrl->DrawItem(pDC, rect,
                                m_pFlatHeaderCtrl->m_hditemHotItem,
                                (m_pFlatHeaderCtrl->m_iSortColumn == m_iItem),
                                m_pFlatHeaderCtrl->m_bSortAscending);

    pDC->SelectObject(pFont);
    pDC->SelectObject(pPen);
}

void CFHDragWnd::PostNcDestroy()
{
    CWnd::PostNcDestroy();
    delete this;
}

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl

IMPLEMENT_DYNCREATE(CFlatHeaderCtrl, CHeaderCtrl)

CFlatHeaderCtrl::CFlatHeaderCtrl()
{
//  m_bNoFlicker        = TRUE;
    m_iSpacing          = 6;
    m_sizeArrow.cx      = 8;
    m_sizeArrow.cy      = 8;
    m_bStaticBorder     = FALSE;

    m_iHotIndex         = -1;
    m_bHotItemResizable = TRUE;

    m_bResizing         = FALSE;

    m_iHotDivider       = -1;
    m_crHotDivider      = 0x000000FF;

    m_bDragging         = FALSE;
    m_pDragWnd          = NULL;

    m_nClickFlags       = 0;

    m_bSortAscending    = FALSE;
    m_iSortColumn       = -1;
    m_arrayHdrItemEx.SetSize(0, 8);

    m_cr3DHighLight     = ::GetSysColor(COLOR_3DHIGHLIGHT);
    m_cr3DShadow        = ::GetSysColor(COLOR_3DSHADOW);
    m_cr3DFace          = ::GetSysColor(COLOR_3DFACE);
    m_crText            = ::GetSysColor(COLOR_BTNTEXT);
}

CFlatHeaderCtrl::~CFlatHeaderCtrl()
{
    if (m_pDragWnd != NULL)
    {
        m_pDragWnd->DestroyWindow();
        m_pDragWnd = NULL;
    }
}
#if _MFC_VER == 0x0800 
//Hack for VS beta version
#undef ON_WM_NCHITTEST
#define ON_WM_NCHITTEST() \
{ WM_NCHITTEST, 0, 0, 0, AfxSig_l_p, \
	(AFX_PMSG)(AFX_PMSGW) \
	(static_cast< UINT (AFX_MSG_CALL CWnd::*)(CPoint) > (&ThisClass :: OnNcHitTest)) },
#endif
BEGIN_MESSAGE_MAP(CFlatHeaderCtrl, CHeaderCtrl)
    //{{AFX_MSG_MAP(CFlatHeaderCtrl)
    ON_MESSAGE(HDM_INSERTITEMA, OnInsertItem)
    ON_MESSAGE(HDM_INSERTITEMW, OnInsertItem)
    ON_MESSAGE(HDM_DELETEITEM, OnDeleteItem)
    ON_MESSAGE(HDM_SETHOTDIVIDER, OnSetHotDivider)
    ON_MESSAGE(HDM_LAYOUT, OnLayout)
    ON_WM_NCHITTEST()
    ON_WM_SETCURSOR()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONDBLCLK()
    ON_WM_PAINT()
    ON_WM_SYSCOLORCHANGE()
    ON_WM_ERASEBKGND()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl attributes

BOOL CFlatHeaderCtrl::ModifyProperty(WPARAM wParam, LPARAM lParam)
{
    switch (wParam)
    {
    case FH_PROPERTY_SPACING:
        m_iSpacing = (INT)lParam;
        break;
    case FH_PROPERTY_ARROW:
        m_sizeArrow.cx = LOWORD(lParam);
        m_sizeArrow.cy = HIWORD(lParam);
        break;
    case FH_PROPERTY_STATICBORDER:
        m_bStaticBorder = (BOOL)lParam;
        break;
    default:
        return FALSE;
    }

    Invalidate();
    return TRUE;
}

BOOL CFlatHeaderCtrl::GetItemEx(INT iPos, HDITEMEX* phditemex) const
{
    if (iPos >= m_arrayHdrItemEx.GetSize())
        return FALSE;

    *phditemex = m_arrayHdrItemEx[iPos];
    return TRUE;
}

BOOL CFlatHeaderCtrl::SetItemEx(INT iPos, HDITEMEX* phditemex)
{
    if (iPos >= m_arrayHdrItemEx.GetSize())
        return FALSE;

    if (phditemex->m_iMinWidth <= phditemex->m_iMaxWidth)
    {
        HDITEM hditem;
        hditem.mask = HDI_WIDTH;

        if (!GetItem(iPos, &hditem))
            return FALSE;

        if (hditem.cxy < phditemex->m_iMinWidth)
            hditem.cxy = phditemex->m_iMinWidth;

        if (hditem.cxy > phditemex->m_iMaxWidth)
            hditem.cxy = phditemex->m_iMaxWidth;

        SetItem(iPos, &hditem);
    }

    m_arrayHdrItemEx.SetAt(iPos, *phditemex);

    return TRUE;
}

void CFlatHeaderCtrl::SetSortColumn(INT iPos, BOOL bSortAscending)
{
    ASSERT(iPos < GetItemCount());

    m_bSortAscending = bSortAscending;
    m_iSortColumn = iPos;

    Invalidate();
}

INT CFlatHeaderCtrl::GetSortColumn(BOOL* pbSortAscending /*= NULL*/)
{
    if (pbSortAscending)
        *pbSortAscending = m_bSortAscending;

    return m_iSortColumn;
}

/////////////////////////////////////////////////////////////////////////////
// CFlatHeaderCtrl implementation

void CFlatHeaderCtrl::DrawCtrl(CDC* pDC)
{
    CRect rectClip;

    if (pDC->GetClipBox(&rectClip) == ERROR)
        return;

    CRect rectClient, rectItem;
    GetClientRect(&rectClient);

    pDC->FillSolidRect(rectClip, m_cr3DFace);

    INT iItems = GetItemCount();
    ASSERT(iItems >= 0);

    CPen penHighLight(PS_SOLID, 1, m_cr3DHighLight);
    CPen penShadow(PS_SOLID, 1, m_cr3DShadow);
    CPen* pPen = pDC->GetCurrentPen();

    CFont* pFont = pDC->SelectObject(GetFont());

    pDC->SetBkColor(m_cr3DFace);
    pDC->SetTextColor(m_crText);

    INT iWidth = 0;

    for (INT i = 0; i < iItems; i++)
    {
        INT iItem = OrderToIndex(i);

        TCHAR szText[FLATHEADER_TEXT_MAX];

        HDITEM hditem;
        hditem.mask         = HDI_WIDTH | HDI_FORMAT | HDI_TEXT | HDI_IMAGE | HDI_BITMAP;
        hditem.pszText      = szText;
        hditem.cchTextMax   = sizeof(szText);

        VERIFY(GetItem(iItem, &hditem));
        VERIFY(GetItemRect(iItem, rectItem));

        if (rectItem.right >= rectClip.left || rectItem.left <= rectClip.right)
        {
            if (hditem.fmt & HDF_OWNERDRAW)
            {
                DRAWITEMSTRUCT disItem;

                disItem.CtlType     = ODT_BUTTON;
                disItem.CtlID       = GetDlgCtrlID();
                disItem.itemID      = iItem;
                disItem.itemAction  = ODA_DRAWENTIRE;
                disItem.itemState   = 0;
                disItem.hwndItem    = m_hWnd;
                disItem.hDC         = pDC->m_hDC;
                disItem.rcItem      = rectItem;
                disItem.itemData    = 0;

                DrawItem(&disItem);
            }
            else
            {
                rectItem.DeflateRect(m_iSpacing, 0);
                DrawItem(pDC, rectItem, hditem, (iItem == m_iSortColumn), m_bSortAscending);
                rectItem.InflateRect(m_iSpacing, 0);

                if (m_nClickFlags & MK_LBUTTON &&
                    m_iHotIndex == iItem &&
                    m_hdhtiHotItem.flags & HHT_ONHEADER)
                {
                    pDC->InvertRect(rectItem);
                }
            }

            if (i < iItems-1)
            {
                pDC->SelectObject(&penShadow);
                pDC->MoveTo(rectItem.right - 1, rectItem.top + 2);
                pDC->LineTo(rectItem.right - 1, rectItem.bottom - 2);

                pDC->SelectObject(&penHighLight);
                pDC->MoveTo(rectItem.right, rectItem.top + 2);
                pDC->LineTo(rectItem.right, rectItem.bottom - 2);
            }
        }

⌨️ 快捷键说明

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