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

📄 skinbase.cpp

📁 WMI接口测试Demo程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// SkinBase.cpp: implementation of the CSkinBase class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SkinBase.h"
#include "wclassdefines.h"
#include "winclasses.h"

//#define ACTIVATE_VIEWER
//#include "imageviewer.h"

#include <afxpriv.h>

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

// for transparency
typedef BOOL (WINAPI *LPSetLayeredWindowAttributes)
(
  HWND hwnd,           // handle to the layered window
  COLORREF crKey,      // specifies the color key
  BYTE bAlpha,         // value for the blend function
  DWORD dwFlags        // action
);

#ifndef SPI_SETMENUFADE
	#define SPI_GETMENUFADE 0x1012
	#define SPI_SETMENUFADE 0x1013
#endif

#ifndef WS_EX_LAYERED
	#define WS_EX_LAYERED           0x00080000

	// win 2000 layered windows support
	#define LWA_COLORKEY            0x00000001
	#define LWA_ALPHA               0x00000002

	#define ULW_COLORKEY            0x00000001
	#define ULW_ALPHA               0x00000002
	#define ULW_OPAQUE              0x00000004
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

int CSkinBase::s_nOSVer = -1;
PFNTRANSPARENTBLT CSkinBase::s_pfnFastTransparentBlt = NULL;
PFNGRADIENTFILL CSkinBase::s_pfnFastGradientFill = NULL;
BOOL CSkinBase::s_bThemingEnabled = (GetOS() >= SBOS_XP);

// don't use fast trasparent blt on win95/98 because msimg32.dll has a resource leak
BOOL CSkinBase::s_bSupportsFastTransparentBlt = (GetOS() < SBOS_ME) ? FALSE : -1;
BOOL CSkinBase::s_bSupportsFastGradientFill = (GetOS() < SBOS_ME) ? FALSE : -1;

CSkinBase::CSkinBase()
{
}

CSkinBase::~CSkinBase()
{
}

int CSkinBase::GetOS()
{
	if (s_nOSVer == -1) // first time
	{
		OSVERSIONINFO vinfo;
		vinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		
		BOOL rslt = GetVersionEx(&vinfo);
		
		if (rslt)
		{
			switch (vinfo.dwPlatformId)
			{
			case VER_PLATFORM_WIN32_NT:
				switch (vinfo.dwMajorVersion)
				{
				case 3: // nt351
					ASSERT (0); // not supported
					break;
					
				case 4: // nt4
					s_nOSVer = SBOS_NT4;
					break;
					
				case 5: // >= w2k
					switch (vinfo.dwMinorVersion)
					{
					case 0: // w2k
						s_nOSVer = SBOS_2K;
						break;
						
					case 1: // xp
						s_nOSVer = SBOS_XP;
						break;
						
					default: // > xp
						s_nOSVer = SBOS_XPP;
						break;
					}
					break;
					
					default: // > xp
						s_nOSVer = SBOS_XPP;
						break;
				}
				break;
				
				case VER_PLATFORM_WIN32_WINDOWS:
					ASSERT (vinfo.dwMajorVersion == 4);
					
					switch (vinfo.dwMinorVersion)
					{
					case 0: // nt4
						s_nOSVer = SBOS_95;
						break;
						
					case 10: // xp
						s_nOSVer = SBOS_98;
						break;
						
					case 90: // > xp
						s_nOSVer = SBOS_ME;
						break;
						
					default:
						ASSERT (0);
						break;
					}
					break;
					
					default:
						ASSERT (0);
						break;
			}
		}
	}
	
	return s_nOSVer;
}

BOOL CSkinBase::SupportsFastTransparentBlt()
{
	if (s_bSupportsFastTransparentBlt == -1) // first time
	{
		HINSTANCE hInst = LoadLibrary("msimg32.dll");
		
		if (hInst)
		{
			s_pfnFastTransparentBlt = (PFNTRANSPARENTBLT)GetProcAddress(hInst, "TransparentBlt");
			s_bSupportsFastTransparentBlt = (s_pfnFastTransparentBlt != NULL);
		}
		else
			s_bSupportsFastTransparentBlt = FALSE;
	}
	
	return s_bSupportsFastTransparentBlt;
}

BOOL CSkinBase::SupportsFastGradientFill()
{
	if (s_bSupportsFastGradientFill == -1) // first time
	{
		HINSTANCE hInst = LoadLibrary("msimg32.dll");
		
		if (hInst)
		{
			s_pfnFastGradientFill = (PFNGRADIENTFILL)GetProcAddress(hInst, "GradientFill");
			s_bSupportsFastGradientFill = (s_pfnFastGradientFill != NULL);
		}
		else
			s_bSupportsFastGradientFill = FALSE;
	}
	
	return s_bSupportsFastGradientFill;
}

