改进版截图函数(主要解决XP下保存对话框遮挡截图问题)
2014-03-09 19:12
447 查看
本函数的用法很简单,只需要添加到相应的相应函数中去即可。
我做了个简单的测试程序,已经上传到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);
下面是效果图:
我做了个简单的测试程序,已经上传到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);
下面是效果图:
相关文章推荐
- Easyui dialog对话框遮挡关闭按钮问题的解决
- photoshop 保存为web 图像老弹出的对话框的问题解决
- 在DLL中使用资源 - 主要是解决DLL的对话框导出问题
- CFileDialog的钩子函数解决对话框的多选之DoModal问题
- 解决Dialog对话框在输入法弹出时被遮挡的问题
- asp.net下载保存对话框中文乱码问题解决
- 一、 找出函数中存在的问题。以下题目均在Lab05项目中完成。2、 找出项目中存在的缺陷,并给出解决的方案(至少3个,不包含下面那个举例)。 说明:这里所说的缺陷不一定都是错误,而是明显需要改进的地方。 如:不可以无限输入密码,容易被暴力破解,存在安全隐患。
- win xp系统无法保存“运行”对话框中的dos命令问题的解决
- win xp系统无法保存“运行”对话框中的dos命令问题的解决
- 解决R语言中save()函数保存对象集合问题-->《R语言编程艺术》P195
- 第四章函数--函数初体验项目2-1用函数解决素数回文数问题(改进)
- Windows Movie Maker XP不能保存视频问题完全解决!
- 使用CFileDialog的钩子函数解决对话框的多选问题
- 单元测试实践的主要问题与解决(5)
- jQuery解决IE6、7、8不能使用 JSON.stringify 函数的问题
- Invalidate函数造成屏幕闪烁问题解决方法
- memcache保存php的session 解决多服务器的session问题
- 解决android有些机型截图返回 resultCode = 0的问题
- Android4.0中Alertdialog对话框点击边缘外部消失问题解决
- 完美解决PJ的Cookies保存时限问题!可选择记录登陆时长!