基于对话框的应用程序中的皮肤

介绍 这是在基于对话框的应用程序中实现皮肤的一个非常简单的示例。 代码实际上是我的一个朋友(sun@codefinger.de)写的,谢谢 去见他。我只是向你们展示它使用起来有多简单。也谢谢 致Davide Calabro,他允许我使用他的CButtonST类。 例子 在我的例子中,我使用了一个简单的基于对话框的应用程序,称为“皮肤”。 为你的对话框导入一个你喜欢的位图。在我们的例子中,它被标记为IDB_MAIN。 在对话框头文件中创建以下变量和函数。 隐藏,复制Code

CSkinDlg : public CDialog
{
public:
        CSkinDlg();
    HBITMAP m_hBmp;
    HRGN m_hWndRgn;
    HRGN DIBToRgn(HBITMAP hBmp,COLORREF BkColor,BOOL Direct); // Handle the Skin
    .
    .
    .

在构造函数中执行以下操作: 隐藏,复制Code

CSkinDlg::CSkintDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CSkinDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CSkinDlg)
    //}}AFX_DATA_INIT
    m_hBmp=(HBITMAP)LoadImage(AfxGetApp()->m_hInstance,
                                   MAKEINTRESOURCE(IDB_MAIN),
                                   IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION);

    m_hWndRgn=DIBToRgn(m_hBmp,0x00ff00,FALSE);
}

插入函数HRGN DIBToRgn(HBITMAP hBmp, COLORREF BkColor, BOOL Direct)到你的 对话框类,并将以下代码粘贴到其中。 隐藏,收缩,复制Code

