最近,想自己写个独立的截图程序,网上看了很多资料,大致都一般无二,实现起来也有不少不足之处。最后,还是写了一些实验性的程序,现在贴出来:
以下是我的几点理解:
1、截图,顾名思义,即是将屏幕的某一部分或全部内容截取下来保存成文件。截取整个屏幕我就不说了,下面讲讲如何实现截取某个窗口和自定义范围的截取。
2、截取某个窗口,意思是对某个窗口内的内容进行截图操作,截取的图片以窗口的边界为边界。另外,这里所说的“窗口”包括各种控件窗口,例如对话框上的按钮,输入框等,也包括诸如浏览器地址栏,资源管理器侧边栏等等。
3、截取某个窗口,只要获得它的DC(设备上下文),在“复制”一份就可以了,可是我们要的结果是最终能够存成文件的图片,显然还需要许多后续的操作。
4、如果,仅仅是将某个窗口的图像复制到剪切板会容易得多,先不管如何确定截图窗口的问题,考虑将截图程序的主窗口图像复制到剪切板。
5、介绍第一个函数:功能是将某个窗口的图像复制到剪切板。
void CopyBitmapToClipboard(CWnd *wnd, BOOL FullWnd)
{
CDC *dc;
if(FullWnd)
{
/* 抓取整个窗口*/
dc = new CWindowDC(wnd);
}
else
{
/* 仅抓取客户区时*/
dc = new CClientDC(wnd);
}
CDC memDC;
memDC.CreateCompatibleDC(dc);
CBitmap bm;
CRect r;
if(FullWnd)
wnd->GetWindowRect(&r);
else
wnd->GetClientRect(&r);
CString s;
wnd->GetWindowText(s);
CSize sz(r.Width(), r.Height());
bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);
CBitmap * oldbm = memDC.SelectObject(&bm);
memDC.BitBlt(0, 0, sz.cx, sz.cy, dc, 0, 0, SRCCOPY);
//直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
wnd->OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, bm.m_hObject);
CloseClipboard();
//恢复原始环境
memDC.SelectObject(oldbm);
bm.Detach();
delete dc;
}
6、函数示例:vc6.0下新建基于基本对话框的MFC工程,工程名123
添加一个按钮,双击为其添加响应函数:
程序片段:
void CMy123Dlg::CopyBitmapToClipboard(CWnd *wnd, BOOL FullWnd)
{
CDC *dc;
if(FullWnd)
{
/* 抓取整个窗口*/
dc = new CWindowDC(wnd);
}
else
{
/* 仅抓取客户区时*/
dc = new CClientDC(wnd);
}
CDC memDC;
memDC.CreateCompatibleDC(dc);
CBitmap bm;
CRect r;
if(FullWnd)
wnd->GetWindowRect(&r);
else
wnd->GetClientRect(&r);
CString s;
wnd->GetWindowText(s);
CSize sz(r.Width(), r.Height());
bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);
CBitmap * oldbm = memDC.SelectObject(&bm);
memDC.BitBlt(0, 0, sz.cx, sz.cy, dc, 0, 0, SRCCOPY);
//直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
wnd->OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, bm.m_hObject);
CloseClipboard();
//恢复原始环境
memDC.SelectObject(oldbm);
bm.Detach();
delete dc;
// 加一句提示
MessageBox(_T("复制完成"));
}
// 按钮的响应函数
void CMy123Dlg::OnButton1()
{
// TODO: Add your control notification handler code here
CWnd * wnd = FromHandle(GetSafeHwnd()); // 将当前窗口的句柄转化为CWnd
CopyBitmapToClipboard(wnd, FALSE); // 调用复制函数
}
运行结果:
新建一个Word文档,按Ctrl + V,查看结果:
将函数的第2个参数改为TRUE:
显然,函数功能实现了,如果不要求存成文件,那么剩下的问题就是如何确定函数的第一个参数的问题了。