www.pudn.com > DiskInfo.tgz > DrawEx.cpp


#include "stdafx.h" 
#include "DrawEx.h" 
#include "useful.h" 
 
// Public DLL Functions //////////////////////////////////////// 
#define CPU_ID _asm _emit 0x0f _asm _emit 0xa2 
//#define RDTSC  _asm _emit 0x0f _asm _emit 0x31	 
#define htuA                    0x68747541            // hex value for htuA 
#define itne                    0x69746e65            // hex value for itne 
#define DMAc                    0x444d4163            // hex value for DMAc 
 
/*************************************************************** 
* wincpuidsupport() 
* 
* Inputs: none 
* 
* Returns: 
*  1 = CPUID opcode is supported 
*  0 = CPUID opcode is not supported 
***************************************************************/ 
 
WORD intel_wincpuidsupport()  
{ 
	int cpuid_support = 1; 
 
	_asm { 
        pushfd					// Get original EFLAGS 
		pop		eax 
		mov 	ecx, eax 
        xor     eax, 200000h	// Flip ID bit in EFLAGS 
        push    eax				// Save new EFLAGS value on 
        						//   stack 
        popfd					// Replace current EFLAGS value 
        pushfd					// Get new EFLAGS 
        pop     eax				// Store new EFLAGS in EAX 
        xor     eax, ecx		// Can not toggle ID bit, 
        jnz     support			// Processor=80486 
		 
		mov cpuid_support,0		// Clear support flag 
support: 
      } 
	 
	return cpuid_support; 
 
} // wincpuidsupport() 
 
 
/*************************************************************** 
* intel_check_IDProc() 
* 
* Inputs: none 
* 
* Returns: 
*  CPU Family (i.e. 4 if Intel 486, 5 if Pentium(R) Processor) 
* 
*  Note: This function also sets the global variable clone_flag 
***************************************************************/ 
 
WORD intel_check_IDProc()  
{ 
		int i=0; 
		WORD cpu_type=0xffff; 
		BYTE stepping=0; 
		BYTE model=0; 
		BYTE vendor_id[13]="------------"; 
		//BYTE intel_id[13]="GenuineIntel"; 
 
_asm {       
 
        xor     eax, eax		// Set up for CPUID instruction 
         
        CPU_ID                  // Get and save vendor ID 
 
        mov     dword ptr vendor_id, ebx 
        mov     dword ptr vendor_id[+4], edx 
        mov     dword ptr vendor_id[+8], ecx 
} 
 
_asm { 
 
        cmp     eax, 1			// Make sure 1 is valid input  
        						//   for CPUID 
         
        jl      end_IDProc		// If not, jump to end 
        xor     eax, eax 
        inc		eax 
        CPU_ID					// Get family/model/stepping/ 
        						//   features 
 
		mov 	stepping, al 
		and		stepping, 0x0f //0fh 
		 
		and 	al, 0f0h 
		shr		al, 4 
		mov 	model, al 
		 
		and		eax, 0f00h 
        shr     eax, 8			// Isolate family 
		and		eax, 0fh 
        mov     cpu_type, ax	// Set _cpu_type with family 
 
end_IDProc: 
		mov		ax, cpu_type 
      } 
	 
	return cpu_type; 
 
} // Check_IDProc() 
 
