关于BITMAP位图选入DC

看到一段代码,内容是:

	
	//获取窗口DC
	HDC hdc = GetDC(hWnd);
	//获取窗口的客户区区域
	RECT rect;
	GetClientRect(hWnd, &rect);
	//获取当前窗口的位图
	HDC hMemDC = CreateCompatibleDC(hdc);
	HBITMAP hBitmapSrc;
	hBitmapSrc = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
	SelectObject(hMemDC, hBitmapSrc);
	BitBlt(hMemDC, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY);
	SaveBitmap(hBitmapSrc , "C:\\123.bmp");		// SaveBitmap()是自定义的一个函数,用来把传递进来的位图句柄保存成图片文件
	// 结果是C:\\123.bmp内容是hWnd的窗口内容



原来一直觉得,HBITMAP选进设备DC以后,是将图片数据拷贝到DC上,从这段代码当然这里自然而然猜想,HBITMAP选进DC后,对DC的操作会影响到HBIMAP。

于是添加了如下测试代码:


//把窗口填充成白色
	SelectObject(hdc, GetStockObject(WHITE_PEN));
	SelectObject(hdc, GetStockObject(WHITE_BRUSH));
	Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);

	HDC hMemDC2 = CreateCompatibleDC(hdc);
	SelectObject(hMemDC2, hBitmapSrc);
	BitBlt(hdc, 0, 0, rect.right, rect.bottom, hMemDC2, 0, 0, SRCCOPY);
先把原窗口拷贝成白色,然后再把选入了hBitmapSrc的内存DC拷贝到原窗口上,测试发现,窗口还是白色,无效。这是为什么呢。

百度下CreateCompatibleBitmap,发现百度百科里面介绍:


HDC hdc=GetDC(hwnd);
HDC memdc=CreateCompatibleDC(hdc);
RECT rc;
BITMAP bmp;
HBITMAP holdbmp,hbmp=LoadBitmap(hInstDVBRes,MAKEINTRESOURCE(IDB_CLOCK));//从资源加载位图
holdbmp=(HBITMAP)SelectObject(memdc,hbmp);//这里把hbmp的位图选择到兼容DC memdc,之后这个兼容DC就拥有和
//hbmp同样大小的绘图区域,注意超出位图返回的GDI输出都是无效的.
GetObject(hbmp,sizeof(BITMAP),&bmp);//这里获取 位图的大小信息,事实上也是兼容DC绘图输出的范围
SetRect(&rc,0,0,bmp.bmWidth,bmp.bmHeight);
DrawText(memdc,"Center Line Text" -1,&rc,DT_VCENTER|DT_SINGLELINE|DT_CENTER);//在兼容DC中间位置输出字符串
//这样以来我们就相当于把hbmp这个位图加上了文字标注,我们可以把这个增加了文字标注的位图保存起来.一个简单的图像处理基本就OK了.
SelectObject(memdc,holdbmp);//复原兼容DC数据.
DeleteDC(memdc);
ReleaseDC(hwnd, hdc);

这说明我的猜想是对的,如果HBITMAP选进了DC,对DC的操作的确会影响到HBITMAP。但代码测试不无效时为什么呢。
突然想到,可能使一个HBITMAP不能同时选进两个DC。做了如下测试
	//获取窗口DC
	HDC hdc = GetDC(hWnd);

	//获取窗口的客户区区域
	RECT rect;
	GetClientRect(hWnd, &rect);

	//获取当前窗口的位图
	HDC hMemDC = CreateCompatibleDC(hdc);
	HBITMAP hBitmapSrc;
	hBitmapSrc = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
	HGDIOBJ hOldBt = SelectObject(hMemDC, hBitmapSrc);	// 修改,保存老位图句柄
	BitBlt(hMemDC, 0, 0, rect.right, rect.bottom, hdc, 0, 0, SRCCOPY);

	//获取当前窗口位图的像素颜色数据
	BYTE *pBitmapDataSrc = new BYTE[(rect.right-rect.left)*(rect.bottom-rect.top)*4];
	GetBitmapBits(hBitmapSrc, (rect.right-rect.left)*(rect.bottom-rect.top)*4, pBitmapDataSrc);

	//把窗口填充成白色
	SelectObject(hdc, GetStockObject(WHITE_PEN));
	SelectObject(hdc, GetStockObject(WHITE_BRUSH));
	Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);

	TextOut(hMemDC, 100, 100, _T("123456abcd"), 10);		// 新加内容,为了验证是否是之后拷贝上去的,多画了点东西  
	SelectObject(hMemDC, hOldBt);							// 新加内容
	HDC hMemDC2 = CreateCompatibleDC(hdc);
	SelectObject(hMemDC2, hBitmapSrc);
	BitBlt(hdc, 0, 0, rect.right, rect.bottom, hMemDC2, 0, 0, SRCCOPY);
	return;


验证无误。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值