www.pudn.com > DlgScrSaver.rar > drawwnd.cpp


// drawwnd.cpp : implementation file 
// 
 
#include "stdafx.h" 
//#include  
#include  
#include  
#include "collect.h" 
#include "DlgScrSaver.h" 
#include "drawwnd.h" 
#include "CImage.h" 
#include "Meta.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char BASED_CODE THIS_FILE[] = __FILE__; 
#endif 
 
LPCTSTR CDrawWnd::m_lpszClassName = NULL; 
 
// LoadBMP		- Loads a BMP file and creates a logical palette for it. 
// Returns		- TRUE for success 
// sBMPFile		- Full path of the BMP file 
// phDIB		- Pointer to a HGLOBAL variable to hold the loaded bitmap 
//			  Memory is allocated by this function but should be  
//			  released by the caller. 
// pPal			- Will hold the logical palette 
BOOL LoadBMP( LPCTSTR sBMPFile, HGLOBAL* phDIB, CPalette* pPal ) 
{ 
	CFile file; 
	if( !file.Open( sBMPFile, CFile::modeRead) ) 
		return FALSE; 
 
	BITMAPFILEHEADER bmfHeader; 
	long nFileLen; 
 
	nFileLen = file.GetLength(); 
 
 
	// Read file header 
	if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)) 
		return FALSE; 
 
	// File type should be 'BM' 
	if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) 
		return FALSE; 
 
	HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nFileLen); 
	if (hDIB == 0) 
		return FALSE; 
 
	// Read the remainder of the bitmap file. 
	if (file.ReadHuge((LPSTR)hDIB, nFileLen - sizeof(BITMAPFILEHEADER)) != 
		nFileLen - sizeof(BITMAPFILEHEADER) ) 
	{ 
		::GlobalFree(hDIB); 
		return FALSE; 
	} 
 
 
	 
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; 
 
	int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :  
						1 << bmInfo.bmiHeader.biBitCount; 
 
	// Create the palette 
	if( nColors <= 256 ) 
	{ 
		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); 
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; 
 
		pLP->palVersion = 0x300; 
		pLP->palNumEntries = nColors; 
 
		for( int i=0; i < nColors; i++) 
		{ 
			pLP->palPalEntry[i].peRed = bmInfo.bmiColors[i].rgbRed; 
			pLP->palPalEntry[i].peGreen = bmInfo.bmiColors[i].rgbGreen; 
			pLP->palPalEntry[i].peBlue = bmInfo.bmiColors[i].rgbBlue; 
			pLP->palPalEntry[i].peFlags = 0; 
		} 
 
		pPal->CreatePalette( pLP ); 
 
		delete[] pLP; 
	} 
 
	*phDIB = hDIB; 
	return TRUE; 
} 
 
void DrawDIB(CRect& rect, CDC* pDC, HGLOBAL hDIB, CPalette* pPal ) 
{ 
	LPVOID	lpDIBBits;		// Pointer to DIB bits 
	BOOL	bSuccess=FALSE; 	// Success/fail flag 
 
	BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; 
	int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :  
						1 << bmInfo.bmiHeader.biBitCount; 
 
	if( bmInfo.bmiHeader.biBitCount > 8 ) 
		lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + 
			bmInfo.bmiHeader.biClrUsed) + 
			((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0)); 
	else 
		lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors); 
	 
	if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) ) 
	{ 
		pDC->SelectPalette(pPal, FALSE); 
		pDC->RealizePalette(); 
	} 
 
	int DestX = (rect.Width()- bmInfo.bmiHeader.biWidth) / 2; 
	int DestY = (rect.Height()- bmInfo.bmiHeader.biHeight) / 2; 
	int nDestWidth = bmInfo.bmiHeader.biWidth; 
	int nDestHeight = bmInfo.bmiHeader.biHeight; 
	 
	while (nDestWidth > rect.Width() || nDestHeight > rect.Height()) 
	{ 
		nDestWidth /= 2; 
		nDestHeight /= 2; 
	} 
	 
	//int DestX = (::GetSystemMetrics(SM_CXSCREEN)- bmInfo.bmiHeader.biWidth) / 2; 
	//int DestY = (::GetSystemMetrics(SM_CYSCREEN)- bmInfo.bmiHeader.biHeight) / 2; 
	if (DestX < 0) 
		DestX = 0; 
	if (DestY < 0) 
		DestY = 0; 
