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

📄 skinbase.cpp

📁 WMI接口测试Demo程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	BYTE btRed = (BYTE)min(255, (int)(GetRValue(crA) * fAmountA + GetRValue(crB) * (1.0f - fAmountA)));
	BYTE btGreen = (BYTE)min(255, (int)(GetGValue(crA) * fAmountA + GetGValue(crB) * (1.0f - fAmountA)));
	BYTE btBlue = (BYTE)min(255, (int)(GetBValue(crA) * fAmountA + GetBValue(crB) * (1.0f - fAmountA)));
	
	return RGB(btRed, btGreen, btBlue);
}

COLORREF CSkinBase::VaryColor(COLORREF crColor, float fFactor)
{
	BYTE btRed = (BYTE)min(255, (int)(GetRValue(crColor) * fFactor));
	BYTE btGreen = (BYTE)min(255, (int)(GetGValue(crColor) * fFactor));
	BYTE btBlue = (BYTE)min(255, (int)(GetBValue(crColor) * fFactor));
	
	return RGB(btRed, btGreen, btBlue);
}

HRGN CSkinBase::BitmapToRegion(CBitmap* pBmp, COLORREF color)
{
	const DWORD RGNDATAHEADER_SIZE	= sizeof(RGNDATAHEADER);
	const DWORD ADD_RECTS_COUNT 	= 40;			// number of rects to be appended
	
	// get image properties
	BITMAP BM = { 0 };
	pBmp->GetBitmap(&BM);
	
	// create temporary dc
	CBitmap bmpMem;
	CDC dc, dcMem1, dcMem2;
	CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
	
	dcMem1.CreateCompatibleDC(pDC);
	dcMem2.CreateCompatibleDC(pDC);
	bmpMem.CreateCompatibleBitmap(pDC, BM.bmWidth, BM.bmHeight);
	
	CWnd::GetDesktopWindow()->ReleaseDC(pDC);
	
	CBitmap* pOldBM1 = dcMem1.SelectObject(pBmp);
	CBitmap* pOldBM2 = dcMem2.SelectObject(&bmpMem);

	// verify that the mask color is correct for the current bit depth
	color = dcMem2.SetPixel(0, 0, color);
	
	dcMem2.BitBlt(0, 0, BM.bmWidth, BM.bmHeight, &dcMem1, 0, 0, SRCCOPY);
	dcMem1.SelectObject(pOldBM1);
	dcMem1.DeleteDC();
	
	DWORD	dwRectsCount = BM.bmHeight; 		// number of rects in allocated buffer
	int 	nY, nX; 								// current position in mask image
	// where mask was found
	bool	bWasMask;						// set when mask has been found in current scan line
	bool	bIsMask;								// set when current color is mask color
	CRect	rLine;
	
	// allocate memory for region data
	// region data here is set of regions that are rectangles with height 1 pixel (scan line)
	// that's why nRgnStart allocation is <bm.biHeight> RECTs - number of scan lines in image
	RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
	
	// get pointer to RECT table
	LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
	
	// zero region data header memory (header  part only)
	memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
	
	// fill it by default
	pRgnData->dwSize	= RGNDATAHEADER_SIZE;
	pRgnData->iType 	= RDH_RECTANGLES;
	
	for ( nY = 0; nY < BM.bmHeight; nY++ )
	{
		bWasMask = true;
		rLine.SetRect(0, nY, 0, nY + 1);
		
		for ( nX = 0; nX < BM.bmWidth; nX++ )
		{
			// get color
			COLORREF crPixel = dcMem2.GetPixel(nX, nY);
			bIsMask = (crPixel == color);
			
			if (!bIsMask && bWasMask) // start of the rgn
			{
				rLine.left = nX;
				bWasMask = FALSE;
			}
			
			if (!bWasMask && (bIsMask || nX == BM.bmWidth - 1)) // end of rgn
			{
				bWasMask = true;
				rLine.right = bIsMask ? nX : nX + 1;
				
				// save current RECT
				// if this was a full line append to the last if it was full too
				BOOL bAdded = FALSE;
				
				if (pRgnData->nCount)
				{
					LPRECT pLastRect = &pRects[ pRgnData->nCount - 1];
					
					if (!pLastRect->left && !rLine.left && 
						pLastRect->right == BM.bmWidth - 1 && rLine.right == BM.bmWidth - 1)
					{
						pLastRect->bottom = rLine.bottom;
						bAdded = TRUE;
					}
				}
				
				// else add as a new line
				if (!bAdded)
				{
					pRects[ pRgnData->nCount++ ] = rLine;
					
					// if buffer full reallocate it with more room
					if ( pRgnData->nCount >= dwRectsCount )
					{
						dwRectsCount += ADD_RECTS_COUNT;
						
						// allocate new buffer
						LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
						
						// copy current region data to it
						memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
						
						// delte old region data buffer
						delete pRgnData;
						
						// set pointer to new regiondata buffer to current
						pRgnData = (RGNDATAHEADER*)pRgnDataNew;
						
						// correct pointer to RECT table
						pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
					}
				}
			}
		}
	}
	
	// create region
	HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
	CRect rBox;
	
	::GetRgnBox(hRgn, rBox);
	
	// release region data
	delete pRgnData;
	
	dcMem2.SelectObject(pOldBM2);
	dcMem2.DeleteDC();
	bmpMem.DeleteObject();
	
	return hRgn;
}