BOOL CSkinBase::GradientFill(CDC* pDCDest, LPRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
{
	if (!lpRect)
		return FALSE;

	if (::IsRectEmpty(lpRect))
		return FALSE;

	if (crFrom == crTo)
	{
		pDCDest->FillSolidRect(lpRect, crFrom);
		return TRUE;
	}

	if (GradientFillFast(pDCDest, lpRect, crFrom, crTo, bHorz))
		return TRUE;

	// else
	return GradientFillSlow(pDCDest, lpRect, crFrom, crTo, bHorz);
}

BOOL CSkinBase::TransparentBlt(CDC* pDCDest, 
							   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
							   CDC* pDCSrc, 
							   int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, 	
							   UINT crTransparent)
{
	if (nWidthDest < 1) 
		return FALSE;
	
	if (nWidthSrc < 1) 
		return FALSE; 
	
	if (nHeightDest < 1) 
		return FALSE;
	
	if (nHeightSrc < 1) 
		return FALSE;
	
	if (TransparentBltFast(pDCDest, 
		nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
		pDCSrc, 
		nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,	 
		crTransparent))
		return TRUE;
	
	// else 
	return TransparentBltSlow(pDCDest, 
		nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
		pDCSrc, 
		nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc,	 
		crTransparent);
}

BOOL CSkinBase::TransparentBltFast(CDC* pDCDest, 		
								   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,	
								   CDC* pDCSrc, 		 
								   int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,	 
								   UINT crTransparent) 
{
	if (!SupportsFastTransparentBlt() || !s_pfnFastTransparentBlt)
		return FALSE;
	
	return s_pfnFastTransparentBlt(*pDCDest, 
									nXOriginDest, 
									nYOriginDest, 
									nWidthDest, 
									nHeightDest,
									*pDCSrc, 
									nXOriginSrc, 
									nYOriginSrc, 
									nWidthSrc, 
									nHeightSrc,	   
									crTransparent);
}

BOOL CSkinBase::TransparentBltSlow(CDC* pDCDest, 		
								   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,	
								   CDC* pDCSrc, 		 
								   int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,	 
								   UINT crTransparent) 
{
	CDC dcMem, dcMask;

	dcMask.CreateCompatibleDC(pDCDest);
	dcMem.CreateCompatibleDC(pDCDest);

	CBitmap bmMask, bmMem;

	// copy src bitmap to mem dc
	bmMem.CreateCompatibleBitmap(pDCDest, nWidthSrc, nHeightSrc);

	CBitmap* pOldBMMem = dcMem.SelectObject(&bmMem);
	dcMem.BitBlt(0, 0, nWidthSrc, nHeightSrc, pDCSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);

//	ShowDC(dcMem);
	
	// Create monochrome bitmap for the mask
	bmMask.CreateBitmap(nWidthSrc, nHeightSrc, 1, 1, NULL);
	CBitmap* pOldBMMask = dcMask.SelectObject(&bmMask);
	dcMem.SetBkColor(crTransparent);
	
	// Create the mask from the memory DC
	dcMask.BitBlt(0, 0, nWidthSrc, nHeightSrc, &dcMem, 0, 0, SRCCOPY);

//	ShowDC(dcMask);

	// Set the background in dcMem to black. Using SRCPAINT with black
	// and any other color results in the other color, thus making
	// black the transparent color
	dcMem.SetBkColor(RGB(0,0,0));
	dcMem.SetTextColor(RGB(255,255,255));
	dcMem.BitBlt(0, 0, nWidthSrc, nHeightSrc, &dcMask, 0, 0, SRCAND);

//	ShowDC(dcMem);
	
	// Set the foreground to black. See comment above.
//	pDCDest->SetStretchBltMode(COLORONCOLOR);
	pDCDest->SetStretchBltMode(HALFTONE);
	pDCDest->SetBkColor(RGB(255,255,255));
	pDCDest->SetTextColor(RGB(0,0,0));
	
//	CPoint ptOrg;
//	::GetBrushOrgEx(*pDCDest, &ptOrg);
//	::SetBrushOrgEx(*pDCDest, 0, 0, &ptOrg);

	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
	{
		pDCDest->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
//		ShowDC(*pDCDest);
	}
	else
	{
		pDCDest->StretchBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
						&dcMask, 0, 0, nWidthSrc, nHeightSrc, SRCAND);
//		ShowDC(*pDCDest);
	}
	
	// Combine the foreground with the background
	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
	{
		pDCDest->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &dcMem, 0, 0, SRCPAINT);
//		ShowDC(*pDCDest);
	}
	else
	{
		pDCDest->StretchBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
						&dcMem, 0, 0, nWidthSrc, nHeightSrc, SRCPAINT);
