⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cskinobject.cpp

📁 windows ce imageviewer_customized
💻 CPP
字号:
//
// CSkinObject.cpp
//
// --------------------------------------------------------
// A Practical Guide to Script-Driven Software Development
// Author: Qiming Lu                        Date: 6/1/2006
// MSN Messager: luqiming26@hotmail.com
// MSN Blog: http://spaces.msn.com/jemylu
// --------------------------------------------------------

#include "stdafx.h"
#include "CSkinObject.h"
#include "MiscUtils.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
CSkinObject::CSkinObject() 
	: mStateCount(1)
	, mImageCount(0)
	, mTagName("")
	, mSkinXPos(0)
	, mSkinYPos(0)
	, mSkinWidth(0)
	, mSkinHeight(0)
{
}

CSkinObject::~CSkinObject()
{
}

void CSkinObject::SetTagName(const char* inTagName)
{
	if (mTagName != inTagName)
	{
		mTagName = inTagName;
		ReadXMLSettings();		
	}
}

void CSkinObject::ReadXMLSettings()
{
}

void CSkinObject::LoadImageMap(CRgn& outRegion)
{
	LoadImageMap(outRegion, mSkinWidth, mSkinHeight, mImageCount, mSkinFileName, 0);
}

// The transparent color is RGB(255, 0, 255).
void CSkinObject::LoadImageMap(CRgn& outRegion, long& outWidth, long& outHeight,
							   long& outImageCount, const char* inFileName, char* pBuffer)
{
	HRGN hRgn = NULL; 

/*	COLORREF crTransparentColor = RGB(255,0,255);
	int rTol = 10;
	int gTol = 10;
	int bTol = 10;*/

	CString skinFilePath = MiscUtils::GetSkinFolder() + "\\" + inFileName;
//	HBITMAP bitmapUsed = NULL;
//	bitmapUsed = (HBITMAP)::LoadImage(0, skinFilePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if (mImageProcessor.LoadFile(skinFilePath))
	{
		long bmpWidth, bmpHeight, bmpBitcount;
		mImageProcessor.GetInfo(&bmpWidth, &bmpHeight, &bmpBitcount);

		//get the bitmap dimension.
		outWidth  = bmpWidth / mStateCount;
		outHeight = bmpHeight;
		outImageCount = bmpWidth /outWidth;

		//create a new region for the window.
		if (outRegion.m_hObject)
		{
			outRegion.DeleteObject();
		}
		outRegion.CreateRectRgn(0, 0, outWidth, outHeight);

        //--------------------------------------------------------------------------
		CBitmap bitmap;
		bitmap.Attach(mImageProcessor.GetImage());
		if (bitmap.m_hObject)
		{
			//Create the memory DC inside which we will scan the bitmap content
			HDC hMemDC = CreateCompatibleDC(0);
			if (hMemDC)
			{
				//create a 32 bits depth bitmap map and Select it into the memory dc
				BITMAPINFOHEADER RGB32BITSBITMAPINFO = {	
					    sizeof(BITMAPINFOHEADER),	// biSize 
					    bmpWidth,					// biWidth
					    bmpHeight,				    // biHeight
					    1,							// biPlanes
					    32,							// biBitCount 
					    BI_RGB,						// biCompression
					    0,							// biSizeImage
					    0,							// biXPelsPerMeter
					    0,							// biYPelsPerMeter
					    0,							// biClrUsed
					    0							// biClrImportant
				};

				void * pbits32 = 0;
				HBITMAP hbm32 = CreateDIBSection(hMemDC,(BITMAPINFO*)&RGB32BITSBITMAPINFO,DIB_RGB_COLORS,&pbits32,NULL,0);
				if (hbm32)
				{
					HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
					
					//get how many bytes per row we have for the bitmap bits (round up to 32 bits)
					BITMAP bm32;
					GetObject(hbm32, sizeof(bm32), &bm32);
					while (bm32.bmWidthBytes % 4)
						bm32.bmWidthBytes++;

					//copy the bitmap into the memory DC
					::BitBlt(hMemDC, 0, 0, bmpWidth, bmpHeight, mImageProcessor.GetImageDC(), 0, 0, SRCCOPY);
					
					//for the better performance ,we use the ExtCreateRegion() function to create the window Region
					#define ALLOC_UNIT  100
					DWORD maxRects = ALLOC_UNIT;
					HANDLE hData = GlobalAlloc(GMEM_MOVEABLE,sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
					RGNDATA * pData   = (RGNDATA*)GlobalLock(hData);
					pData->rdh.dwSize = sizeof(RGNDATAHEADER);
					pData->rdh.iType  = RDH_RECTANGLES;
					pData->rdh.nCount = pData->rdh.nRgnSize = 0;
					SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);

					//the transparent color is R > 246, G < 9, B > 246, please remember it.
					BYTE R = 246;
					BYTE G = 9;
					BYTE B = 246;
					
					//scan each the bitmap row from bottom to the top for the transparent pixels.
					BYTE * p32 = (BYTE*)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
					for (int y = 0; y < outHeight; y++)
					{
						//scan for the bitmap from left to right 
						for (int x = 0; x < outWidth; x++)
						{
							//scan for the continuous range of non transparetn pixel
							int  x0 = x;
							LONG * p = (LONG*)p32 + x;
							while (x < outWidth)
							{ 
								BYTE tmp = GetRValue(*p);
								if (tmp > R)
								{ 
									tmp = GetGValue(*p);
									if (tmp < G)
									{ 
										tmp = GetBValue(*p);
										if (tmp > B)
											break;
									}
								}
								p++;
								x++;
							}

							if (x > x0)
							{
								//add the pixels (x0, y) to (x, y+1) as a new rectangle in the region.
								if (pData->rdh.nCount >= maxRects)
								{
									GlobalUnlock(hData);
									maxRects += ALLOC_UNIT;
									hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
									pData = (RGNDATA *)GlobalLock(hData);
								}
								RECT *pr = (RECT *)&pData->Buffer;
								SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
								if (x0 < pData->rdh.rcBound.left)
									pData->rdh.rcBound.left = x0;
								if (y < pData->rdh.rcBound.top)
									pData->rdh.rcBound.top = y;
								if (x > pData->rdh.rcBound.right)
									pData->rdh.rcBound.right = x;
								if (y+1 > pData->rdh.rcBound.bottom)
									pData->rdh.rcBound.bottom = y + 1;
								pData->rdh.nCount++;

								// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
								// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
								if (pData->rdh.nCount == 2000)
								{
									HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
									if (hRgn)
									{
										CombineRgn(hRgn, hRgn, h, RGN_OR);
										DeleteObject(h);
									}
									else
									{
										hRgn = h;
									}

									pData->rdh.nCount = 0;
									SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
								}
							}
						}

						// Go to next row (remember, the bitmap is inverted vertically)
						p32 -= bm32.bmWidthBytes; 
					}

					//create or extend the region with the remaining rectangle
					HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
					if (hRgn)
					{
						CombineRgn(hRgn, hRgn, h, RGN_OR);
						DeleteObject(h);
					}
					else
					{
						hRgn = h;
					}

					// Clean up
					GlobalFree(hData);
					DeleteObject(SelectObject(hMemDC, holdBmp));
				}

				DeleteDC(hMemDC);
			}

			outRegion.CopyRgn(CRgn::FromHandle(hRgn));
			::DeleteObject(hRgn);
		}

		bitmap.Detach();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -