蜗牛的家
男儿当自强
posts - 48,  comments - 21,  trackbacks - 0
#pragma once

#ifndef MYPROPERTYSHEET_H
#define MYPROPERTYSHEET_H

#pragma warning(disable : 
4996)


class CMyPropertySheet : public CPropertySheet
{
    DECLARE_DYNAMIC(CMyPropertySheet)
public:
    CMyPropertySheet(UINT nIDCaption, CWnd
* pParentWnd = NULL, UINT iSelectPage = 0);
    CMyPropertySheet(LPCTSTR pszCaption, CWnd
* pParentWnd = NULL, UINT iSelectPage = 0);
    
void CMyPropertySheet::SetCurrentPage(int nPage);
    
virtual ~CMyPropertySheet();

protected:
    CImageList m_imgList;
    CListCtrl m_wndList;
    
int  m_nSelectedItem;
    
//列表的字体,大小不能超过列表项的高度
    CFont m_ftList;
    
    COLORREF m_clrTextBkSele ;
    COLORREF m_clrSeprator;
    COLORREF m_clrCaption;
    COLORREF m_clrSelected;

    LPTSTR m_szCaption;
    CRect m_rectPage;
    
static BOOL bMoved[4];

    DECLARE_MESSAGE_MAP()
public:
    
virtual BOOL OnInitDialog();

    afx_msg 
void OnPaint();
    afx_msg 
void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg 
void OnNMCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);    

    
int AddIcon(HICON icon);
    
//设置属性页标题的初始颜色
    void SetCaptionColor(const COLORREF clrCaption);
    
//设置列表控件分隔线的初始颜色
    void SetSepratorColor(const COLORREF clrSeprator);
    
//设置列表控件某项被选择时的背景色
    void SetSelectedColor(const COLORREF clrSelected);

    
void SetChildCaption(int nIndex, LPSTR strCaption);
    
void FlashCurCaption();

private:
    
void InitList(void);
    
void DrawCaption(CDC * pDC, const COLORREF clrCaption);
    
void DrawGradientLine(CDC* pDC, COLORREF clrLine, POINT ptStart, POINT ptEnd);
}
;


#endif
实现文件
// MyPropertySheet.cpp : 实现文件
//

#include 
"stdafx.h"
#include 
"PropertySheet.h"