/* 
	::StretchDIBits(pDC->m_hDC, 					// hDC 
				   DestX,							// DestX 
				   DestY,							// DestY 
				   nDestWidth,						// nDestWidth 
				   nDestHeight,						// nDestHeight 
				   0,								// SrcX 
				   0,								// SrcY 
				   bmInfo.bmiHeader.biWidth,		// SrcWidth 
				   bmInfo.bmiHeader.biHeight,		// ScrHeight 
				   lpDIBBits,						// lpBits 
				   (LPBITMAPINFO)hDIB,				// lpBitsInfo 
				   DIB_RGB_COLORS,	 				// wUsage 
				   PATCOPY);						// ROP 
*/ 
	::SetDIBitsToDevice(pDC->m_hDC, 				// hDC 
				   DestX,							// DestX 
				   DestY,							// DestY 
				   nDestWidth,						// nDestWidth 
				   nDestHeight,						// nDestHeight 
				   0,								// SrcX 
				   0,								// SrcY 
				   0,								// nStartScan 
				   bmInfo.bmiHeader.biHeight,		// nNumScans 
				   lpDIBBits,						// lpBits 
				   (LPBITMAPINFO)hDIB,				// lpBitsInfo 
				   DIB_RGB_COLORS); 				// wUsage 
 
} 
 
void DrawImage(CRect& rect, CDC* pDC, CImage& img) 
{ 
	int DestX = (rect.Width()- img.GetWidth()) / 2; 
	int DestY = (rect.Height()- img.GetHeight()) / 2; 
/* no stretching 
	int nDestWidth = img.GetWidth(); 
	int nDestHeight = img.GetHeight(); 
	 
	while (nDestWidth > rect.Width() || nDestHeight > rect.Height()) 
	{ 
		nDestWidth /= 2; 
		nDestHeight /= 2; 
	} 
*/	 
	if (DestX < 0) 
		DestX = 0; 
	if (DestY < 0) 
		DestY = 0; 
	img.Draw(pDC, DestX, DestY); 
} 
 
void DrawMetafile(CRect& rect, CDC* pDC, CMetaFile& wmf) 
{ 
	int nDestWidth = wmf.GetWidth(); 
	int nDestHeight = wmf.GetHeight(); 
	 
	if (nDestWidth == 0) 
		nDestWidth = 1; 
	if (nDestHeight == 0) 
		nDestHeight = 1; 
 
	while (nDestWidth > rect.Width() || nDestHeight > rect.Height()) 
	{ 
		nDestWidth /= 2; 
		nDestHeight /= 2; 
	} 
	/* 
	while (nDestWidth < rect.Width()/2 && nDestHeight < rect.Height()/2) 
	{ 
		nDestWidth *= 2; 
		nDestHeight *= 2; 
	} 
	*/ 
	 
	int DestX = (rect.Width()- nDestWidth) / 2; 
	int DestY = (rect.Height()- nDestHeight) / 2; 
	 
	if (DestX < 0) 
		DestX = 0; 
	if (DestY < 0) 
		DestY = 0; 
	CRect rc(DestX, DestY, DestX+nDestWidth, DestY+nDestHeight); 
	CBrush brush(RGB(255,255,255)); 
	pDC->FillRect(&rc, &brush); 
	wmf.Display(pDC, rc); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawWnd 
void CDrawWnd::SearchFiles(const char* BitmapPath, const char* filter) 
{ 
	struct _finddata_t c_file; 
	long hFile; 
	char Filter[_MAX_PATH]; 
	strcpy(Filter, BitmapPath); 
	strcat(Filter, filter); 
    if ((hFile = _findfirst(Filter, &c_file)) != -1L) 
	{ 
		if ((c_file.attrib & _A_SUBDIR)==0) 
		{ 
			CString* str = new CString(BitmapPath); 
			(*str) += c_file.name; 
			BitmapList.Insert(str); 
			//os << (*str) << endl; 
		} 
		/* Find the rest of the .c files */ 
		while( _findnext( hFile, &c_file ) == 0 ) 
		{ 
			if ((c_file.attrib & _A_SUBDIR)==0) 
			{ 
				CString* str = new CString(BitmapPath); 
				(*str) += c_file.name; 
				BitmapList.Insert(str); 
				//os << (*str) << endl; 
			} 
		} 
 
		_findclose( hFile ); 
	} 
} 
 
CDrawWnd::CDrawWnd(BOOL bAutoDelete) 
{ 
	m_bAutoDelete = bAutoDelete; 
	m_nPos = 0; 
	m_nStep = 1; 
	m_nCounter = 0; 
	m_nTimerID = 123; 
	m_rgnLast.CreateRectRgn(0,0,0,0); 
 
	m_nWidth = AfxGetApp()->GetProfileInt("Config", "Width", 10); 
	m_nSteps = AfxGetApp()->GetProfileInt("Config", "Resolution", 10); 
	m_nStyle = AfxGetApp()->GetProfileInt("Config", "Style", PS_ENDCAP_ROUND|PS_JOIN_ROUND); 
	if (m_nSteps < 1) 
		m_nSteps = 1; 
	m_logbrush.lbStyle = m_logbrushBlack.lbStyle = BS_SOLID; 
	m_logbrush.lbHatch = m_logbrushBlack.lbHatch = 0; 
	m_logbrush.lbColor = RGB( 
		AfxGetApp()->GetProfileInt("Config", "ColorRed", 255), 
		AfxGetApp()->GetProfileInt("Config", "ColorGreen", 0), 
		AfxGetApp()->GetProfileInt("Config", "ColorBlue", 0)); 
	m_logbrushBlack.lbColor = RGB(0, 0, 0); 
 
	// initialize BitmapList 
	char DefaultPath[_MAX_PATH]; 
	HINSTANCE hModul = AfxGetInstanceHandle(); 
	::GetModuleFileName(hModul, DefaultPath, sizeof(DefaultPath)-1); 
 
	while (strlen(DefaultPath) > 0 && DefaultPath[strlen(DefaultPath)-1]!='\\') 
		DefaultPath[strlen(DefaultPath)-1] = 0; 
	BitmapPath = AfxGetApp()->GetProfileString("Config", "BitmapPath", DefaultPath); 
	if (BitmapPath.GetLength() == 0) 
	{ 
		BitmapPath = DefaultPath; 
	} 
	if (BitmapPath.GetAt(BitmapPath.GetLength()-1) != '\\') 
	{ 
		BitmapPath += "\\"; 
	} 
	//ofstream os("c:\\test.txt"); 
	//os << AfxGetApp()->m_pszAppName << endl; 
	//os << DefaultPath << endl; 
	//os << BitmapPath << endl; 
 
	// Metafiles 
	SearchFiles(BitmapPath, "*.wmf"); 
	SearchFiles(BitmapPath, "*.emf"); 
 
	// Bitmaps 
	SearchFiles(BitmapPath, "*.bmp"); 
	SearchFiles(BitmapPath, "*.dib"); 
	SearchFiles(BitmapPath, "*.rle"); 
 
	// JPEG 
	SearchFiles(BitmapPath, "*.jpg"); 
	SearchFiles(BitmapPath, "*.jpeg"); 
	SearchFiles(BitmapPath, "*.jpe"); 
	SearchFiles(BitmapPath, "*.jif"); 
	SearchFiles(BitmapPath, "*.jfif"); 
	 
	// GIF 
	SearchFiles(BitmapPath, "*.gif"); 
 
	// PNG 
	SearchFiles(BitmapPath, "*.png"); 
} 
 
CDrawWnd::~CDrawWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CDrawWnd, CWnd) 
	//{{AFX_MSG_MAP(CDrawWnd) 
	ON_WM_TIMER() 
	ON_WM_PAINT() 
	ON_WM_SIZE() 
	ON_WM_CREATE() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
