设为首页 加入收藏

TOP

VC只用GDI实现位图展现简单特效(二)
2014-11-23 17:31:26 来源: 作者: 【 】 浏览:36
Tags:VC只用 GDI 实现 位图 展现 简单 特效
)x, (int)y, (int)w, (int)h, &dcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); Sleep(10); } CLEAN_CODE return 0; }

旋转变大比较复杂,在上网找到可以完成位图按任意弧度旋转的代码改了一下,使其可以指定显示的大小:

最后一个参数的颜色值,指定图像旋转后空出来的位置填充的颜色

HBITMAP GetRotatedBitmap(HBITMAP hBitmap, float radians, int width, int height, COLORREF clrBack)  
{  
	// Create a memory DC compatible with the display  
	CDC sourceDC, destDC;  
	sourceDC.CreateCompatibleDC( NULL );  
	destDC.CreateCompatibleDC( NULL );  
	
	// Get logical coordinates  
	BITMAP bm, bmOld;  
	::GetObject( hBitmap, sizeof( bm ), &bm );  
	bmOld = bm;
	bm.bmWidth = width;
	bm.bmHeight = height;
	
	float cosine = (float)cos(radians);  
	float sine = (float)sin(radians);  
	
	// Compute dimensions of the resulting bitmap  
	// First get the coordinates of the 3 corners other than origin  
	int x1 = (int)(bm.bmHeight * sine);  
	int y1 = (int)(bm.bmHeight * cosine);  
	int x2 = (int)(bm.bmWidth * cosine + bm.bmHeight * sine);  
	int y2 = (int)(bm.bmHeight * cosine - bm.bmWidth * sine);  
	int x3 = (int)(bm.bmWidth * cosine);  
	int y3 = (int)(-bm.bmWidth * sine);  
	
	int minx = min(0,min(x1, min(x2,x3)));  
	int miny = min(0,min(y1, min(y2,y3)));  
	int maxx = max(0,max(x1, max(x2,x3)));  
	int maxy = max(0,max(y1, max(y2,y3)));  
	
	int w = maxx - minx;  
	int h = maxy - miny;  
	
	// Create a bitmap to hold the result  
	HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h);  
	
	HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap );  
	HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult );  
	
	// Draw the background color before we change mapping mode  
	HBRUSH hbrBack = CreateSolidBrush( clrBack );  
	HBRUSH hbrOld = (HBRUSH)::SelectObject( destDC.m_hDC, hbrBack );  
	destDC.PatBlt( 0, 0, w, h, PATCOPY );  
	::DeleteObject( ::SelectObject( destDC.m_hDC, hbrOld ) );  
	
	// We will use world transform to rotate the bitmap  
	SetGraphicsMode(destDC.m_hDC, GM_ADVANCED);  
	XFORM xform;  
	xform.eM11 = cosine;  
	xform.eM12 = -sine;  
	xform.eM21 = sine;  
	xform.eM22 = cosine;  
	xform.eDx = (float)-minx;  
	xform.eDy = (float)-miny;  
	
	SetWorldTransform( destDC.m_hDC, &xform );  
	
	// Now do the actual rotating - a pixel at a time  
//	destDC.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY );  
	destDC.SetStretchBltMode(HALFTONE);
	destDC.StretchBlt(0, 0, bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, bmOld.bmWidth, bmOld.bmHeight, SRCCOPY);
	
	// Restore DCs  
	::SelectObject( sourceDC.m_hDC, hbmOldSource );  
	::SelectObject( destDC.m_hDC, hbmOldDest );  
	
	return hbmResult;  
}

只要是要控制当位图变到最大时旋转角度是0度,也就是说当变到最大时就不能再大了,但是如果角度不是0度也还是要转到0度去。

还有就是我使用了双缓冲,怎么还闪烁得这么厉害我也不清楚了。

/*旋转变大*/
UINT CGditestDlg::LargerWithSpin(LPVOID pParam)
{
//	READY_CODE
	CGditestDlg *pMainDlg = (CGditestDlg *)pParam;
	CDC *pDC = pMainDlg->GetDC();
	pMainDlg->Invalidate();
	EnumChildWindows(pMainDlg->GetSafeHwnd(), EnumChildProc, 0L);
	pDC->SetStretchBltMode(HALFTONE);
	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;
	}
	HBITMAP hBmp;
	CDC dcMem;
	CBitmap *pbmpRotated;
	BITMAP bm;
	int degree = 0;
	float width, height;
	float base = 0;
	long oldWidth, ol
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC版超级记事本 下一篇VC版八皇后

评论

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