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

📄 deviceresolutionaware.h

📁 用EVC编写的添加背景音乐程序,其中还有线程的创建和终止,很好的学习示例
💻 H
📖 第 1 页 / 共 3 页
字号:
	HBITMAP hbmIn,
	HBITMAP* phbmOut,
	int cxDstImg,
	int cyDstImg,
	int cImagesX,
	int cImagesY)
{
	if(	phbmOut == NULL || 
		(cxDstImg == 0 && cyDstImg == 0) || 
		(cImagesX == 0 || cImagesY == 0))
	{
		return FALSE;
	}

	if (!hbmIn)
		return FALSE;

	BITMAP bm;
	int nSize = ::GetObject(hbmIn, sizeof(bm), &bm);
	if(nSize != sizeof(bm))
	{
		TCHAR szMsg[255];
		wsprintf(szMsg, TEXT("nSize = %d, sizeof(bm) = %d."), nSize, sizeof(bm));
		MessageBox(0, szMsg, TEXT("Status"), MB_TOPMOST);
		return FALSE;
	}

	// If you hit this ASSERT, that mean your passed in image count in row and
	//   the column number of images is not correct.

// glc
#if (_WIN32_WCE >= 501)
	_ASSERTE(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));
#else
	ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));
#endif

	int cxSrcImg = bm.bmWidth / cImagesX;
	int cySrcImg = bm.bmHeight / cImagesY;

	if(cxSrcImg == cxDstImg && cySrcImg == cyDstImg)
	{
		return TRUE;
	}

	if(cxDstImg == 0)
	{
		cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg);
	}
	else if(cyDstImg == 0)
	{
		cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg);
	}

	BOOL bRet = FALSE;
	HBITMAP hbmNew;

	HDC hdcSrc = ::CreateCompatibleDC(NULL);
	if(hdcSrc != NULL)
	{
		HDC hdcDst = ::CreateCompatibleDC(NULL);
		if(hdcDst != NULL)
		{
			HDC hdcScreen = ::GetDC(NULL);
			if(hdcScreen != NULL)
			{
				HBITMAP hbmOldSrc = static_cast<HBITMAP>(::SelectObject(hdcSrc, hbmIn));
				if(hbmOldSrc != NULL)
				{
					hbmNew = ::CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY);
					if(hbmNew != NULL)
					{
						HBITMAP hbmOldDst = static_cast<HBITMAP>(::SelectObject(hdcDst, hbmNew));
						if(hbmOldDst != NULL)
						{
							bRet = TRUE; // fix added by glc
							for(int j = 0, yDest = 0, yBmp = 0;
								(j < cImagesY) && (bRet != FALSE);
								++j, yDest += cyDstImg, yBmp += cySrcImg)
							{
								for(int i = 0, xDest = 0, xBmp = 0;
									(i < cImagesX) && (bRet != FALSE);
									++i, xDest += cxDstImg, xBmp += cxSrcImg)
								{
									bRet = ::StretchBlt(
										hdcDst, 
										xDest, 
										yDest, 
										cxDstImg, 
										cyDstImg,
										hdcSrc, 
										xBmp, 
										yBmp, 
										cxSrcImg, 
										cySrcImg,
										SRCCOPY);
								}
							}
						}
					}
				}
// Free the resources, but don't need to put restore original objects for deleted DCs.
				::ReleaseDC(NULL, hdcScreen);
			}
			::DeleteDC(hdcDst);
		}
		::DeleteDC(hdcSrc);
	}

	if(bRet != FALSE)
	{
		*phbmOut = hbmNew;
	}
	return bRet;
}

// glc
//
// A generic bitmap stretching call that replaces the HBITMAP that is passed in as the first arg.
//
// This was missing from the original code.

