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

📄 deviceresolutionaware.h

📁 用EVC编写的添加背景音乐程序,其中还有线程的创建和终止,很好的学习示例
💻 H
📖 第 1 页 / 共 3 页
字号:
// This is a part of the Device Resolution Aware Library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Device Resolution Aware Library and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Device Resolution Aware Library product.

#ifndef __DEVICERESOLUTIONAWARE_H__
#define __DEVICERESOLUTIONAWARE_H__

#pragma once

#ifndef _WIN32_WCE
	#error DeviceResolutionAware.h is only supported on Windows CE platforms.
#endif // _WIN32_WCE

#ifndef __cplusplus
	#error DRA requires C++ compilation (use a .cpp suffix)
#endif

#include <windows.h>
#include <commctrl.h>

// glc
//
// To get this .h file to compile under eVC4, we must conditionally
// include the altcecrt.h file (which exports _ASSERTE function).
//
// Since altcecrt.h is not available for eVC4, you will find all
// references to _ASSERTE used conditionally as well.

#if (_WIN32_WCE >= 501)
#include <altcecrt.h>
#endif

namespace DRA
{

////////////////////////////////////////////////////////////////////////////////
// HIDPI functions and constants.
////////////////////////////////////////////////////////////////////////////////

#ifndef _DRA_ALTERNATE_DPI
const int HIDPI = 96;
#else
const int HIDPI = _DRA_ALTERNATE_DPI;
#endif

const unsigned int ILC_COLORMASK = 0x000000FE;

//
// The two inlines HIDPISIGN and HIDPIABS are there to ensure correct rounding
// for negative numbers passed into HIDPIMulDiv as x (we want -1.5 to round 
// to -1, 2.5 to round to 2, etc).  So we use the absolute value of x, and then 
// multiply the result by the sign of x.  Y and z should never be negative, as 
// y is the dpi of the device (presumably 192 or 96), and z is always 96, as 
// that is our original dpi we developed on.
//

inline int HIDPISIGN(int x)
{
	return (((x)<0)?-1:1);
}

inline int HIDPIABS(int x)
{
	return (((x)<0)?-(x):x);
}

inline int HIDPIMulDiv(int x, int y, int z)
{
	return ((((HIDPIABS(x)*(y))+((z)>>1))/(z))*HIDPISIGN(x));
}

//
// Cached values of GetDeviceCaps(LOGPIXELSX/Y) for the screen DC.
//

inline int GetScreenCaps(int nIndex)
{
	// Get the DC for the entire screen
	HDC hDC = ::GetDC(NULL);
	if(hDC == NULL)
	{

// glc
#if (_WIN32_WCE >= 501)
		_ASSERTE(hDC != NULL);
#else
		ASSERT(hDC != NULL);
#endif
		return -1;
	}

	int i = ::GetDeviceCaps(hDC, nIndex);
	::ReleaseDC(NULL, hDC);
	return i;
}

static inline int LogPixelsX()
{
#ifndef _DRA_ADJUSTABLE_RESOLUTION
	static int x = GetScreenCaps(LOGPIXELSX);
#else
	int x = GetScreenCaps(LOGPIXELSX);
#endif
	return x;
}

static inline int LogPixelsY()
{
#ifndef _DRA_ADJUSTABLE_RESOLUTION
	static int y = GetScreenCaps(LOGPIXELSY);
#else
	int y = GetScreenCaps(LOGPIXELSY);
#endif
	return y;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: GetDisplayMode
//
// PURPOSE: used to determined if the display is currently configured as 
//     portrait, square, or landscape.
//
// ON ENTRY:
//     No parameters
//
// ON EXIT:
//     Returns the appropraite value from the DisplayMode enum based on the
//     current display resolution.
//

enum DisplayMode
{
	Landscape = -1,
	Square = 0,
	Portrait = 1
};

inline DisplayMode GetDisplayMode()

{
	int nWidth = ::GetSystemMetrics(SM_CXSCREEN);
	int nHeight = ::GetSystemMetrics(SM_CYSCREEN);

	if(nHeight > nWidth)
	{
		return Portrait;
	}

	if(nHeight < nWidth)
	{
		return Landscape;
	}

   	return Square;
}

// glc
//
// The following 4 functions offer alternate ways to test the
// current screen orientation and resolution, and to double
// the size of a rectangle.

inline BOOL IsLandscapeMode()
{
	return (GetDisplayMode() == Landscape);
}

inline BOOL IsPortraitMode()
{
	return (GetDisplayMode() == Portrait);
}

inline BOOL IsSquareMode()
{
	return (GetDisplayMode() == Square);
}

inline BOOL IsHiResScreen()
{
	return (LogPixelsX() > 96);
}

inline void DoubleRect(LPRECT r) // glc - Caution: assuming hi res screen is exactly 192 DPI!
{
	r->bottom *= 2;
	r->left *= 2;
	r->right *= 2;
	r->top *= 2;
	return;
}



//
// Scaling inlines.
//

inline int SCALEX(int argX, int nLogPixelsX = LogPixelsX())
{
	return HIDPIMulDiv(argX, nLogPixelsX, HIDPI);
}

inline int SCALEY(int argY, int nLogPixelsY = LogPixelsY())
{
	return HIDPIMulDiv(argY, nLogPixelsY, HIDPI);
}

inline int UNSCALEX(int argX, int nLogPixelsX = LogPixelsX())
{
	return HIDPIMulDiv(argX, HIDPI, nLogPixelsX);
}

inline int UNSCALEY(int argY, int nLogPixelsY = LogPixelsY())
{
	return HIDPIMulDiv(argY, HIDPI, nLogPixelsY);
}

inline void SCALERECT(RECT rc)
{
#ifndef _DRA_ADJUSTABLE_RESOLUTION
	rc.left = SCALEX(rc.left);
	rc.right = SCALEX(rc.right);
	rc.top = SCALEY(rc.top);
	rc.bottom = SCALEY(rc.bottom);
#else // _DRA_ADJUSTABLE_RESOLUTION
	int nLogPixelsX = LogPixelsX();
	int nLogPixelsY = LogPixelsY();
	rc.left = SCALEX(rc.left, nLogPixelsX);
	rc.right = SCALEX(rc.right, nLogPixelsX);
	rc.top = SCALEY(rc.top, nLogPixelsY);
	rc.bottom = SCALEY(rc.bottom, nLogPixelsY);
#endif // _DRA_ADJUSTABLE_RESOLUTION
}

inline void SCALEPT(POINT pt)
{
	pt.x = SCALEX(pt.x);
	pt.y = SCALEY(pt.y);
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: StretchIcon
//
// PURPOSE: stretches an icon to the specified size on 4.21 devices and later.
//     On 4.20 and previous revisions of the OS, this is a no-op.
//
// ON ENTRY:
//     HICON hiconIn: the icon to stretch.
//     HICON* phiconOut: the stretched icon.
//     INT cxIcon: the desired width of the icon.
//     INT cyIcon: the desired height of the icon.
//
// ON EXIT:
//     Returns TRUE on success, FALSE on failure.
//

inline BOOL StretchIcon(
	HICON hiconIn,
	HICON* phiconOut,
	int cxIcon,
	int cyIcon)
{
	HBITMAP hBmpTemp;

	*phiconOut = NULL;
	
	HDC hdc = ::CreateCompatibleDC(NULL);
	if(hdc == NULL)
	{
		return FALSE;
	}

	BOOL bRet = FALSE;
	
	HBITMAP hbmMask = ::CreateCompatibleBitmap(hdc, cxIcon, cyIcon);
	if(hbmMask != NULL)
	{
		HBITMAP hbmOld = static_cast<HBITMAP>(::SelectObject(hdc, hbmMask));
		if(hbmOld != NULL)
		{
			BOOL bRet2 = ::DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK);
			if(bRet2 != FALSE)
			{
				HBITMAP hbmImage = ::CreateBitmap(cxIcon, cyIcon, 1, ::GetDeviceCaps(hdc, BITSPIXEL), NULL);
				if(hbmImage != NULL)
				{
					hBmpTemp = static_cast<HBITMAP>(::SelectObject(hdc, hbmImage));
					if(hBmpTemp != NULL)
					{
						bRet2 = ::DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE);
						if(bRet2 != FALSE)
						{
							ICONINFO iconinfo;
							::memset(&iconinfo, 0, sizeof(iconinfo));
							iconinfo.fIcon = TRUE;
							iconinfo.hbmColor = hbmImage;
							iconinfo.hbmMask = hbmMask;
							
							*phiconOut = ::CreateIconIndirect(&iconinfo);
							if(phiconOut != NULL)
							{
								bRet = TRUE;
							}
						}
					}
// Free the resources, but don't need to put restore original objects for deleted DCs.
					// yes you do, dummy, if you want the delete to work! glc
					::SelectObject(hdc, hbmOld);
					::DeleteObject(hbmImage);
				}
			}
		}
		::SelectObject(hdc, hbmOld);
		::DeleteObject(hbmMask);
	}
	::DeleteDC(hdc);

	return bRet;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: GetBitmapLogPixels
//
// PURPOSE: retrieves the DPI fields of the specified bitmap.
//
// ON ENTRY:
//     HINSTANCE hinst: the HINSTANCE of the bitmap resource.
//     LPCTSTR lpbmp: the ID of the bitmap resource.  The MAKEINTRESOURCE 
//         macro can be used for integer IDs.
//     INT* pnLogPixelsX: the returned value for the horizontal DPI field of
//         the bitmap.  This value is never less than 96.
//     INT* pnLogPixelsY: the returned value for the vertical DPI field of
//         the bitmap.  This value is never less than 96.
//
// ON EXIT:
//     Returns TRUE on success, FALSE on failure.
//     

inline BOOL GetBitmapLogPixels(
	HINSTANCE hinst,
	LPCTSTR lpbmp,
	int* pnLogPixelsX,
	int* pnLogPixelsY)
{
	*pnLogPixelsX = 0;
	*pnLogPixelsY = 0;

	HRSRC hResource = ::FindResource(hinst, lpbmp, RT_BITMAP);
	if(!hResource)
	{
		return FALSE;
	}
	
	HGLOBAL hResourceBitmap = ::LoadResource(hinst, hResource);
	if(!hResourceBitmap)
	{
		return FALSE;
	}
	
	BITMAPINFO* pBitmapInfo = static_cast<BITMAPINFO*>(::LockResource(hResourceBitmap));
	if(!pBitmapInfo)
	{
		return FALSE;
	}

	// There are at least three values of PelsPerMeter used for 96 DPI bitmap:
	//   0    - the bitmap just simply doesn't set this value
	//   2834 - 72 DPI (some editors just always put this in by default)
	//   3780 - 96 DPI
	// So any value of PelsPerMeter under 3780 should be treated as 96 DPI bitmap.

	int nPelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter;
	int nPelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter;

	// The formula for converting PelsPerMeter to LogPixels(DPI) is:
	//   LogPixels = PelsPerMeter / 39.37
	//   ( PelsPerMeter : Pixels per meter )
	//   ( LogPixels    : Pixels per inch  )
	// Note: We need to round up, which is why 19.68 is added (half of 39.37).
	// All values are multiplied by 100 to avoid converion to float and back to int.

	*pnLogPixelsX = static_cast<int>((nPelsPerMeterX * 100 + 1968) / 3937);
	*pnLogPixelsY = static_cast<int>((nPelsPerMeterY * 100 + 1968) / 3937);

	// There is only one system resource behind hResource, hResourceBitmap, 
	// and pBitmapInfo, which needs to be freed by calling DeleteObject
	::DeleteObject(static_cast<HGDIOBJ>(hResourceBitmap));

	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: ImageList_StretchBitmap
//
// PURPOSE: Stretches a bitmap containing a grid of images.  There are 
//     cImagesX images per row and cImagesY rows per bitmap.  Each image is 
//     scaled individually, so that there are no artifacts with non-integral 
//     scaling factors.  If the bitmap contains only one image, set cImagesX
//     and cImagesY to 1.
//
// ON ENTRY:
//     HBITMAP* phbm: a pointer to the bitmap to be scaled.
//     INT cxDstImg: the width of each image after scaling.
//     INT cyDstImg: the height of each image after scaling.
//     INT cImagesX: the number of images per row. This value should
//         evenly divide the width of the bitmap.
//     INT cImagesY: the number of rows in the bitmap. This value should 
//         evenly divide the height of the bitmap.
//
// ON EXIT:
//     Returns TRUE on success, FALSE on failure.     
//
//     If any scaling has occured, the bitmap pointed to by phbm is deleted
//     and is replaced by a new bitmap handle.
//

inline BOOL ImageList_StretchBitmap(

⌨️ 快捷键说明

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