BOOL CMyPropertySheet::bMoved[
4= {FALSE,FALSE,FALSE,FALSE};

#define CAPTION_TEXT_LENGTH 128
#define ITEM_TEXT_LENGTH    256

//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CMyPropertySheet, CPropertySheet)

CMyPropertySheet::CMyPropertySheet(UINT nIDCaption, CWnd
* pParentWnd, UINT iSelectPage)
    :CPropertySheet(nIDCaption, pParentWnd, iSelectPage), 
    m_nSelectedItem(iSelectPage), m_clrTextBkSele(RGB(
0,132,255)),m_clrSeprator(RGB(0,132,255)),
    m_clrCaption(RGB(
92,132,255))
{
    m_szCaption 
= new TCHAR[CAPTION_TEXT_LENGTH];

    
//默认16*16,32位色图标
    m_imgList.Create(16,16,ILC_COLOR32, 020);

    m_ftList.CreatePointFont(
90,_T("宋体"));

}


CMyPropertySheet::CMyPropertySheet(LPCTSTR pszCaption, CWnd
* pParentWnd, UINT iSelectPage)
    :CPropertySheet(pszCaption, pParentWnd, iSelectPage), 
    m_nSelectedItem(iSelectPage), m_clrTextBkSele(RGB(
0,132,255)),m_clrSeprator(RGB(0,132,255)),
    m_clrCaption(RGB(
92,132,255))
{
    m_szCaption 
= new TCHAR[CAPTION_TEXT_LENGTH];

    m_imgList.Create(
16,16,ILC_COLOR32, 020);
    m_ftList.CreatePointFont(
90,_T("宋体"));

}


CMyPropertySheet::
~CMyPropertySheet()
{
    
if (m_szCaption)
    
{
        delete []m_szCaption;
        m_szCaption 
= NULL;
    }

    
    m_imgList.DeleteImageList();
    m_ftList.DeleteObject();
}



BEGIN_MESSAGE_MAP(CMyPropertySheet, CPropertySheet)
    ON_WM_PAINT()
    ON_NOTIFY(NM_CLICK, 
0xFFFF, OnNMClick)
    ON_NOTIFY(NM_CUSTOMDRAW,
0xFFFF, OnNMCustomDraw)
    
END_MESSAGE_MAP()


// CMyPropertySheet 消息处理程序

BOOL CMyPropertySheet::OnInitDialog()
{
    
    BOOL bResult 
= CPropertySheet::OnInitDialog();    
 
    
//计算属性页的矩形,扩大属性表并将属性页其移至右侧
    CRect rect, rectPage, rectTab;
    GetPage(
0)->GetWindowRect(&rectPage);
    
    GetWindowRect(
&rect);
    rect.right 
+= 150;
    
    
int nWidth = rectPage.Width();
    rectPage.right 
= rect.right - 20
    rectPage.left 
= rect.right - nWidth;
    ScreenToClient(
&rectPage);
    m_rectPage 
= rectPage;
    MoveWindow(
&rect);
    GetPage(
0)->MoveWindow(&rectPage);
    
    
//隐藏属性页原来的TabControl
    CTabCtrl *pTab = GetTabControl() ;
    pTab
->GetWindowRect(&rectTab);
    ScreenToClient(
&rectTab);
    BOOL bSucceed 
= pTab->ShowWindow(SW_HIDE);
       ASSERT(bSucceed);

    
//创建列表控件并用一个CImageList对象与之关联
    bSucceed = m_wndList.Create(WS_CHILD | WS_VISIBLE |  LVS_REPORT | LVS_NOCOLUMNHEADER , 
        CRect(
10 ,rectTab.top,150,rectPage.bottom ),this,0xFFFF);
    ASSERT(bSucceed);

    m_wndList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
    m_wndList.SetImageList(
&m_imgList, LVSIL_SMALL);
    
    InitList();

    
//这一步是为了扩大行高度
    CFont font;
    font.CreatePointFont(
240,_T("宋体"));
    m_wndList.SetFont(
&font);
    DeleteObject(
&font);

    CString strCaption;
    GetPage(
0)->GetWindowText(strCaption);    
    _tcscpy(m_szCaption, strCaption.GetBuffer(strCaption.GetLength()));    


    
return bResult;
}


void CMyPropertySheet::OnPaint()
{
    CPaintDC dc(
this); // device context for painting
    CRect rectList,rectPage;
    m_wndList.GetWindowRect(
&rectList);
    GetPage(
0)->GetWindowRect(&rectPage);
    ScreenToClient(
&rectPage);
    ScreenToClient(
&rectList);

    rectList.left 
-= -1;
    rectList.right 
+= 1;
    rectList.top 
-= 1;
    rectList.bottom 
+= 1;

    rectPage.left 
-= 1;
    rectPage.right 
+= 1;
    rectPage.top 
-= 1;
    rectPage.bottom 
+= 1;
    CBrush brush(RGB(
141,141,141));
    dc.FrameRect(
&rectList,&brush);
    dc.FrameRect(
&rectPage, &brush);
    
        
    DrawCaption(
&dc, m_clrCaption);    
}


void CMyPropertySheet::DrawCaption(CDC * pDC, const COLORREF clrCaption)
{
    CDC dcBuf; 
    dcBuf.CreateCompatibleDC(pDC);
    
    CRect rectCap, rectList, rectPage,rectSheet;
    m_wndList.GetWindowRect(
&rectList);
    ScreenToClient(
&rectList);
    GetPage(
0)->GetWindowRect(&rectPage);
    ScreenToClient(
&rectPage);

    rectCap 
= rectPage;
    rectCap.top 
= rectList.top -1;
    rectCap.left 
-= 1;
    rectCap.right 
+= 1;
    rectCap.bottom 
= rectPage.top -1 ;


    GetClientRect(
&rectSheet);
    
    rectCap.bottom 
+= 1;

    CBitmap bmp;
    bmp.CreateCompatibleBitmap(pDC, rectCap.right , rectSheet.Height());
    dcBuf.SelectObject(bmp);

    
//起始颜色
    int clrBBase = clrCaption>>16 & 0x000000FF;
    
int clrGBase = clrCaption>>8 & 0x000000FF;
    
int clrRBase = clrCaption & 0x000000FF;    

    
//过渡中颜色
    int clrRCurr = clrRBase;
    
int clrGCurr = clrGBase;
    
int clrBCurr = clrBBase;
    
    
//色彩增量
    const double nRClrInc = (double)(255 - clrRBase) / (double)rectCap.Width() ;    
    
const double nGClrInc = (double)(255 - clrGBase) / (double)rectCap.Width() ;
    
const double nBClrInc = (double)(255 - clrBBase) / (double)rectCap.Width() ;



    
//画渐进色标题

    CRect drawRect 
= rectCap;
    
    
for (int nLeft = rectCap.left, nRight = rectCap.left + 1 ; nLeft < rectCap.right; 
        nLeft 
++, nRight ++)
    
{

        drawRect.left 
= nLeft;
        drawRect.right 
= nRight;

        dcBuf.FillSolidRect(
&drawRect, RGB(clrRCurr,clrGCurr,clrBCurr));

        clrRCurr 
= (int)((nLeft - rectCap.left) * nRClrInc + clrRBase);
        clrGCurr 
= (int)((nLeft - rectCap.left) * nGClrInc + clrGBase);
        clrBCurr 
= (int)((nLeft - rectCap.left) * nBClrInc + clrBBase);
        
    }


    

    dcBuf.SetBkMode(TRANSPARENT);
    
    CFont font;
    font.CreatePointFont(
110,_T("宋体"),pDC);
    dcBuf.SelectObject(
&font);


    dcBuf.SetTextColor(RGB(
0,0,0));
    dcBuf.TextOut(rectCap.left 
+ 26, rectCap.top +5,m_szCaption,
        (
int)_tcslen(m_szCaption));
    dcBuf.SetTextColor(RGB(
255,255,255));
    dcBuf.TextOut(rectCap.left 
+ 25, rectCap.top + 4, m_szCaption, 
        (
int)_tcslen(m_szCaption));

    ::DrawIconEx(dcBuf,rectCap.left 
+ 4, rectCap.top + 3,
        m_imgList.ExtractIcon(m_nSelectedItem),
        
1616, NULL,NULL, DI_NORMAL);

    pDC
->BitBlt(rectCap.left,rectCap.top,rectCap.Width()+rectCap.Width(),rectCap.Height(),
        
&dcBuf,rectCap.left,rectCap.top,SRCCOPY);
    

    bmp.DeleteObject();
    font.DeleteObject();
    dcBuf.DeleteDC();
}


void CMyPropertySheet::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE lpItem 
= reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    m_nSelectedItem 
= lpItem->iItem ;

   
if (lpItem->iItem  >= 0 && lpItem->iItem < m_wndList.GetItemCount())
   
{
       m_nSelectedItem 
= lpItem->iItem;
       CString strCaption 
= m_wndList.GetItemText(lpItem->iItem,0);
       _tcscpy(m_szCaption, strCaption.GetBuffer());

    SetActivePage(m_nSelectedItem);
    Invalidate();
        
    GetPage(m_nSelectedItem)
->MoveWindow(&m_rectPage);

    m_wndList.SetFocus();
   }

}


