这个是此换肤方法的基础函数: 相关资料:Microsoft Knowledge Base Article - Q79212
///{{{{ for global function
///HOWTO: Drawing Transparent Bitmaps see: Microsoft Knowledge Base Article - Q79212
// TransparentBlt - Copies a bitmap transparently onto the destination DC
// hdcDes - Handle to destination device context
// xDes - x-coordinate of destination rectangle's upper-left corner
// yDes - y-coordinate of destination rectangle's upper-left corner
// width - Width of destination rectangle
// height - height of destination rectangle
// hbmSrc - Handle of the source bitmap
// xSrc - x-coordinate of source rectangle's upper-left corner
// ySrc - y-coordinate of source rectangle's upper-left corner
// crTrans - The transparent color
// hPal - Logical palette to be used with bitmap. Can be NULL
BOOL TransparentBitBlt(HDC hdcDes,
int xDes,
int yDes,
int width,
int height,
HBITMAP hbmSrc,
int xSrc,
int ySrc,
COLORREF crTrans,
HPALETTE hPal
)
{
ASSERT(hdcDes!=NULL);//if(hdcDes == NULL) return FALSE;
ASSERT(hbmSrc!=NULL);//if(hbmSrc == NULL) return FALSE;
CDC dc, memDC, maskDC, tempDC;
dc.Attach(hdcDes);
maskDC.CreateCompatibleDC(&dc);
CBitmap maskBmp;
//add these to store return of SelectObject() calls
CBitmap *pOldMemBmp = NULL;
CBitmap *pOldMaskBmp = NULL;
HBITMAP hOldTempBmp = NULL;
memDC.CreateCompatibleDC(&dc);
tempDC.CreateCompatibleDC(&dc);
CBitmap bmpImage;
bmpImage.CreateCompatibleBitmap(&dc, width, height);
pOldMemBmp = memDC.SelectObject(&bmpImage);
// Select and realize the palette
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && hPal )
{
::SelectPalette(dc, hPal, FALSE);
dc.RealizePalette();
::SelectPalette(memDC, hPal, FALSE);
}
hOldTempBmp = (HBITMAP)::SelectObject(tempDC.m_hDC, hbmSrc);
memDC.BitBlt(0, 0, width, height, &tempDC, xSrc, ySrc, SRCCOPY);
// Create monochrome bitmap for the mask
maskBmp.CreateBitmap(width, height, 1, 1, NULL);
pOldMaskBmp = maskDC.SelectObject(&maskBmp);
memDC.SetBkColor(crTrans);
// Create the mask from the memory DC
maskDC.BitBlt(0, 0, width, height, &memDC, 0, 0, SRCCOPY);
// Set the background in memDC to black. Using SRCPAINT with black
// and any other color results in the other color, thus making
// black the transparent color
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(0, 0, width, height, &maskDC, 0, 0, SRCAND);
// Set the foreground to black. See comment above.
dc.SetBkColor(RGB(255,255,255));
dc.SetTextColor(RGB(0,0,0));
dc.BitBlt(xDes, yDes, width, height, &maskDC, 0, 0, SRCAND);
// Combine the foreground with the background
dc.BitBlt(xDes, yDes, width, height, &memDC, 0, 0, SRCPAINT);
if (hOldTempBmp)
::SelectObject(tempDC.m_hDC, hOldTempBmp);
if (pOldMaskBmp)
maskDC.SelectObject(pOldMaskBmp);
if (pOldMemBmp)
memDC.SelectObject(pOldMemBmp);
dc.Detach();
maskBmp.DeleteObject();
bmpImage.DeleteObject();
maskDC.DeleteDC();
memDC.DeleteDC();
tempDC.DeleteDC();
pOldMemBmp = NULL;
pOldMaskBmp = NULL;
hOldTempBmp = NULL;
return TRUE;
}
///}}} for global function
另三个很有意思的类,从高手那“盗”来的,呵呵:
class CWinRect: public CRect
{
public:
CWinRect(HWND hWnd)
{
::GetWindowRect(hWnd, this);
}
CWinRect(const CWnd *pWnd)
{
::GetWindowRect(pWnd->GetSafeHwnd(), this);
}
};
class CWinText: public CString
{
public:
CWinText(HWND hWnd)
{
(CWnd::FromHandle(hWnd))->GetWindowText(*this);
}
CWinText(const CWnd *pWnd)
{
pWnd->GetWindowText(*this);
}
};
class CClientRect: public CRect
{
public:
CClientRect(HWND hWnd)
{
::GetClientRect(hWnd, this);
}
CClientRect(CWnd *pWnd)
{
::GetClientRect(pWnd->GetSafeHwnd(), this);
}
};