inline BOOL StretchBitmap(
    HBITMAP* phbm,
    int cxDstImg,
    int cyDstImg,
    int cImagesX,
    int cImagesY
    )
{
	HBITMAP hNewBitmap;
	BOOL bReturn;
	bReturn = ImageList_StretchBitmap(*phbm, &hNewBitmap, cxDstImg, cyDstImg, cImagesX, cImagesY); 
	if (bReturn)
	{
		DeleteObject(*phbm);
		*phbm = hNewBitmap;
	}
	return bReturn;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: ImageList_LoadImage
//
// PURPOSE: This function operates identically to ImageList_LoadImage, except
//     that it first checks the DPI fields of the bitmap (using 
//     GetBitmapLogPixels); compares it to the DPI of the screen
//     (using LogPixelsX() and LogPixelsY()), and performs scaling
//     (using ImageList_StretchBitmap) if the values are different.
//
// ON ENTRY:
//     See the MSDN documentation for ImageList_LoadImage.
//
// ON EXIT:
//     See the MSDN documentation for ImageList_LoadImage.
//

inline HIMAGELIST ImageList_LoadImage(
	HINSTANCE hinst,
	LPCTSTR lpbmp,
	int cx,
	int cGrow,
	COLORREF crMask,
	UINT uType,
	UINT uFlags)
{

	UINT flags = 0;
	int cy = 0;
	int cImages = 0;
	int cxImage = 0;
	int nSize = 0;


	if(	uType != IMAGE_BITMAP ||  // Image type is not IMAGE_BITMAP
		cx == 0)                  // Caller doesn't care about the dimensions of the image - assumes the ones in the file
	{
		return ::ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
	}

	int BmpLogPixelsX;
	int BmpLogPixelsY;
	if(!GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY))
	{
		return NULL;
	}

	HIMAGELIST piml = NULL;
	
	HBITMAP hbmImage = static_cast<HBITMAP>(::LoadImage(hinst, lpbmp, uType, 0, 0, uFlags));
	if(hbmImage == NULL)
	{
		goto cleanup;
	}

	BITMAP bm;
	nSize = ::GetObject(hbmImage, sizeof(bm), &bm);
	if(nSize != sizeof(bm))
	{
		goto cleanup;
	}

	if(BmpLogPixelsX == LogPixelsX())
	{
		// do not need to scale the bitmap
		piml = ::ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
		goto cleanup;
	}

	 cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, LogPixelsX());

	// Bitmap width should be multiple integral of image width.
	// If not, that means either your bitmap is wrong or passed in cx is wrong.

// glc
#if (_WIN32_WCE >= 501)
	_ASSERTE((bm.bmWidth % cxImage) == 0);
#else
	ASSERT((bm.bmWidth % cxImage) == 0);
#endif

	cImages = bm.bmWidth / cxImage;

	cy = HIDPIMulDiv(bm.bmHeight, LogPixelsY(), BmpLogPixelsY);

	HBITMAP hbmStretched;
	BOOL bRet;
	if((LogPixelsX() % BmpLogPixelsX) == 0)
	{
		bRet = ImageList_StretchBitmap(hbmImage, &hbmStretched, cx * cImages, cy, 1, 1);
	}
	else
	{
		// Here means the DPI is not integral multiple of standard DPI (96DPI).
		// So if we stretch entire bitmap together, we are not sure each indivisual
		//   image will be stretch to right place. It is controled by StretchBlt().
		//   (for example, a 16 pixel icon, the first one might be stretch to 22 pixels
		//    and next one might be stretched to 20 pixels)
		// What we have to do here is stretching indivisual image separately to make sure
		//   every one is stretched properly.
		bRet = ImageList_StretchBitmap(hbmImage, &hbmStretched, cx, cy, cImages, 1);
	}
	if(bRet == FALSE)
	{
		goto cleanup;
	}

	//UINT flags = 0;
	
	// ILC_MASK is important for supporting CLR_DEFAULT
	if(crMask != CLR_NONE)
	{
		flags |= ILC_MASK;
	}
	
	// ILC_COLORMASK bits are important if we ever want to Merge ImageLists
	if(bm.bmBits)
	{
		flags |= (bm.bmBitsPixel & ILC_COLORMASK);
	}

	// bitmap MUST be de-selected from the DC
	// create the image list of the size asked for.
	piml = ::ImageList_Create(cx, cy, flags, cImages, cGrow);

	if(piml)
	{
		int added;

// fixed by glc
#if 0
		if(crMask == CLR_NONE)
		{
			added = ::ImageList_Add(piml, hbmImage, NULL);
		}
		else
		{
			added = ::ImageList_AddMasked(piml, hbmImage, crMask);
		}
#else
		if(crMask == CLR_NONE)
		{
			added = ::ImageList_Add(piml, hbmStretched, NULL);
		}
		else
		{
			added = ::ImageList_AddMasked(piml, hbmStretched, crMask);
		}
#endif
		if(added < 0)
		{
			::ImageList_Destroy(piml);
			piml = NULL;
		}
	}
	
	::DeleteObject(hbmStretched);