HMENU CSkinBase::MakeMenuCopy(const CMenu* pSrc)
{
	if (!pSrc)
		return NULL;
	
	CMenu menu;
	
	VERIFY (menu.CreatePopupMenu());
	ASSERT (::IsMenu(menu.m_hMenu));
	
	int nNumItems = pSrc->GetMenuItemCount();
	CString sLabel;
	
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii); // must fill up this field
	mii.fMask = MIIM_STATE | MIIM_DATA; 			// get the state of the menu item
				
	for (int nItem = 0; nItem < nNumItems; nItem++)
	{
		UINT uIDItem = pSrc->GetMenuItemID(nItem);
		pSrc->GetMenuString(nItem, sLabel, MF_BYPOSITION);
		UINT uFlags = (uIDItem == 0) ? MF_SEPARATOR : (uIDItem == (UINT)-1) ? MF_POPUP : MF_STRING;
		
		// special case: if a popup menu we must copy it too
		if (uFlags == MF_POPUP)
		{
			HMENU hPopup = MakeMenuCopy(pSrc->GetSubMenu(nItem));
			ASSERT (hPopup);
			
			uIDItem = (UINT)hPopup;
		}
		
		menu.AppendMenu(uFlags, uIDItem, sLabel);
		
		// make sure we copy the state too
		::GetMenuItemInfo(*pSrc, nItem, TRUE, &mii);
		::SetMenuItemInfo(menu, nItem, TRUE, &mii);
	}
	
	return menu.Detach();
}

// this one copies the menu without deleting the root
BOOL CSkinBase::CopyMenu(const CMenu* pSrc, CMenu* pDest)
{
	ASSERT (::IsMenu(pDest->m_hMenu));
	
	if (!::IsMenu(pDest->m_hMenu))
		return FALSE;
	
	ASSERT (::IsMenu(pSrc->m_hMenu));
	
	if (!::IsMenu(pSrc->m_hMenu))
		return FALSE;
	
	// delete all the existing items
	while (pDest->GetMenuItemCount())
		pDest->DeleteMenu(0, MF_BYPOSITION);
	
	// copy across
	int nNumItems = pSrc->GetMenuItemCount();
	CString sLabel;
	
	MENUITEMINFO mii;
	ZeroMemory(&mii, sizeof(mii));
	mii.cbSize = sizeof(mii); // must fill up this field
	mii.fMask = MIIM_STATE | MIIM_DATA; 			// get the state of the menu item
				
	for (int nItem = 0; nItem < nNumItems; nItem++)
	{
		UINT uIDItem = pSrc->GetMenuItemID(nItem);
		pSrc->GetMenuString(nItem, sLabel, MF_BYPOSITION);
		UINT uFlags = (uIDItem == 0) ? MF_SEPARATOR : (uIDItem == (UINT)-1) ? MF_POPUP : MF_STRING;
		
		// special case: if a popup menu we must copy it too
		if (uFlags == MF_POPUP)
		{
			HMENU hPopup = MakeMenuCopy(pSrc->GetSubMenu(nItem));
			ASSERT (hPopup);
			
			uIDItem = (UINT)hPopup;
		}
		
		pDest->AppendMenu(uFlags, uIDItem, sLabel);
		
		// make sure we copy the state too
		::GetMenuItemInfo(*pSrc, nItem, TRUE, &mii);
		::SetMenuItemInfo(*pDest, nItem, TRUE, &mii);
	}
	
	return TRUE;
}

BOOL CSkinBase::CopyBitmap(const CBitmap* pSrc, CBitmap* pDest)
{
	ASSERT (pDest);
	
	if (!pDest)
		return FALSE;
	
	pDest->DeleteObject();
	
	if (!pSrc || !pSrc->GetSafeHandle())
		return FALSE;
	
	CDC* pDC = CWnd::GetDesktopWindow()->GetDC();
	CDC dcMem1, dcMem2;
	BOOL bRes = FALSE;
	
	if (dcMem1.CreateCompatibleDC(pDC) && dcMem2.CreateCompatibleDC(pDC))
	{
		BITMAP bm;
		((CBitmap*)pSrc)->GetBitmap(&bm);
		
		if (pDest->CreateCompatibleBitmap(pDC, bm.bmWidth, bm.bmHeight))
		{
			ASSERT (CBitmap::FromHandle((HBITMAP)pDest->GetSafeHandle()) == pDest);
			
			CBitmap* pOldBM1 = dcMem1.SelectObject((CBitmap*)pSrc);
			CBitmap* pOldBM2 = dcMem2.SelectObject(pDest);
			
			dcMem2.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem1, 0, 0, SRCCOPY);
			bRes = TRUE;
			
			dcMem1.SelectObject(pOldBM1);
			dcMem2.SelectObject(pOldBM2);
			
		}
	}
	
	dcMem1.DeleteDC();
	dcMem2.DeleteDC();
	
	CWnd::GetDesktopWindow()->ReleaseDC(pDC);
	
	ASSERT (CBitmap::FromHandle((HBITMAP)pDest->GetSafeHandle()) == pDest);
	HANDLE* ph = (HANDLE*)((BYTE*)pDest + 4);  // after CObject
	ASSERT (ph[0] == pDest->GetSafeHandle());
	
	return bRes;
}

BOOL CSkinBase::ExtractResource(UINT nID, LPCTSTR szType, CString& sTempFilePath, HINSTANCE hInst)
{
	if (!hInst)
		hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nID), szType);
	
	if (!hInst)
		return FALSE;
	
	// compare time with that of module from which it was loaded
	CString sTempPath;
	CFileStatus fsRes, fsModule;
	CString sModulePath;
	::GetModuleFileName(hInst, sModulePath.GetBuffer(MAX_PATH + 1), MAX_PATH);
	sModulePath.ReleaseBuffer();
	
	if (!CFile::GetStatus(sModulePath, fsModule))
		return FALSE;
	
	// create temp filename
	::GetTempPath(MAX_PATH, sTempPath.GetBuffer(MAX_PATH));
	sTempPath.ReleaseBuffer();
	sTempFilePath.Format("%s%s_skin_%d.tmp", sTempPath, szType, nID);
	
	// see if the file has been created before
	if (!CFile::GetStatus(sTempFilePath, fsRes) || fsRes.m_mtime < fsModule.m_mtime)
	{
		// Load the resource into memory
		HRSRC hRes = FindResource(hInst, (LPCSTR)nID, szType);
		
		if (!hRes) 
		{
			TRACE("Couldn't find %s resource %d!\n", szType, nID);
			return FALSE;
		}
		
		DWORD len = SizeofResource(hInst, hRes);
		
		BYTE* lpRes = (BYTE*)LoadResource(hInst, hRes);
		ASSERT(lpRes);
		
		CFile file;
		
		if (file.Open(sTempFilePath, CFile::modeCreate | CFile::modeWrite))
		{
			file.Write(lpRes, len);
			file.Close();
			FreeResource((HANDLE)lpRes);
		}
		else
		{
			FreeResource((HANDLE)lpRes);
			return FALSE;
		}
	}
	
	return TRUE;
}