HRGN CSkinDlg ::DIBToRgn(HBITMAP hBmp, COLORREF BkColor, BOOL Direct)
{
    // use to return the handle of the HGRN
      HRGN hRgn = NULL;                    
    #define MAX_ALLOC_RECTS  100
    //the difference of the color
    COLORREF  Tolerance=0x00101010;
    if (hBmp)
    {
        //creat the dib to save the dc
        HDC hMemDC = CreateCompatibleDC(NULL);        
        if (hMemDC)
        {
            BITMAP bm;
            //get the info of the bitmap
            GetObject(hBmp, sizeof(bm), &bm);    

            BITMAPINFOHEADER BmpInfoh = {     // the struct of the bitmap
                    sizeof(BITMAPINFOHEADER), // biSize
                    bm.bmWidth,               // biWidth;
                    bm.bmHeight,              // biHeight;
                    1,                        // biPlanes;
                    32,                       // biBitCount
                    BI_RGB,                   // biCompression;
                    0,                        // biSizeImage;
                    0,                        // biXPelsPerMeter;
                    0,                        // biYPelsPerMeter;
                    0,                        // biClrUsed;
                    0                         // biClrImportant;
            };
            //design a void point to point to the bitmap
            LPVOID pBit32; 
            //creat a DIB
            HBITMAP hDib32 = CreateDIBSection(hMemDC, 
                    (BITMAPINFO *)&BmpInfoh, 
                    DIB_RGB_COLORS, &pBit32, NULL, 0);
            if (hDic32)
            {
                //copy dib to DC
                HBITMAP hOldib32 = (IBITMAP)SelectObject(hMemDC, hDib32);
                // create a DC to save orgin bitmap
                HDC hDC = CreateCompatibleDC(hMemDC);
                if (hDC)
                {
                    BITMAP bm32;
                    // get the new 34 bit Dib size
                    GetObject(hDib32, sizeof(bm32), &bm32);
                    //make sure the 32Dib's every line pilex's is 4 's times
                    while (bm32.bmWidthBytes % 4)
                        bm32.bmWidthBytes++;
                    //copy the orginal dib to DC
                    HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
                    //copy dib to memory DC
                    BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
                    DWORD MaxRects = MAX_ALLOC_RECTS;
                    SYSTEM_INFO  Sysinfo;
                    //get memory size
                    GetSystemInfo(&Sysinfo);
                    //make a stack which can chang big
                    //alloct memory
                    HANDLE hRcData=HeapCreate(HEAP_GENERATE_EXCEPTIONS,Sysinfo.dwPageSize, 0);
                    RGNDATA * pRcData=(RGNDATA*)HeapAlloc(hRcData,HEAP_ZERO_MEMORY,
                        sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
                     //fill the the RGNDATA struck
                    pRcData->rdh.dwSize = sizeof(RGNDATAHEADER);
                    pRcData->rdh.iType = RDH_RECTANGLES;
                    pRcData->rdh.nCount = pRcData->rdh.nRgnSize = 0;
                    SetRect(&pRcData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
                             BYTE hr,hg,hb,lr,lg,lb;
                    switch(BkColor)
                    {
                    case RGB(255,255,255):    //if the bkcolor is white
                        hr = GetRValue(BkColor);
                        hg = GetGValue(BkColor);
                        hb = GetBValue(BkColor);
                        lr = min(0xff, hr - GetRValue(Tolerance));
                        lg = min(0xff, hg - GetGValue(Tolerance));
                        lb = min(0xff, hb - GetBValue(Tolerance));
                        break;
                    case RGB(0,0,0):    //if the bkcolor is black
                        lr = GetRValue(BkColor);
                        lg = GetGValue(BkColor);
                        lb = GetBValue(BkColor);
                        hr = min(0xff, lr + GetRValue(Tolerance));
                        hg = min(0xff, lg + GetGValue(Tolerance));
                        hb = min(0xff, lb + GetBValue(Tolerance));
                        break;
                    default:        //if the bkcolor is other color
                        Tolerance=0x111111;
                        lr =max(0, GetRValue(BkColor)-GetRValue(Tolerance));
                        lg = max(0,GetGValue(BkColor)-GetGValue(Tolerance));
                        lb = max(0,GetBValue(BkColor)-GetBValue(Tolerance));
                        hr=min(0xff,GetRValue(BkColor)+GetRValue(Tolerance));
                        hg=min(0xff,GetGValue(BkColor)+GetGValue(Tolerance));
                        hb=min(0xff,GetBValue(BkColor)+GetBValue(Tolerance));
                        break;
                    }
                    // Get the bit point and do the search
                    BYTE *pBits = (BYTE *)bm32.bmBits + 
                                         (bm32.bmHeight - 1) * bm32.bmWidthBytes;
                    for (int y = 0; y < bm.bmHeight; y++)
                    {
                        for (int x = 0; x < bm.bmWidth; x++)
                        {
                            int x0 = x;
                            DWORD *pColor = (DWORD *)pBits + x;
                            BYTE dr,dg,db;
                            while (x < bm.bmWidth)
                            {
                                dr=GetRValue(*pColor);
                                dg=GetGValue(*pColor);
                                db=GetBValue(*pColor);

                                if ((dr>= lr && dr<= hr) && (dg>=lg&&dg<=hg) 
                                                         && (db>=lb&&db<=hb))
                                {
                                    if(Direct)
                                        break;
                                    else
                                    {
                                        pColor++;
                                        x++;
                                    }
                                  }
                                else if(Direct)
                                {
                                    pColor++;
                                    x++;
                                }
                                else
                                    break;

                            }
                            if (x > x0)
                            {
                                if (pRcData->rdh.nCount >= MaxRects)
                                {
                                    MaxRects += MAX_ALLOC_RECTS;
                                    //re alloc the stack
                                    pRcData=(RGNDATA*)HeapReAlloc(
                                    hRcData,HEAP_ZERO_MEMORY,pRcData, 
                                    sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
                                }
                                RECT *pr = (RECT *)&pRcData->Buffer;
                                SetRect(&pr[pRcData->rdh.nCount], x0, y, x, y+1);
                                pRcData->rdh.rcBound.left = x0;
                                pRcData->rdh.rcBound.top = y;
                                pRcData->rdh.rcBound.right = x;
                                pRcData->rdh.rcBound.bottom = y+1;
                                pRcData->rdh.nCount++;

                                if (pRcData->rdh.nCount == 3000)
                                {    
                                    HRGN tmphRgn = ExtCreateRegion(NULL,
                                    sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects),
                                    pRcData);
                                    if (hRgn)
                                    {
                                        CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
                                        DeleteObject(tmphRgn);
                                    }
                                    else
                                        hRgn = tmphRgn;
                                    pRcData->rdh.nCount = 0;
                                    SetRect(&pRcData->rdh.rcBound, 
                                    MAXLONG, MAXLONG, 0, 0);
                                }
                            }
                        }

                        // search next line
                        pBits -= bm32.bmWidthBytes;
                    }
                    HRGN tmphRgn = ExtCreateRegion(NULL, 
                            sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects), pRcData);
                    if (hRgn)
                    {
                        CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
                        DeleteObject(tmphRgn);
                    }
                    else
                        hRgn = tmphRgn;
                    // make a rect ,use this rect xor to the  BkColor
                    //then we can get the rect we want
                    if(!Direct)
                    {
                        HRGN hRect=CreateRectRgn(0,0,bm.bmWidth,bm.bmHeight);
                                        if(hRect)
                        {
                            CombineRgn(hRgn,hRgn,hRect,RGN_XOR);
                            DeleteObject(hRect);
                        }
                        else
                            return NULL;
                    }
                    //release the memory
                    HeapFree(hRcData,HEAP_NO_SERIALIZE,pRcData);
                    SelectObject(hDC, holdBmp);
                    DeleteDC(hDC);
                    DeleteObject(holdBmp);
                }
                SelectObject(hMemDC,hOldib32);
                DeleteDC(hMemDC);
                DeleteObject(hOldib32);
                DeleteObject(hDib32);
            }
            else
                DeleteDC(hMemDC);
        }
    }
    return hRgn;
  }

为ON_WM_ERASEBKND消息添加一个处理程序来擦除对话框的背景: 隐藏,复制Code

BOOL CSkinDlg::OnEraseBkgnd(CDC* pDC) 
{
    if(m_hBmp)
    {
        BITMAP bm;
        GetObject(m_hBmp,sizeof(bm),&bm);
        HDC hMemdc=CreateCompatibleDC(pDC->m_hDC); 
        if(hMemdc)
        {
           HBITMAP hOldBmp=(HBITMAP)SelectObject(hMemdc,m_hBmp);
           if(hOldBmp)
           {
               BitBlt(pDC->m_hDC,0,0,bm.bmWidth,bm.bmHeight,hMemdc,0,0,SRCCOPY);
               SelectObject(hMemdc,hOldBmp);
               DeleteDC(hMemdc);
               DeleteObject(hOldBmp);
               return TRUE;
           }
           else
             DeleteDC(hMemdc);
        }
    }
    return CDialog::OnEraseBkgnd(pDC);
}

在您的OnInitDialog中输入以下代码: 隐藏,复制Code

BOOL CSkinDlg::OnInitDialog()
{
    .
    .
    .
    // Show the Skin
    if(m_hWndRgn)
        SetWindowRgn(m_hWndRgn,TRUE);

    return TRUE;  // return TRUE  unless you set the focus to a control
}

对话框中的“最小化”和“关闭”是由Davide实现的 Calabro CButtonST阶级 就是这样!运行你的应用程序,你会看到你漂亮的皮肤。本文由www.codefinger.de提供 本文转载于:http://www.diyabc.com/frontweb/news12225.html

原文地址:https://www.cnblogs.com/Dincat/p/13473747.html