/* 
void CDemoView::OnDraw(CDC* pDC) 
{ 
	CDemoDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
 
	CPoint pos(GetScrollPosition()); 
	CRect rect; 
	GetClientRect(&rect); 
	int width = rect.right - rect.left; 
	int height = rect.bottom - rect.top; 
 
	if (pDoc->GetImage()) 
	{ 
		int x = -pos.x; 
		int y = -pos.y; 
		if (width >= pDoc->GetImage()->GetWidth()) 
			x = (width - pDoc->GetImage()->GetWidth())/2; 
		if (height >= pDoc->GetImage()->GetHeight()) 
			y = (height - pDoc->GetImage()->GetHeight())/2; 
 
		CDC *dc = GetDC(); 
		CPalette *hOldPal = 0; 
		if (pDoc->GetImage()->GetPalette()) 
		{ 
			hOldPal = dc->SelectPalette(pDoc->GetImage()->GetPalette(), TRUE); 
			dc->RealizePalette(); 
		} 
 
		if (pDoc->GetStretchMode()) 
		{ 
			SetScrollSizes(MM_TEXT, 
				CSize(0,0)); 
			pDoc->GetImage()->Stretch(dc, 0, 0, width, height); 
		} 
		else 
		{ 
			SetScrollSizes(MM_TEXT, 
				CSize(pDoc->GetImage()->GetWidth(), pDoc->GetImage()->GetHeight())); 
			pDoc->GetImage()->Draw(dc, x, y); 
		} 
 
//		dc->SelectPalette(hOldPal, TRUE); 
		ReleaseDC(dc); 
	} 
} 
*/ 
 
