#include "StdAfx.h" #include "..\include\skinimage.h" CSkinImage::CSkinImage() : m_hDib(NULL), m_nColors(0), m_dwLineWidth(0UL), m_dwPixelWidth(0UL) { ::ZeroMemory(&m_bi, sizeof(m_bi)); } CSkinImage::~CSkinImage(void) { if( !IsEmpty() ) DeleteObject(); } BOOL CSkinImage::CopyTo(CSkinImage *pDst) const { ATLASSERT(pDst); if( !pDst->IsEmpty() ) pDst->DeleteObject(); DWORD dwSize = GetByteSize(); pDst->m_hDib = malloc(dwSize); // Allocate memory block to store our bitmap ATLASSERT(pDst->m_hDib); if( pDst->m_hDib==NULL return FALSE; ::CopyMemory(&pDst->m_bi, &m_bi, sizeof(m_bi)); ::CopyMemory(pDst->m_hDib, m_hDib, dwSize); pDst->m_dwLineWidth = m_dwLineWidth; pDst->m_dwPixelWidth = m_dwPixelWidth; pDst->m_nColors = m_nColors; return TRUE; } BOOL CSkinImage::LoadBitmap(LPCTSTR lpszPathName) { ATLASSERT(!::IsBadStringPtr(lpszPathName,-1)); HBITMAP hBitmap = (HBITMAP) ::LoadImage(NULL, lpszPathName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); ATLASSERT(hBitmap); if( hBitmap==NULL ) return FALSE; BOOL res = Create(hBitmap); ::DeleteObject(hBitmap); return res; } BOOL CSkinImage::LoadBitmap(UINT nRes) { HBITMAP hBitmap = (HBITMAP) ::LoadImage(NULL,MAKEINTRESOURCE(nRes), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); ATLASSERT(hBitmap); if( hBitmap==NULL ) return FALSE; BOOL res = Create(hBitmap); ::DeleteObject(hBitmap); return res; } BOOL CSkinImage::Create(HBITMAP hBitmap) { ATLASSERT(::GetObjectType(hBitmap)==OBJ_BITMAP); BITMAP bm; ::GetObject(hBitmap, sizeof(BITMAP), &bm); if( Create(bm.bmWidth, bm.bmHeight, 24)==FALSE ) return FALSE; CWindowDC dc(CWnd::FromHandle(HWND_DESKTOP)); // Need a DC; any DC will do! int lines = ::GetDIBits(dc, hBitmap, 0, bm.bmHeight, GetBits(), (BITMAPINFO*) &m_bi, DIB_RGB_COLORS); ATLASSERT(lines==bm.bmHeight); if( lines != bm.bmHeight ) return FALSE; return TRUE; } BOOL CSkinImage::Create(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) { #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) if( !IsEmpty() ) DeleteObject(); // Make sure bits per pixel is valid if( wBitCount<=1 ) wBitCount = 1; else if( wBitCount<=4 ) wBitCount = 4; else if( wBitCount<=8 ) wBitCount = 8; else wBitCount = 24; switch( wBitCount ){ case 1: m_nColors = 2; break; case 4: m_nColors = 16; break; case 8: m_nColors = 256; break; default: // A 24/32 bit DIB has no color table m_nColors = 0; } m_dwLineWidth = WIDTHBYTES(wBitCount * dwWidth); m_dwPixelWidth = wBitCount / 8; // Initialize BITMAPINFOHEADER m_bi.biSize = sizeof(BITMAPINFOHEADER); m_bi.biWidth = dwWidth; // Fill in width from parameter m_bi.biHeight = dwHeight; // Fill in height from parameter m_bi.biPlanes = 1; // Must be 1 m_bi.biBitCount = wBitCount; m_bi.biCompression = BI_RGB; m_bi.biSizeImage = m_dwLineWidth * dwHeight; m_bi.biXPelsPerMeter = 0; m_bi.biYPelsPerMeter = 0; m_bi.biClrUsed = 0; m_bi.biClrImportant = 0; // Calculate size of memory block required to store the DIB. This // block should be big enough to hold the BITMAPINFOHEADER, the color // table, and the bits m_hDib = malloc(GetByteSize()); // Allocate memory block to store our bitmap if( m_hDib==NULL ) return FALSE; // Use our bitmap info structure to fill in first part of // our DIB with the BITMAPINFOHEADER LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) m_hDib; *lpbi = m_bi; return TRUE; }