CxSkinButton類的擴展

        CxSkinButton是開源的換膚按鈕控件,用起來也很方便。CxSkinButton提供的皮膚設置接口如下:

void SetSkin(UINT normal,UINT down, UINT over=0, UINT disabled=0, UINT focus=0,UINT mask=0,short drawmode=1,short border=1,short margin=4)

可以看到該接口必須輸入一個個的狀態位圖ID,但是在實際中,美工將按鈕的各個狀態圖放在一張圖片中,上述接口就無法使用。針對這個問題, 可以在CxSkinButton的基礎上,擴展一個新的類,增加一個新的皮膚設置接口。

繼承類定義:

class CDvssButton :
    public CxSkinButton
{
public:
    CDvssButton(void);
    ~CDvssButton(void);
public:

    //此處接口可以根據美工提供圖片適當改變
    void SetSkin(UINT nIDRes,UINT nIDMask = 0,short nDrawMode = 1,short nBorder = 1,short nMargin = 4,int nSmallImages = 7);
private:
    void CopyBitmap(CBitmap* pDstBitmap,int nDstX,int nDstY,int nWidth,int nHeight,CBitmap* pSrcBitmap,int nSrcX,int nSrcY);

};

繼承類實現函數:

void CDvssButton::SetSkin(UINT nIDRes,UINT nIDMask,short nDrawMode,short nBorder,short nMargin,int nSmallImages)
{
    m_bNormal.DeleteObject();
    m_bDown.DeleteObject();
    m_bOver.DeleteObject();
    m_bDisabled.DeleteObject();
    m_bMask.DeleteObject();
    m_bFocus.DeleteObject();


    CBitmap bitmap;
    bitmap.LoadBitmap(nIDRes);
    int nWidth = GetBitmapWidth((HBITMAP)bitmap.m_hObject);
    int nHeight = GetBitmapHeight((HBITMAP)bitmap.m_hObject);
    //將大圖片的各種狀態圖拷貝到對應的狀態位圖對象成員中,此處需根據美工提供的圖片自己靈活調用
    CopyBitmap(&m_bDisabled,0,0,nWidth/nSmallImages,nHeight,&bitmap,0,0);
    CopyBitmap(&m_bNormal,0,0,nWidth/nSmallImages,nHeight,&bitmap,nWidth/nSmallImages,0);
    CopyBitmap(&m_bDown,0,0,nWidth/nSmallImages,nHeight,&bitmap,nWidth/nSmallImages*2,0);
    CopyBitmap(&m_bOver,0,0,nWidth/nSmallImages,nHeight,&bitmap,nWidth/nSmallImages*3,0);
   
    bitmap.DeleteObject();
   
    m_DrawMode=max(0,min(nDrawMode,2));
    m_Border=nBorder;
    m_FocusRectMargin=max(0,nMargin);
   
    if (nIDMask>0){
        m_bMask.LoadBitmap(nIDMask);
        if (hClipRgn) DeleteObject(hClipRgn);
        hClipRgn = CreateRgnFromBitmap(m_bMask,RGB(255,255,255));
        if (hClipRgn){
            SetWindowRgn(hClipRgn, TRUE);
            CDC *pDC = GetDC();
            if (pDC){
                SelectClipRgn(pDC->GetSafeHdc(), hClipRgn);
                ReleaseDC(pDC);
            }
        }
        if (m_DrawMode==0){
            SetWindowPos(NULL,0,0,GetBitmapWidth(m_bMask),
                        GetBitmapHeight(m_bMask),SWP_NOZORDER|SWP_NOMOVE);
        }
    }
}
//該函數可以實現將一張圖片位圖對象的指定位置,指定高,寬拷貝給另一位圖對象
void CDvssButton::CopyBitmap(CBitmap* pDstBitmap,int nDstX,int nDstY,int nWidth,int nHeight,CBitmap* pSrcBitmap,int nSrcX,int nSrcY)
{
    CDC SrcDC;
    CDC DstDC;

    SrcDC.CreateCompatibleDC(NULL);
    DstDC.CreateCompatibleDC(NULL);
   
    BITMAP bitmap;
    pSrcBitmap->GetBitmap(&bitmap);
    bitmap.bmWidth = nWidth;
    bitmap.bmHeight = nHeight;
    pDstBitmap->CreateBitmapIndirect(&bitmap);

    //此處不要使用如下這種方法創建兼容位圖,否則創建的位圖格式只有黑白兩色
    //pDstBitmap->CreateCompatibleBitmap(&DstDC,nWidth,nHeight);
    CBitmap* pOldSrcBitmap = SrcDC.SelectObject(pSrcBitmap);
    CBitmap* pOldDstBitmap = DstDC.SelectObject(pDstBitmap);
   
    DstDC.BitBlt(0,0,nWidth,nHeight,&SrcDC,nSrcX,nSrcY,SRCCOPY);
   
    SrcDC.SelectObject(pOldSrcBitmap);
    DstDC.SelectObject(pOldDstBitmap);
    SrcDC.DeleteDC();
    DstDC.DeleteDC();

}

 

如此一來,該按鈕就可以實現對一張含有多種狀態圖圖片的處理,上述代碼,測試通過,可以直接使用。這裏也可以直接修改CxSkinButton的源碼,解決此問題。但CxSkinButton類大量的成員變量,成員函數都是保護成員,提供了擴展的便利,實現起來很快。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章