Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1609391
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2011-08-27 13:53:43

 当利用业余时间开发完成纷飞(Outplay...)一个类似Outlook的客户端的邮件程序后 , 发现Outlook的新邮件的显示使用单列不同的颜色,酷酷的,于是决定,也该让我的 Outplay如此...

        说做就做,就立刻查找了codeguru里的关于CTreeView的文章,找到了一些合适的信息,大概花了30分钟的时间,终于让我的纷飞(Outplay...)也酷了一把。
        Follow me,你会发现它是如此的简单和便捷,仅仅需要在你的CTreeView中添加几行代码而已。

        该怎么做呢?(as below)
        首先假定你的CTreeView派生类CTreeViewEx,然后你需要在TreeViewEx.h中,添加如下行:

        afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);

        然后你需要在消息映射中添加:

        ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)

        在OnCusteomDraw消息处理例程中添加如下代码:

        void CLeftView::OnCustomDraw(LPNMHDR pNmhdr, LRESULT* pResult) 
        { 
                static CRect rcItem; 
                static int nItemState; 
                LPNMTVCUSTOMDRAW pCustomDraw = (LPNMTVCUSTOMDRAW)pNmhdr; 
                switch (pCustomDraw->nmcd.dwDrawStage) 
                { 
                        case CDDS_PREPAINT: 
                                // 这种情况必须处理,且必须将pResult设置为 CDRF_NOTIFYITEMDRAW, 
                                // 否则父窗口怎么也收不到 CDDS_ITEMPREPAINT 通知消息 (GGH) 
                                *pResult = CDRF_NOTIFYITEMDRAW; 
                                // 重新定位视图窗口,这样 TreeCtrl 的 DefWindowProc 不会重画 
                                //::SetViewportOrgEx(pCustomDraw->nmcd.hdc, /*m_nOffset*/0, 0, NULL); 
                                break; 
                        case CDDS_ITEMPREPAINT: 
                                // 设置背景和前景颜色 
                                nItemState = pCustomDraw->nmcd.uItemState; 
                                pCustomDraw->nmcd.uItemState &= ~CDIS_FOCUS; 
                                pCustomDraw->clrText = m_colHilightText; 
                                // 记住绘制项目的矩形 
                                m_pTree->GetItemRect((HTREEITEM) pCustomDraw->nmcd.dwItemSpec, &rcItem, TRUE); 
                                *pResult = CDRF_NOTIFYPOSTPAINT; 
                                        break; 
                        case CDDS_ITEMPOSTPAINT: 
                                DrawTreeItem(nItemState, rcItem, pCustomDraw->nmcd.hdc, (HTREEITEM) pCustomDraw->nmcd.dwItemSpec); 
                                break; 
                        default: 
                                *pResult = CDRF_DODEFAULT; 
                } 
        }

        最后你需要做的只是在DrawTreeItem中自绘你想要的得效果就是了如下:

        void CLeftView::DrawTreeItem(int nItemState, CRect rcItem, HDC hdc, HTREEITEM hItem) 
        { 
                // 如果此项获得输入焦点,则绘制外围矩形并用蓝色填充矩形区域 
                COLORREF colText = m_colText; 
                if(nItemState & CDIS_FOCUS) 
                { 
                        ::FillRect(hdc, &rcItem, (HBRUSH)m_BackBrush.m_hObject); 
                        // 新的焦点矩形代码...... 
                        ::DrawFocusRect( hdc, &rcItem); 
                        colText = m_colHilightText; 
                } 
                else if(nItemState & CDIS_SELECTED) 
                { 
                        ::FillRect(hdc, &rcItem, (HBRUSH)m_GrayBrush.m_hObject); 
                } 
                else 
                { 
                        TRACE("CLEAR HIGH\n"); 
                        // 清除剩余的高亮条 
                        ::FillRect(hdc, &rcItem, (HBRUSH)m_BackBrushNormal.m_hObject); 
                } 
                // 总是要写没有背景的文本 
                ::SetBkMode(hdc, TRANSPARENT); 
                ::SetTextColor(hdc,colText); 
                CString str = m_pTree->GetItemText(hItem); 
                ::DrawText(hdc, str, -1, &rcItem, DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS); 
                int nNew = 20; 
                CString strNew = _T(""); 
                strNew.Format(_T("(%d)"),nNew); 
                ::SetTextColor(hdc,RGB(0,0,255)); 
                RECT rc = rcItem; 
                rc.left = rcItem.right+2; 
                rc.right = rc.left + 100; 
                ::FillRect(hdc, &rc, (HBRUSH)m_BackBrushNormal.m_hObject); 
                ::DrawText(hdc,strNew, -1, &rc, DT_VCENTER | DT_SINGLELINE | DT_WORD_ELLIPSIS); 
        }

        需要说明的是如果你想支持拖放,那么你必需要做一些修改......

阅读(686) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~