wingdi.cpp Line:1120 错误 GetRotatedBitmapNT

今天画图时,想把某个位图旋转画出来,网上搜了一个旋转的方法,

HBITMAP GetRotatedBitmapNT( HBITMAP hBitmap, float radians, COLORREF clrBack )

可是返回的是HBitmap ,我要把他转为CBitmap来使用,网上搜索CBitmap和HBitmap的转换方法,编写代码如下

   CBitmap bit;
    bit.LoadBitmap(IDB_SHead);//加载一个资源图片

   HBITMAP hbitmap=GetRotatedBitmapNT(bit,30,pDC->GetBkColor());

   bit.Attach(hbitmap);

结果运行一直报错 wingdi.cpp Line:1120 错误 跟踪是

ASSERT(m_hObject == NULL); // only attach once, detach on destroy 1120行

可是监视发现m_hObject不为NULL,不知道为啥么 ,这句"only attach once, detach on destroy " 是关键,可是刚开始我没读懂。后面看了别人的一篇文章明白了。

见: http://hi.baidu.com/chen_liluo/item/1bd03e0428c306db75cd3cfa
意识到可能是我的 bit 没有detach,果然在GetRotatedBitmapNT 函数中发现有对  bit 进行 selectobject 操作,

参考:http://www.cnblogs.com/CBDoctor/archive/2013/01/21/2869480.html  意识到selectobject 可能 会进行attach。

所以想出解决办法是:在  bit.Attach(hbitmap); 前面加上一句bit.Detach(); 即可。

 

 

CBitmap 不支持 =操作,所以赋值的话, 要通过其他途径。

 CBitmap和 HBitmap 的转换

 HBITMAP转成CBitmap: 
CBitmap*   pcBmp   =   CBitmap::FromHandle(hBmp); 
CBitmap   bmp;   
 bmp.Attach(hbmp); 
   
CBitmap转成HBITMAP:   
HBITMAP   hBmp   =   (HBITMAP)cBmp;

 

旋转位图函数如下:

// GetRotatedBitmapNT - Create a new bitmap with rotated image
// Returns - Returns new bitmap with rotated image
// hBitmap - Bitmap to rotate
// radians - Angle of rotation in radians
// clrBack - Color of pixels in the resulting bitmap that do
// not get covered by source pixels
HBITMAP GetRotatedBitmapNT( HBITMAP hBitmap, float radians, COLORREF clrBack )
{
	// Create a memory DC compatible with the display
	CDC sourceDC, destDC;
	sourceDC.CreateCompatibleDC( NULL );
	destDC.CreateCompatibleDC( NULL );
	
	// Get logical coordinates
	BITMAP bm;
	::GetObject(hBitmap, sizeof(bm), &bm);
	
	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 );
	
	// Restore DCs
	::SelectObject( sourceDC.m_hDC, hbmOldSource );
	::SelectObject( destDC.m_hDC, hbmOldDest );
	
	return hbmResult;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值