void CDrawWnd::Draw(CDC& dc, int nWidth)  
{ 
	CBrush brush(RGB(0,0,0)); 
	CRect rect; 
	GetClientRect(rect); 
	dc.FillRect(&rect, &brush); 
 
	/* 
	BYTE* buffer = new BYTE[5000000]; 
	readpcx(buffer, "F:\\swag\\pas\\chess.pcx"); 
	*/ 
	/* 
	PCXHEADER hdr; 
	BYTE* buffer = ReadPCX("F:\\swag\\pas\\chess.pcx", hdr); 
	if (buffer) 
	{ 
		DisplayPCX(&dc, rect, hdr, buffer); 
	} 
	*/ 
	BOOL bOK; 
	long anz = BitmapList.Count(); 
	if (anz == 0) 
		return; 
 
	long index = m_nCounter % anz; 
	//long index = abs(rand()) % anz; 
	CPalette pal; 
	HGLOBAL hBmp = NULL; 
	bOK = LoadBMP(*(BitmapList.At(index)), &hBmp, &pal); 
	if (bOK) 
	{ 
		DrawDIB(rect, &dc, hBmp, &pal); 
		GlobalFree(hBmp); 
		return; 
	} 
	//else 
	CMetaFile emf; 
	emf.Read(*(BitmapList.At(index))); 
	if (emf.IsOK()) 
	{ 
		DrawMetafile(rect, &dc, emf); 
		return; 
	} 
	//else 
	CImage img(*(BitmapList.At(index))); 
	if (img.IsOK()) 
	{ 
		CPalette* hOldPal = NULL; 
		if (img.GetPalette()) 
		{ 
			hOldPal = dc.SelectPalette(img.GetPalette(), TRUE); 
			dc.RealizePalette(); 
		} 
		DrawImage(rect, &dc, img); 
		//img.Draw(&dc); 
		return; 
	} 
} 
 
void CDrawWnd::SetSpeed(int nSpeed) 
{ 
	KillTimer(m_nTimerID); 
	VERIFY((m_nTimerID = SetTimer(m_nTimerID, 20*(50+500-nSpeed*5), NULL)) != 0); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CDrawWnd message handlers 
 
void CDrawWnd::OnTimer(UINT nIDEvent)  
{ 
	if (nIDEvent == m_nTimerID) 
	{ 
		m_nCounter++; 
		m_nPos += m_nStep; 
		if (m_nPos > m_nSteps || m_nPos < 0) 
		{ 
			m_nStep = -m_nStep; 
			m_nPos += m_nStep; 
		} 
		CClientDC dc(this); 
		CRect rect; 
		GetClientRect(&rect); 
		int nWidth = m_nWidth * rect.Width() + ::GetSystemMetrics(SM_CXSCREEN)/2; 
		nWidth = nWidth/::GetSystemMetrics(SM_CXSCREEN); 
		Draw(dc, nWidth); 
	} 
	else	 
		CWnd::OnTimer(nIDEvent); 
} 
 
void CDrawWnd::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	m_rgnLast.DeleteObject(); 
	m_rgnLast.CreateRectRgn(0,0,0,0); 
	CBrush brush(RGB(0,0,0)); 
	CRect rect; 
	GetClientRect(rect); 
	dc.FillRect(&rect, &brush); 
	int nWidth = m_nWidth * rect.Width() + ::GetSystemMetrics(SM_CXSCREEN)/2; 
	nWidth = nWidth/::GetSystemMetrics(SM_CXSCREEN); 
	Draw(dc, nWidth); 
	// Do not call CWnd::OnPaint() for painting messages 
} 
 
void CDrawWnd::OnSize(UINT nType, int cx, int cy)  
{ 
	CWnd::OnSize(nType, cx, cy); 
	 
	m_nScale = cx/29; 
	m_nHeight = cy; 
} 
 
int CDrawWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	int nSpeed = AfxGetApp()->GetProfileInt("Config", "Speed", 1); 
	if (nSpeed < 0) 
		nSpeed = 0;	 
	SetSpeed(nSpeed); 
	srand( (unsigned)time( NULL ) ); 
	return 0; 
} 
 
BOOL CDrawWnd::Create(DWORD dwExStyle, DWORD dwStyle, const RECT& rect,  
	CWnd* pParentWnd, UINT nID, CCreateContext* pContext)  
{ 
    // Register a class with no cursor 
	if (m_lpszClassName == NULL) 
	{ 
    	m_lpszClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, 
			::LoadCursor(AfxGetResourceHandle(),  
			MAKEINTRESOURCE(IDC_NULLCURSOR))); 
	} 
 
	// TODO: Add your specialized code here and/or call the base class 
	return CreateEx(dwExStyle, m_lpszClassName, _T(""), dwStyle,  
		rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,  
		pParentWnd->GetSafeHwnd(), NULL, NULL ); 
} 
 
void CDrawWnd::PostNcDestroy()  
{ 
	if (m_bAutoDelete) 
		delete this; 
}