设为首页 加入收藏

TOP

VC只用GDI实现位图展现简单特效(一)
2014-11-23 17:31:26 来源: 作者: 【 】 浏览:34
Tags:VC只用 GDI 实现 位图 展现 简单 特效

展示截图(略大,4.24M):

\

这些把位图加载到内存DC上的代码需要重复使用,于是定义成宏:

#define READY_CODE								
CGditestDlg *pMainDlg = (CGditestDlg *)pParam;	
CDC *pDC = pMainDlg->GetDC();					
CBitmap bmp;									
if (1 == pMainDlg->m_counter)					
{												
	bmp.LoadBitmap(IDB_BITMAP1);				
	pMainDlg->m_counter = 2;					
}												
else if (2 == pMainDlg->m_counter)				
{												
	bmp.LoadBitmap(IDB_BITMAP2);				
	pMainDlg->m_counter = 3;					
}												
else											
{												
	bmp.LoadBitmap(IDB_BITMAP3);				
	pMainDlg->m_counter = 1;					
}												
CDC dcMem;										
dcMem.CreateCompatibleDC(pDC);					
dcMem.SelectObject(&bmp);						
BITMAP bm;										
bmp.GetBitmap(&bm);								
pMainDlg->Invalidate();							
EnumChildWindows(pMainDlg->GetSafeHwnd(),		
	EnumChildProc, 0L);

#define CLEAN_CODE			
dcMem.DeleteDC();			
bmp.DeleteObject();			
EnumChildWindows(			
	pMainDlg->GetSafeHwnd(),
	EnumChildProc, 1L);		

#define PI	3.14

//弧度 = 2π * 角度 / 360
#define RADIAN(degree)	((float)((2 * PI * degree) / 360))


/*从上飞入*/
UINT CGditestDlg::FlyIntoFromTop(LPVOID pParam)
{
	READY_CODE
	for (int ySrc = bm.bmHeight; ySrc >= 0; ySrc -= 10)
	{
		pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, ySrc, SRCCOPY);
		Sleep(1);
	}
	CLEAN_CODE
	return 0;
}

/*从左飞入*/
UINT CGditestDlg::FlyIntoFromLeft(LPVOID pParam)
{
	READY_CODE
	for (int xSrc = bm.bmWidth; xSrc >= 0; xSrc -= 10)
	{
		pDC->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, xSrc, 0, SRCCOPY);
		Sleep(1);
	}
	CLEAN_CODE
	return 0;
}

/*从上展开*/
UINT CGditestDlg::UnfoldFromTop(LPVOID pParam)
{
	READY_CODE
	for (int htDes = 0; htDes <= bm.bmHeight; htDes += 10)
	{
		pDC->BitBlt(0, 0, bm.bmWidth, htDes, &dcMem, 0, 0, SRCCOPY);
		Sleep(1);
	}
	CLEAN_CODE
	return 0;
}

/*从左展开*/
UINT CGditestDlg::UnfoldFromLeft(LPVOID pParam)
{
	READY_CODE
	for (int wtDes = 0; wtDes <= bm.bmWidth; wtDes += 10)
	{
		pDC->BitBlt(0, 0, wtDes, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);
		Sleep(1);
	}
	CLEAN_CODE
	return 0;
}

百叶窗就是把位图分块同步显示,原理比较简单。

/*水平百叶窗*/
UINT CGditestDlg::HorizontalWindow(LPVOID pParam)
{
	READY_CODE
	int n = bm.bmHeight / 8;
	for (int htDes = 0; htDes <= n; htDes += 1)
	{
		for (int i = 0; i < 8; i++)
		{
			pDC->BitBlt(0, n * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);
		}
		Sleep(10);
	}
	CLEAN_CODE
	return 0;
}

/*垂直百叶窗*/
UINT CGditestDlg::VerticalWindow(LPVOID pParam)
{
	READY_CODE
	int n = bm.bmWidth / 8;
	for (int wtDes = 0; wtDes <= n; wtDes += 1)
	{
		for (int i = 0; i < 8; i++)
		{
			pDC->BitBlt(n * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);
		}
		Sleep(10);
	}
	CLEAN_CODE
	return 0;
}

拉直其实和百叶窗相差不了多少,也是分块同步显示,但是每一块是慢慢变大的。

/*往下拉直*/
UINT CGditestDlg::StraightenToBottom(LPVOID pParam)
{
	READY_CODE
	int n = bm.bmHeight / 8;
	for (int htDes = 0; htDes <= n; htDes += 1)
	{
		for (int i = 0; i < 8; i++)
		{
			pDC->BitBlt(0, htDes * i, bm.bmWidth, htDes, &dcMem, 0, n * i, SRCCOPY);
		}
		Sleep(10);
	}
	CLEAN_CODE
	return 0;
}

/*往右拉直*/
UINT CGditestDlg::StraightenToRight(LPVOID pParam)
{
	READY_CODE
	int n = bm.bmWidth / 8;
	for (int wtDes = 0; wtDes <= n; wtDes += 1)
	{
		for (int i = 0; i < 8; i++)
		{
			pDC->BitBlt(wtDes * i, 0, wtDes, bm.bmHeight, &dcMem, n * i, 0, SRCCOPY);
		}
		Sleep(10);
	}
	CLEAN_CODE
	return 0;
}

由小变大主要是要保存图像比例和算位图从在哪个坐标显示,图像大小发生变化,坐标随之变化。可以先确定图像的宽,然后 长=宽*(高/2);x坐标=位图实际的宽/2-当前的宽/2,y坐标=位图实际的高/2-当前的高/2。

/*由小变大*/
UINT CGditestDlg::SmallToLarge(LPVOID pParam)
{
	READY_CODE
	float x, y, w, h;
	float base = 0;
	pDC->SetStretchBltMode(HALFTONE);
	while ((int)(base += 10) <= bm.bmWidth)
	{
		w = base;
		h = base * ((float)bm.bmHeight / (float)bm.bmWidth);
		x = (float)bm.bmWidth / 2 - w / 2;
		y = (float)bm.bmHeight / 2 - h / 2;
		pDC->StretchBlt((int
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC版超级记事本 下一篇VC版八皇后

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: