// MyBitmap.cpp: implementation of the CMyBitmap class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MyBitmap.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif static void prepareMasks(HDC hdcSrc, HBITMAP hBmpSrc, COLORREF transColor, int width, int height, HBITMAP &hBmpSprite, HBITMAP &hBmpMask); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMyBitmap::CMyBitmap() : m_cx(0), m_cy(0) { } CMyBitmap::~CMyBitmap() { } BOOL CMyBitmap::LoadBitmapFromFile(LPCTSTR szFilename) { // if ((pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)==RC_PALETTE) // return FALSE; // AfxMessageBox("This program does not show correct colors on non-true color surface!!"); // remove old source DeleteObject(); ASSERT(szFilename); // try to open the specified picture file CFile fPicture; if (!fPicture.Open(szFilename, CFile::modeRead)) return false; // read file status CFileStatus fsPictureStatus; fPicture.GetStatus(szFilename, fsPictureStatus); if (fsPictureStatus.m_size == -1) return false; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, fsPictureStatus.m_size); ASSERT(hGlobal); LPVOID lpvPictureData = GlobalLock(hGlobal); ASSERT(lpvPictureData); ASSERT((LONG)fPicture.Read(lpvPictureData, fsPictureStatus.m_size) == fsPictureStatus.m_size); GlobalUnlock(hGlobal); LPSTREAM lpIStream = NULL; BOOL ret = FALSE; if (SUCCEEDED(CreateStreamOnHGlobal(hGlobal, TRUE, &lpIStream))) { LPPICTURE lpIPicture = NULL; if (SUCCEEDED(::OleLoadPicture(lpIStream, fsPictureStatus.m_size, FALSE, IID_IPicture, (LPVOID*)&lpIPicture))) { ASSERT(lpIPicture); HBITMAP hbmpPicture = NULL; lpIPicture->get_Handle((OLE_HANDLE*)&hbmpPicture); if (hbmpPicture) { HBITMAP hbmpOwnPicture = (HBITMAP) CopyImage(hbmpPicture, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG); ret = Attach(hbmpOwnPicture); } lpIPicture->Release(); } lpIStream->Release(); } if (ret) { BITMAP bm; GetBitmap(&bm); m_cx = bm.bmWidth; m_cy = bm.bmHeight; } return ret; } int CMyBitmap::Width() { return m_cx; } int CMyBitmap::Height() { return m_cy; } void CMyBitmap::Draw(CDC *pDC, int ix, int iy, BOOL forceBackgroundPalette) { if ((m_cx==0)||(m_cy==0)) return; // Create a compatible memory DC CDC memDC; memDC.CreateCompatibleDC(pDC); CBitmap *pOldBitmap = (CBitmap *)memDC.SelectObject(this); CPalette *pOldPalette; // Select and realize the palette if ((pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) && (m_palette.GetSafeHandle())) { pOldPalette = (CPalette *)pDC->SelectPalette(&m_palette, forceBackgroundPalette); pDC->RealizePalette(); } pDC->BitBlt(ix,iy, m_cx, m_cy, &memDC, 0,0, SRCCOPY); memDC.SelectObject(pOldBitmap); if ((pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) && (m_palette.GetSafeHandle())) pDC->SelectPalette(pOldPalette, FALSE); } void CMyBitmap::createBitmap(CWnd *pWnd, Card card, int width, int height) { m_cx = width; m_cy = height; CClientDC clientDC(pWnd); CDC dcMem; dcMem.CreateCompatibleDC(&clientDC); CreateCompatibleBitmap(&dcMem, width, height); CBitmap *pOldBmp = (CBitmap *) dcMem.SelectObject(this); CString tmp; if (card.suite==Spade) tmp.Format("%d Spade", card.face); else if (card.suite==Heart) { dcMem.SetTextColor(RGB(255,0,0)); tmp.Format("%d Heart", card.face); } else if (card.suite==Diamond) { dcMem.SetTextColor(RGB(255,0,0)); tmp.Format("%d Diam", card.face); } else if (card.suite==Club) tmp.Format("%d Club", card.face); dcMem.Rectangle(0, 0, width, height); dcMem.TextOut(3, 3, tmp); if (card.suite==Back) { CBrush *pOldBr = (CBrush *)dcMem.SelectStockObject(LTGRAY_BRUSH); dcMem.Rectangle(0, 0, width, height); dcMem.Rectangle(2, 2, width-2, height-2); dcMem.SelectObject(pOldBr); } dcMem.SelectObject(pOldBmp); } void CMyBitmap::DrawSprite(CDC *pDC, COLORREF transColor, int ix, int iy) { CBitmap *pOldSprite, *pOldMask; HBITMAP hBmpSprite, hBmpMask; prepareMasks(pDC->GetSafeHdc(), (HBITMAP) GetSafeHandle(), transColor, m_cx, m_cy, hBmpSprite, hBmpMask); CBitmap bmpMask, bmpSprite; bmpMask.Attach(hBmpMask); bmpSprite.Attach(hBmpSprite); CDC dcMem; dcMem.CreateCompatibleDC(pDC); // Step 1. cut a sprite shape from background pOldMask = (CBitmap *) dcMem.SelectObject(&bmpMask); pDC->BitBlt(ix, iy, m_cx, m_cy, &dcMem, 0, 0, SRCAND); dcMem.SelectObject(pOldMask); // Step 3. OR the clean sprite to the background pOldSprite = (CBitmap *) dcMem.SelectObject(&bmpSprite); pDC->BitBlt(ix, iy, m_cx, m_cy, &dcMem, 0, 0, SRCPAINT); // OR dcMem.SelectObject(pOldSprite); } static pBGR MyGetDibBits(HDC hdcSrc, HBITMAP hBmpSrc, int nx, int ny) { BITMAPINFO bi; BOOL bRes; pBGR buf; bi.bmiHeader.biSize = sizeof(bi.bmiHeader); bi.bmiHeader.biWidth = nx; bi.bmiHeader.biHeight = ny; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 32; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = nx * 4 * ny; bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; buf = (pBGR) malloc(nx * 4 * ny); bRes = GetDIBits(hdcSrc, hBmpSrc, 0, ny, buf, &bi, DIB_RGB_COLORS); if (!bRes) { free(buf); buf = 0; } return buf; } static void prepareMasks(HDC hdcSrc, HBITMAP hBmpSrc, COLORREF transColor, int width, int height, HBITMAP &hBmpSprite, HBITMAP &hBmpMask) { pBGR src = MyGetDibBits(hdcSrc, hBmpSrc, width, height); // pBGR sprite = MyGetDibBits(hdcSrc, hBmpSprite, width, height); pBGR sprite = (pBGR) malloc(width*height*4); memcpy(sprite, src, width*height*4); // pBGR mask = MyGetDibBits(hdcSrc, hBmpMask, width, height); pBGR mask = (pBGR) malloc(width*height*4); memset(mask, 0, width*height*4); pBGR srcLine = src; pBGR spriteLine = sprite; pBGR maskLine = mask; int stepX, stepY; for (stepY=0; stepY