void CMyPropertySheet::SetCurrentPage(int nPage)
{
    m_nSelectedItem 
= nPage;

    
if (nPage >=0 && nPage < m_wndList.GetItemCount())
    
{
        CString strCaption 
= m_wndList.GetItemText(m_nSelectedItem,0);
        _tcscpy(m_szCaption, strCaption);

        SetActivePage(m_nSelectedItem);
        Invalidate();

        GetPage(m_nSelectedItem)
->MoveWindow(&m_rectPage);

        m_wndList.SetFocus();
    }

}


void CMyPropertySheet::InitList(void)
{
    LVITEM lvi;
    ::ZeroMemory(
&lvi, sizeof(lvi));
    
    CHeaderCtrl 
*pHeader = m_wndList.GetHeaderCtrl();
    
    pHeader
->ShowWindow(SW_HIDE);

    CRect rectList;
    m_wndList.GetWindowRect(
&rectList);
    ScreenToClient(
&rectList);

    
//报表头不会显示,但是是必需的
    m_wndList.InsertColumn(0,_T("设置"), LVCFMT_CENTER, rectList.Width(), 0);
    

    CString strCaption;

    CTabCtrl 
*pTab = GetTabControl();
    TCITEM tci;
    ::ZeroMemory(
&tci,sizeof(tci));
    tci.mask 
= TCIF_TEXT;
    tci.cchTextMax 
= ITEM_TEXT_LENGTH;
    TCHAR szBuf[ITEM_TEXT_LENGTH] 
= {0};
    tci.pszText 
= szBuf;
    
    
for (int idxPge = 0; idxPge < GetPageCount(); idxPge ++)
    
{
        
if(pTab->GetItem(idxPge, &tci))
        
{
            lvi.iItem 
= idxPge;
            lvi.iSubItem 
= 0;
            lvi.iImage 
= idxPge;
            lvi.mask 
= LVIF_TEXT | LVIF_IMAGE;   
            lvi.pszText 
= tci.pszText ;
            m_wndList.InsertItem(
&lvi);
        }

    }

}


void CMyPropertySheet::OnNMCustomDraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLVCUSTOMDRAW  pLVCD 
= reinterpret_cast<LPNMLVCUSTOMDRAW>(pNMHDR);

    CRect rectRow, rectList;

    m_wndList.GetWindowRect(
&rectList);
    ScreenToClient(
&rectList);
    m_wndList.GetItemRect(
0&rectRow, LVIR_BOUNDS);
    
int iItemHeight = rectRow.Height();
    
int iItemTop = rectRow.top ;


    ::SelectObject(pLVCD
->nmcd.hdc, m_ftList);


    
switch (pLVCD->nmcd.dwDrawStage)
    
{
    
case CDDS_PREPAINT:

        
*pResult = CDRF_NOTIFYITEMDRAW;
        
break;
    
case CDDS_ITEMPREPAINT:

        
*pResult = CDRF_NOTIFYSUBITEMDRAW;
        
break;
    
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
        
{
            
int iCol = pLVCD->iSubItem ;
            
int iRow = (int)pLVCD->nmcd.dwItemSpec;
            CRect rectItem(pLVCD
->nmcd.rc), rectIcon;

            
//计算每个子项的矩形

            rectItem.top 
= iItemTop + iRow * iItemHeight;
            rectItem.bottom 
= rectItem.top + iItemHeight;

            rectItem.left 
+= 3;
            rectItem.right 
-= 3;

            
if (iRow == 0)
                rectItem.top 
+= 3;

            CDC 
*pDC = CDC::FromHandle(pLVCD->nmcd.hdc);            

            LOGFONT lf;

            ::ZeroMemory(
&lf, sizeof(lf));
            
            pDC
->GetCurrentFont()->GetLogFont(&lf);

            
//获得第图标所在的矩形
            m_wndList.GetSubItemRect(iRow, 0, LVIR_ICON, rectIcon);

            
const COLORREF clrBlack = RGB(000);
            
const COLORREF clrWhite = RGB(255255255);

            
if ((pLVCD->nmcd.uItemState & (CDIS_FOCUS | CDIS_SELECTED)) == 
                (CDIS_FOCUS 
| CDIS_SELECTED))
            
{
                    
                    pDC
->FillSolidRect(&rectItem, m_clrTextBkSele);
                    pDC
->SetTextColor(clrWhite);
                    pDC
->TextOut(rectItem.left + rectIcon.Width() + 8
                        (iRow 
== 0 ? (rectItem.top - 3) : rectItem.top) + 
                        (iItemHeight 
- abs(lf.lfHeight))/2, m_wndList.GetItemText(iRow, iCol), 
                        (
int)_tcslen(m_wndList.GetItemText(iRow, iCol)));
                    
                    ::DrawIconEx(
*pDC,rectIcon.left, rectIcon.top + (iItemHeight - 16/ 2,
                        m_imgList.ExtractIcon(iRow),
16,16,NULL,NULL,DI_NORMAL);                        
                    
                    pDC
->SetTextColor(clrBlack);
                    
                    DrawGradientLine(pDC,m_clrSeprator,CPoint(rectItem.left, rectItem.bottom 
- 1),
                        CPoint(rectItem.right, rectItem.bottom
-1));                    
            
            }

            
else
            
{
                    pDC
->FillSolidRect(&rectItem, clrWhite);

                    pDC
->TextOut(rectItem.left + rectIcon.Width() + 8
                        (iRow 
== 0?(rectItem.top - 3):rectItem.top) + (iItemHeight - abs(lf.lfHeight))/2
                        m_wndList.GetItemText(iRow, iCol), (
int)_tcslen(m_wndList.GetItemText(iRow, iCol)));

                    ::DrawIconEx(
*pDC,rectIcon.left, rectIcon.top + (iItemHeight - 16/ 2
                        m_imgList.ExtractIcon(iRow), 
1616, NULL, NULL, DI_NORMAL);

                    DrawGradientLine(pDC,m_clrSeprator,CPoint(rectItem.left, rectItem.bottom
-1), 
                        CPoint(rectItem.right, rectItem.bottom 
- 1));                    

            }


            
*pResult = CDRF_SKIPDEFAULT;
            
break;
        }



    
default:
        
*pResult = CDRF_SKIPDEFAULT;
        
break;
    }
    
}



void CMyPropertySheet::DrawGradientLine(CDC* pDC, COLORREF clrLine, POINT ptStart, POINT ptEnd)
{
//画渐近线,从clrLine的颜色变化至白色

    
int clrBBase = clrLine>>16 & 0x000000FF;
    
int clrGBase = clrLine>>8 & 0x000000FF;
    
int clrRBase = clrLine & 0x000000FF;

    
int clrBCurr = 255;
    
int clrGCurr = 255;
    
int clrRCurr = 255;

    
double dRInc = (double)(255 - clrRBase) / (double)(abs(ptEnd.x - ptStart.x));
    
double dGInc = (double)(255 - clrGBase) / (double)(abs(ptEnd.x - ptStart.x));
    
double dBInc = (double)(255 - clrBBase) / (double)(abs(ptEnd.x - ptStart.x));

    POINT ptCurr 
= ptStart;

    
for ( ; ptCurr.x < ptEnd.x; ptCurr.x ++)            
    
{
        pDC
->SetPixel(ptCurr.x, ptCurr.y - 1,RGB(clrRCurr,clrGCurr,clrBCurr));
        pDC
->SetPixel(ptCurr, RGB(clrRCurr,clrGCurr,clrBCurr));
        clrRCurr 
= clrRBase + (int)((ptCurr.x - ptStart.x) * dRInc);
        clrGCurr 
= clrGBase + (int)((ptCurr.x - ptStart.x) * dGInc);
        clrBCurr 
= clrBBase + (int)((ptCurr.x - ptStart.x) * dBInc);
    }

}


int CMyPropertySheet::AddIcon(HICON icon)
{
    
return m_imgList.Add(icon);
}


void CMyPropertySheet::SetCaptionColor(const COLORREF clrCaption)
{
    m_clrCaption 
= clrCaption;
}


void CMyPropertySheet::SetSepratorColor(const COLORREF clrSeprator)
{
    m_clrSeprator 
= clrSeprator;
}


void CMyPropertySheet::SetSelectedColor(const COLORREF clrSelected)
{
    m_clrTextBkSele 
= clrSelected;
}


void CMyPropertySheet::SetChildCaption(int nIndex, LPSTR strCaption)
{
    
if (nIndex >= 0 && nIndex <= GetPageCount())
    
{
        LVITEM lvi;
        ::ZeroMemory(
&lvi, sizeof(lvi));

        lvi.iItem 
= nIndex;
        lvi.iSubItem 
= 0;
        lvi.iImage 
= nIndex;
        lvi.mask 
= LVIF_TEXT | LVIF_IMAGE;   
        lvi.pszText 
= strCaption;
        m_wndList.SetItem(
&lvi);
    }

}


void CMyPropertySheet::FlashCurCaption()
{
    CString strCaption 
= m_wndList.GetItemText(GetActiveIndex(),0);
    _tcscpy( m_szCaption, strCaption );
    SetActivePage(GetActiveIndex());

    Invalidate();

    GetPage(m_nSelectedItem)
->MoveWindow(&m_rectPage);
    m_wndList.SetFocus();
}
posted on 2008-11-28 17:24 黑色天使 阅读(946) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用链接

留言簿(2)

随笔分类

随笔档案

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