bool amd_isK6orLater() 
{	/* 
	unsigned long family=0; 
	unsigned long model_no=0; 
	unsigned long stepping=0; 
 
	unsigned long mode1=0, mode2=0, mode3=0; 
	unsigned long save_value; 
 
	_asm{ 
			// cpu_oK - run CPUID instruction to get cpu vendor 
			mov     eax, 0                          // function 0 
			db      0fh, 0a2h                       // CPUID opcode 
			mov     mode1, ebx              			 // load to string variable 
			mov     mode2, edx                      // load to string variable 
			mov     mode3, ecx                      // load to string variable 
		} 
 
		if ((mode1 == htuA) && (mode2 == itne) && (mode3 == DMAc))    // AMD CPU 
		{ 
			_asm { 
					mov    eax, 1                          // function 1 
					db     0fh, 0a2h                       // CPUID opcode 
					mov    save_value, eax                 // reload the whole cpu family 
			} 
 
			family = (save_value >> 8) & 0x0F;          // find out the familu number (8 - 11 bits in EAX register) 
 
			model_no = (save_value >> 4) & 0x0F;        // find out the model number  (4 - 7 bits in EAX register) 
 
			stepping = save_value & 0x0F;								  // find out the stepping number (0 - 3 bits in EAX register) 
      	 
		} 
 
	if (family == 5) 
	{ 
		if (model_no < 6) // K5 
			return false; 
		else // K6 
			return true; 
	} 
 
	if (family>5) // K7 or later 
		return true;*/ 
	return false; 
} 
 
 
int DrawAniRects(CRect* rcFr, CRect* rcTo) 
{ 
	CWnd* pDesktop = CWnd::GetDesktopWindow(); 
	 
	CWindowDC dc(pDesktop); 
	 
	int index = 10; 
	CRect rc(rcFr); 
	 
	int oldRop = dc.SetROP2(R2_NOT); 
	CPen* pOldPen = (CPen*)dc.SelectStockObject(BLACK_PEN); 
	CBrush* pOldBrush = (CBrush*)dc.SelectStockObject(NULL_BRUSH); 
	 
	int d1 = (rcTo->left - rcFr->left) / index; 
	int d2 = (rcTo->top - rcFr->top) / index; 
	int d3 = (rcTo->right - rcFr->right) / index; 
	int d4 = (rcTo->bottom - rcFr->bottom) / index; 
	 
	for (int i=0; iGetWindowRect(rc); 
	pMain->ScreenToClient(rc); 
	 
	CDC *pDCFrom; 
	pDCFrom=pWndFrom->GetDC (); 
	m_dib1.PasteDC ( pDCFrom, 0, 0, rc.Width(), rc.Height()); 
	m_dib3.PasteDC ( pDCFrom, 0, 0, rc.Width(), rc.Height()); 
	pWndFrom->ReleaseDC ( pDCFrom ); 
	 
	CClientDC dcWndTo(pWndTo); 
	CDC dcTo; 
	dcTo.CreateCompatibleDC(&dcWndTo); 
	CBitmap bmpTo; 
	bmpTo.CreateCompatibleBitmap(&dcWndTo, rc.Width(), rc.Height()); 
	CBitmap * pOldbmp = dcTo.SelectObject(&bmpTo); 
	SetWindowPos(pWndFrom->GetSafeHwnd(), HWND_TOP, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE); 
	pWndTo->ShowWindow(SW_SHOW); 
	pWndTo->SendMessage(WM_PRINT, (WPARAM) dcTo.GetSafeHdc(), (LPARAM) PRF_CLIENT|PRF_CHILDREN|PRF_OWNED); 
	m_dib2.PasteDC ( &dcTo, 0, 0, rc.Width(), rc.Height()); 
	dcTo.SelectObject(pOldbmp); 
 
	//m_draw.DrawDib ( &m_dib2, dc.GetSafeHdc(), 0, 0, 
	//		rc.Width(), rc.Height(), DDF_HALFTONE ); 
	 
	SetWindowPos(pWndTo->GetSafeHwnd(), HWND_TOP, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW|SWP_SHOWWINDOW); 
	SetWindowPos(pWndFrom->GetSafeHwnd(), NULL, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER|SWP_HIDEWINDOW); 
 
	int index = 5; 
	//m_dib3.Fill(231,210,192); 
	for (int i=0; iGetSafeHwnd(), HWND_TOP, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW|SWP_SHOWWINDOW); 
	//SetWindowPos(pWndFrom->GetSafeHwnd(), NULL, 0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER|SWP_HIDEWINDOW); 
 
	return 1; 
} 
 
bool CFadeWindow::IsFastEnough() 
{ 
	bool bRet = false; 
 
	if ( intel_wincpuidsupport() ) 	// Determine whether CPUID  
	{ 
		if (intel_check_IDProc()>5) // Pentium Pro or later; 
			bRet = true; 
	}else // else not even pentium 
	{ 
		// Check if is K6 
		if (amd_isK6orLater()) 
			bRet = true; 
	} 
 
/* 
	DWORD data; 
	DWORD dataSize; 
	LONG result; 
	HKEY hKey; 
	result = ::RegOpenKeyEx (HKEY_LOCAL_MACHINE, 
		"Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey); 
 
	if (result == ERROR_SUCCESS) { 
		result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, 
			(LPBYTE)&data, &dataSize); 
		 
		if (data < 233) 
			bRet = false; 
		RegCloseKey (hKey); 
	}else 
		bRet = false;*/ 
 
	CWindowDC dc(AfxGetMainWnd()); 
	if( bRet && dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE) 
		bRet = false;	 
 
	return bRet; 
} 
 
void FillBmpRect(CDC* pDC, const CRect& rect, CBitmap* pBmp, int nBmpX, int nBmpY) 
{ 
	CDC memDC; 
	memDC.CreateCompatibleDC(pDC); 
	 
	CBitmap* pOldBitmap = (CBitmap*)memDC.SelectObject (pBmp); 
	 
	int nWidth = rect.Width(); 
	int nHeight = rect.Height(); 
	int nX = rect.left; 
	int nY = rect.top; 
	int cx = (nWidth / nBmpX) + 1;  
	int cy = (nHeight / nBmpY) + 1; 
	 
	int i, j, x1, y1; 
	for (i=0; iBitBlt (x1+nX, y1+nY, ((nWidth-x1)FillSolidRect(rect, RGB(255,255,255)); 
	CRect rc(rect); 
	rc.right = rc.left + (int)(double(rect.Width())*dPercent); 
	 
	COLORREF color; 
	if (dPercent<0.65) 
		color = RGB(128,255,128); 
	else if (dPercent<0.75) 
		color = RGB(0,128,255); 
	else if (dPercent<0.90) 
		color = RGB(255,255,128); 
	else 
		color = RGB(255,128,128); 
	 
	/*if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) 
	{ 
		color = RGB(192, 192, 192); 
		pDC->FillSolidRect(rc, color); 
	} 
	else*/ 
	FillGradient(pDC, rc, RGB(255,255,255), color); 
	 
	 
	CFont* pOldFont; 
	if (pFont) 
		pOldFont = pDC->SelectObject(pFont); 
	COLORREF oldTextColor = pDC->SetTextColor(RGB(0,0,0)); 
	pDC->SetBkMode(TRANSPARENT); 
	//pDC->SetBkColor(RGB(0,0,0)); 
	 
	CSize szText = pDC->GetTextExtent(strText); 
	pDC->TextOut(rect.left+(rect.Width()-szText.cx)/2,  
		rect.top+(rect.Height()-szText.cy)/2, strText); 
	//pDC->DrawText(strText, rectText, DT_CENTER|DT_VCENTER); 
	pDC->Draw3dRect(rect, RGB(96,96,96),  
		RGB(255, 255, 255)); 
	 
	if (pFont) 
		pDC->SelectObject(pOldFont); 
	pDC->SetTextColor(oldTextColor); 
} 
 
void TransparentBlt (HDC hdc, HBITMAP hBitmap, int xStart, 
					 int yStart, COLORREF cTransparentColor) 
{ 
	BITMAP     bm; 
	COLORREF   cColor; 
	HBITMAP    bmAndBack, bmAndObject, bmAndMem, bmSave; 
	HBITMAP    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; 
	HDC        hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; 
	POINT      ptSize; 
	 
	hdcTemp = CreateCompatibleDC(hdc); 
	SelectObject(hdcTemp, hBitmap);   // Select the bitmap 
	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); 
	ptSize.x = bm.bmWidth;            // Get width of bitmap 
	ptSize.y = bm.bmHeight;           // Get height of bitmap 
	DPtoLP(hdcTemp, &ptSize, 1);      // Convert from device 
	// to logical points 
	 
	// Create some DCs to hold temporary data. 
	hdcBack   = CreateCompatibleDC(hdc); 
	hdcObject = CreateCompatibleDC(hdc); 
	hdcMem    = CreateCompatibleDC(hdc); 
	hdcSave   = CreateCompatibleDC(hdc); 
	// Create a bitmap for each DC. 
	 
	// Monochrome DC 
	bmAndBack   = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); 
	 
	// Monochrome DC 
	bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); 
	bmAndMem    = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); 
	bmSave      = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); 
	 
	// Each DC must select a bitmap object to store pixel data. 
	bmBackOld   = (HBITMAP) SelectObject(hdcBack, bmAndBack); 
	bmObjectOld = (HBITMAP) SelectObject(hdcObject, bmAndObject); 
	bmMemOld    = (HBITMAP) SelectObject(hdcMem, bmAndMem); 
	bmSaveOld   = (HBITMAP) SelectObject(hdcSave, bmSave); 
	 
	// Set proper mapping mode. 
	SetMapMode(hdcTemp, GetMapMode(hdc)); 
	 
	// Save the bitmap sent here, because it will be overwritten. 
	BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); 
	 
	// Set the background color of the source DC to the color. 
	// contained in the parts of the bitmap that should be transparent 
	cColor = SetBkColor(hdcTemp, cTransparentColor); 
	 
	// Create the object mask for the bitmap by performing a BitBlt 
	// from the source bitmap to a monochrome bitmap. 
	BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, 
		SRCCOPY); 
	 
	// Set the background color of the source DC back to the original 
	// color. 
	SetBkColor(hdcTemp, cColor); 
	 
	// Create the inverse of the object mask. 
	BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, 
		NOTSRCCOPY); 
	 
	// Copy the background of the main DC to the destination. 
	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, 
		SRCCOPY); 
	 
	// Mask out the places where the bitmap will be placed. 
	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); 
	 
	// Mask out the transparent colored pixels on the bitmap. 
	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); 
	 
	// XOR the bitmap with the background on the destination DC. 
	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); 
	 
	// Copy the destination to the screen. 
	BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, 
		SRCCOPY); 
	 
	// Place the original bitmap back into the bitmap sent here. 
	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); 
	 
	// Delete the memory bitmaps. 
	DeleteObject(SelectObject(hdcBack, bmBackOld)); 
	DeleteObject(SelectObject(hdcObject, bmObjectOld)); 
	DeleteObject(SelectObject(hdcMem, bmMemOld)); 
	DeleteObject(SelectObject(hdcSave, bmSaveOld)); 
	 
	// Delete the memory DCs. 
	DeleteDC(hdcMem); 
	DeleteDC(hdcBack); 
	DeleteDC(hdcObject); 
	DeleteDC(hdcSave); 
	DeleteDC(hdcTemp); 
} 
 
 
void FillGradient(CDC *pDC, const CRect& rectClient, COLORREF m_clrStart, COLORREF m_clrEnd) 
{ 
	RECT rectFill;			   // Rectangle for filling band 
	float fStep;              // How wide is each band? 
	CBrush brush;			// Brush to fill in the bar	 
		 
	// First find out the largest color distance between the start and end colors.  This distance 
	// will determine how many steps we use to carve up the client region and the size of each 
	// gradient rect. 
	int r, g, b;							// First distance, then starting value 
	float rStep, gStep, bStep;		// Step size for each color 
	 
	// Get the color differences 
	r = (GetRValue(m_clrEnd) - GetRValue(m_clrStart)); 
	g = (GetGValue(m_clrEnd) - GetGValue(m_clrStart)); 
	b =  (GetBValue(m_clrEnd) - GetBValue(m_clrStart));	 
	 
	// Make the number of steps equal to the greatest distance 
	//int nSteps = max(abs(r), max(abs(g), abs(b))); 
	//TRACE("%d\n", nSteps); 
	int nSteps = 10; 
	 
	// Determine how large each band should be in order to cover the 
	// client with nSteps bands (one for every color intensity level) 
	fStep = (float)rectClient.Width() / (float)nSteps; 
	 
	// Calculate the step size for each color 
	rStep = r/(float)nSteps; 
	gStep = g/(float)nSteps; 
	bStep = b/(float)nSteps; 
	 
	// Reset the colors to the starting position 
	r = GetRValue(m_clrStart); 
	g = GetGValue(m_clrStart); 
	b = GetBValue(m_clrStart); 
	 
	 
	// Start filling bands 
	for (int iOnBand = 0; iOnBand < nSteps; iOnBand++)  
	{ 
		::SetRect(&rectFill, 
			rectClient.left + (int)(iOnBand * fStep),       // Upper left X 
			rectClient.top,									 // Upper left Y 
			rectClient.left + (int)((iOnBand+1) * fStep),          // Lower right X 
			rectClient.bottom);			// Lower right Y 
		 
		if (rectFill.right > rectClient.right) 
			rectFill.right = rectClient.right; 
		 
		// CDC::FillSolidRect is faster, but it does not handle 8-bit color depth 
		VERIFY(brush.CreateSolidBrush(RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand))); 
		pDC->FillRect(&rectFill,&brush); 
		VERIFY(brush.DeleteObject()); 
		//pDC->FillSolidRect(&rectFill, RGB(r+rStep*iOnBand, g + gStep*iOnBand, b + bStep *iOnBand)); 
	} 
}