cleanup:
	::DeleteObject(hbmImage);
	return piml;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: ImageList_ReplaceIcon
//
// PURPOSE: Replaces an icon in an ImageList, scaling it from its original size
//          to the size of the images in the ImageList.
//
// ON ENTRY:
//     See the MSDN documentation for ImageList_ReplaceIcon.
//
// ON EXIT:
//     See the MSDN documentation for ImageList_ReplaceIcon.
//

inline int ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
{
	int cxIcon, cyIcon;
	BOOL bRet = ::ImageList_GetIconSize(himl, &cxIcon, &cyIcon);
	if(bRet == FALSE)
	{
		return -1; // per MSDN documentation for ImageList_ReplaceIcon.
	}
	
	HICON hiconStretched;
	StretchIcon(hicon, &hiconStretched, cxIcon, cyIcon);
	
	int iRet;
	
	if(hiconStretched != NULL)
	{
		iRet = ::ImageList_ReplaceIcon(himl, i, hiconStretched);
		::DestroyIcon(hiconStretched);
	}
	else
	{
		iRet = ::ImageList_ReplaceIcon(himl, i, hicon);
	}

	return iRet;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: ImageList_AddIcon
//
// PURPOSE: Adds an icon to an ImageList, scaling it from its original size
//          to the size of the images in the ImageList.
//
// ON ENTRY:
//     See the MSDN documentation for ImageList_AddIcon.
//
// ON EXIT:
//     See the MSDN documentation for ImageList_AddIcon.
//

// ImageList_AddIcon is defined as a macro in commctrl.h
#ifdef ImageList_AddIcon
#undef ImageList_AddIcon
#endif

inline int ImageList_AddIcon(HIMAGELIST himl, HICON hicon)
{
	return DRA::ImageList_ReplaceIcon(himl, -1, hicon);
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: Rectangle
//
// PURPOSE: Draws a rectangle using the currently selected pen.  Drawing occurs
//    completely within the drawing rectangle (the rectangle has an "inside 
//    frame" drawing style).
//
// ON ENTRY:
//     HDC hdc: the display context of the drawing surface.
//     INT nLeft: left bound of rectangle
//     INT nTop: top bound of rectangle
//     INT nRight: right bound of rectangle plus one.
//     INT nBottom: bottom bound of rectangle plus one.
//
// ON EXIT:
//     Returns TRUE on success, FALSE on failure.
//

inline BOOL Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
{
	// Obtain current pen thickness
	HPEN hpenSel = static_cast<HPEN>(::GetCurrentObject(hdc, OBJ_PEN));
	if(hpenSel == NULL)
	{
		return FALSE;
	}
	
	LOGPEN lpenSel;
	int iRet = ::GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
	if(iRet == 0)
	{
		return FALSE;
	}

	int nOff = lpenSel.lopnWidth.x/2;
	    
	nLeft += nOff;
	nTop += nOff;
	nRight -= nOff;
	nBottom -= nOff;

	return ::Rectangle(hdc, nLeft, nTop, nRight, nBottom);
}
 
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: Polyline
//
// PURPOSE: Draws a polyline using the currently selected pen.  In addition,
//     this function provides control over how the line will be drawn.
//
// ON ENTRY:
//     HDC hdc: the display context of the drawing surface.
//     const POINT* lppt: array of POINTS that specify line to draw.
//     INT cPoints: number of points in array.
//     INT nStyle: the style the pen should be drawn in.  This may be an 
//        existing pen style, such as PS_SOLID, or one of the following styles:
//

⌨️ 快捷键说明

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