介绍 这是在基于对话框的应用程序中实现皮肤的一个非常简单的示例。 代码实际上是我的一个朋友(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