CWnd* CSkinBase::GetChildWnd(CWnd* pParent, LPCTSTR szClass, int nID)
{
	CWnd* pChild = pParent->GetWindow(GW_CHILD); 
	
	while (pChild)	  
	{
		if (CWinClasses::IsClass(*pChild, szClass))
		{
			if (nID == -1 || pChild->GetDlgCtrlID() == nID)
				return pChild;
		}
		pChild = pChild->GetNextWindow();
	}
	
	return NULL;
}

BOOL CSkinBase::BitBlt(CDC* pDCDest, 
					   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
					   CDC* pDCSrc, int nXOriginSrc, int nYOriginSrc, 
					   UINT uROP,	   
					   COLORREF crTransparent)
{
	if (crTransparent != (COLORREF)-1)
	{
		return TransparentBlt(pDCDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
							pDCSrc, nXOriginSrc, nYOriginSrc, nWidthDest, nHeightDest, crTransparent);
	}
	else
	{
		return pDCDest->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
							pDCSrc, nXOriginSrc, nYOriginSrc, uROP);
	}
	
	return TRUE;
}

BOOL CSkinBase::StretchBlt(CDC* pDCDest, 
						   int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
						   CDC* pDCSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,	  
						   UINT uROP,	   
						   COLORREF crTransparent)
{
	// check to see if this is really just a BitBlt
	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
	{
		return BitBlt(pDCDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
					   pDCSrc, nXOriginSrc, nYOriginSrc, uROP, crTransparent);
	}

	// else pick whether its transparent or not
	if (crTransparent != (COLORREF)-1)
	{
		return TransparentBlt(pDCDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
								pDCSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, crTransparent);
	}
	else
	{
		return pDCDest->StretchBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
								pDCSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, uROP);
	}
	
	return TRUE;
}

CString CSkinBase::GetTipText(LPCTSTR szText, BOOL bToolbar)
{
	CString sText(szText), sTip;
	
	if (sText.IsEmpty())
		return "";
	
	// tip text starts at '\n' 
	int nStartTip = bToolbar ? sText.Find('\n') : -1;
	
	if (bToolbar && nStartTip == -1) // no tip
		return "";
	
	sText = sText.Right(sText.GetLength() - nStartTip - 1);
	
	// strip '&' and '...' if present
	int nLen = sText.GetLength();
	sTip.Empty();
	
	for (int nPos = 0; nPos < nLen; nPos++)
	{
		if (sText[nPos] != '&' && sText[nPos] != '.')
			sTip += sText[nPos];
	}
	
	return sTip;
}

BOOL CSkinBase::ConvertToGrayScale(CBitmap* pBitmap, COLORREF crMask)
{
	CDC dcTemp;
	dcTemp.CreateCompatibleDC(NULL);
	
	BITMAP BM;
	pBitmap->GetBitmap(&BM);
	
	CBitmap* pBMOld = dcTemp.SelectObject(pBitmap);
	
	// now iterate all the pixels, converting each to grayscale

⌨️ 快捷键说明

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