//		ShowDC(*pDCDest);
	}

	dcMask.SelectObject(pOldBMMask);
	dcMem.SelectObject(pOldBMMem);

	return TRUE;
}
/*
BOOL CSkinBase::TransparentBltSlow(CDC* pDCDest, 		
								   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,	
								   CDC* pDCSrc, 		 
								   int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,	 
								   UINT crTransparent) 
{
	CDC dcMem, dcMask;

	dcMask.CreateCompatibleDC(pDCDest);
	dcMem.CreateCompatibleDC(pDCDest);

	CBitmap bmMask, bmMem;

	// copy src bitmap to mem dc
	bmMem.CreateCompatibleBitmap(pDCDest, nWidthDest, nHeightDest);

	CBitmap* pOldBMMem = dcMem.SelectObject(&bmMem);

	dcMem.SetStretchBltMode(HALFTONE);
	CPoint ptOrg;
	::GetBrushOrgEx(dcMem, &ptOrg);
	::SetBrushOrgEx(dcMem, 0, 0, &ptOrg);

	dcMem.StretchBlt(0, 0, nWidthDest, nHeightDest, 
					pDCSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

//	ShowDC(dcMem);
	
	// Create monochrome bitmap for the mask
	bmMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
	CBitmap* pOldBMMask = dcMask.SelectObject(&bmMask);
	dcMem.SetBkColor(crTransparent);
	
	// Create the mask from the memory DC
	dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMem, 0, 0, SRCCOPY);

//	ShowDC(dcMask);

	// Set the background in dcMem to black. Using SRCPAINT with black
	// and any other color results in the other color, thus making
	// black the transparent color
	dcMem.SetBkColor(RGB(0,0,0));
	dcMem.SetTextColor(RGB(255,255,255));
	dcMem.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);

//	ShowDC(dcMem);
	
	// Set the foreground to black. See comment above.
	pDCDest->SetBkColor(RGB(255,255,255));
	pDCDest->SetTextColor(RGB(0,0,0));
	
	pDCDest->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
//	ShowDC(*pDCDest);
	
	// Combine the foreground with the background
	pDCDest->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &dcMem, 0, 0, SRCPAINT);
//	ShowDC(*pDCDest);

	dcMask.SelectObject(pOldBMMask);
	dcMem.SelectObject(pOldBMMem);

	return TRUE;
}
*/

BOOL CSkinBase::GradientFillFast(CDC* pDCDest, LPRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
{
	if (!SupportsFastGradientFill() || !s_pfnFastGradientFill)
		return FALSE;
	
	TRIVERTEX vert[2];
	vert[0].x      = lpRect->left;
	vert[0].y      = lpRect->top;
	vert[0].Red    = GetRValue(crFrom) << 8;
	vert[0].Green  = GetGValue(crFrom) << 8;
	vert[0].Blue   = GetBValue(crFrom) << 8;
	vert[0].Alpha  = 0x0000;

	vert[1].x      = lpRect->right;
	vert[1].y      = lpRect->bottom; 
	vert[1].Red    = GetRValue(crTo) << 8;
	vert[1].Green  = GetGValue(crTo) << 8;
	vert[1].Blue   = GetBValue(crTo) << 8;
	vert[1].Alpha  = 0x0000;

	GRADIENT_RECT gRect = { 0, 1 };

	return s_pfnFastGradientFill(*pDCDest, 
									vert,
									2,
									&gRect,
									1,
									bHorz ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V);
}

BOOL CSkinBase::GradientFillSlow(CDC* pDCDest, LPRECT lpRect, COLORREF crFrom, COLORREF crTo, BOOL bHorz)
{
	if (!pDCDest || !lpRect)
		return FALSE;

	int nWidth = lpRect->right - lpRect->left;
	int nHeight = lpRect->bottom - lpRect->top;

	if (bHorz)
	{
		for (int nX = lpRect->left; nX < lpRect->right; nX++)
			pDCDest->FillSolidRect(nX, lpRect->top, 1, nHeight, BlendColors(crFrom, crTo, (lpRect->right - nX) / (float)nWidth));
	}
	else
	{
		for (int nY = lpRect->top; nY < lpRect->bottom; nY++)
			pDCDest->FillSolidRect(lpRect->left, nY, nWidth, 1, BlendColors(crFrom, crTo, (lpRect->bottom - nY) / (float)nHeight));
	}

	return TRUE;
}

COLORREF CSkinBase::BlendColors(COLORREF crA, COLORREF crB, float fAmountA)

⌨️ 快捷键说明

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