改进版截图函数(主要解决XP下保存对话框遮挡截图问题)

本函数的用法很简单,只需要添加到相应的相应函数中去即可。

我做了个简单的测试程序,已经上传到CSDN共享,欢迎下载测试:http://download.csdn.net/detail/k616358281/7014243

下面是源代码:

(参考了网友们的代代码)

/************************************************************************/
/*
	本函数是在网上存在的截图程序的基础上进行了适当的改进。
	1.本函数集成了存储对话框的调用,可以直接放置到菜单栏的相应函数或者按钮的响应函数中去。
	2.本函数解决了原函数普遍存在的问题:对话框的遮挡问题,完美实现,不会出现闪屏现象。
	说明:本函数是在VC6.0环境下编写,系统为XP。由于使用的是静态链接,所以程序包会比较大
	这个是为了避免出现缺少.dll提示。
	有问题欢迎交流学习:461770984@qq.com
*/
	// TODO: Add extra validation here
	HWND hwnd=::FindWindow("#32770",_T("测试窗口"));//查找目标窗口并获取句柄
//	ASSERT(hwnd);
	CRect rect;
	CRect client_rect;
	::GetWindowRect(hwnd,&rect);
	ScreenToClient(&rect);
	::GetClientRect(hwnd,&client_rect);
	HDC hScrDC=::GetWindowDC(hwnd);
	ASSERT(hScrDC);
	HDC hMemDC=::CreateCompatibleDC(hScrDC);
	ASSERT(hMemDC);
	HBITMAP hBitmap=::CreateCompatibleBitmap(hScrDC,client_rect.Width(),client_rect.Height());//不截标题栏(菜单栏同理)
//	HBITMAP hBitmap=::CreateCompatibleBitmap(hScrDC,rect.Width(),rect.Height());//截标题栏(即非客户区域也截)
	ASSERT(hBitmap);
	HBITMAP holdBitmap=(HBITMAP)::SelectObject(hMemDC,hBitmap);
//  下面两行与上面截标题栏和不截标题栏对应,默认注释掉了带标题栏的部分。
	::BitBlt(hMemDC,0,0,rect.Width(),client_rect.Height(),hScrDC,0,client_rect.top-rect.top,SRCCOPY);
//	::BitBlt(hMemDC,0,0,rect.Width(),rect.Height(),hScrDC,0,0,SRCCOPY);
	BITMAP bitmap={0};
	::GetObject(hBitmap,sizeof(BITMAP),&bitmap);
	BITMAPINFOHEADER bi={0};
	BITMAPFILEHEADER bf={0};
	
	bi.biSize=sizeof(BITMAPINFOHEADER);
	bi.biWidth=bitmap.bmWidth;
	bi.biHeight=bitmap.bmHeight;
	bi.biCompression=BI_RGB;
	bi.biPlanes=1;
	bi.biBitCount=24;
	
	DWORD dwSize=((bitmap.bmWidth * 24 + 31) / 32) * 4 * bitmap.bmHeight;//这个我也还不知道是为什么这样算,反正就是计算位图的大小(不包括头文件)
	
	LPBITMAPINFOHEADER lpbi=(LPBITMAPINFOHEADER)malloc(dwSize+sizeof(BITMAPINFOHEADER));
	*lpbi=bi;
	::GetDIBits(hMemDC,hBitmap,0,bitmap.bmHeight,(BYTE*)lpbi+sizeof(BITMAPINFOHEADER),(BITMAPINFO*)lpbi,DIB_RGB_COLORS);
	dwSize+=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
	bf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
	bf.bfSize=dwSize;
	bf.bfType=0x4d42;
//完成截图复制工作,下面就开始保存

	CFileDialog m_FileDlg(FALSE);
	m_FileDlg.m_ofn.lpstrFilter="图片(*.bmp)\0*.bmp\0\0";
	m_FileDlg.m_ofn.lpstrDefExt="bmp";
	if (IDOK==m_FileDlg.DoModal())
	{
		try
		{
			CFile file;
			file.Open(m_FileDlg.GetPathName(),CFile::modeCreate|CFile::modeWrite);
			file.Write((BYTE*)&bf,sizeof(BITMAPFILEHEADER));
			file.Write((BYTE*)lpbi,dwSize);
			file.Close();
		}
		catch (CException* e)
		{
			e->ReportError();
			e->Delete();
		}
	}
	::free(lpbi);
	::SelectObject(hMemDC,holdBitmap);
	::DeleteObject(hBitmap);
	::DeleteDC(hMemDC);
	::ReleaseDC(hwnd,hScrDC);

下面是效果图:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值