VC 如何截取当前窗口的图像到剪切板上?高结贴率! 如题,在VC中,通过右键菜单截取当前窗口的图像到剪切板上?另问:如果当前窗口在windows窗口显示不全,会截取到么?怎么截? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 只说说思路:)方法一:1、创建一个内存DC和一个位图句柄(位图大小与窗口大小等大),并将二者建立关联;2、使用BitBlt方法将窗口DC的内容拷贝到内存DC;3、将位图内容拷贝至剪贴板,或直接存储为位图文件。如果当前窗口显示不全,比如超出屏幕边缘,或者被其它窗口覆盖,则无法抓到全图。 方法二:1、创建一个内存DC和一个位图句柄(位图大小与窗口大小等大),并将二者建立关联;2、使用CWnd::PrintWindow方法将窗口绘制到内存DC;3、将位图内容拷贝至剪贴板,或直接存储为位图文件。 用PrintWindow打印窗口至于操作剪切板你可以参考以下代码 if(!OpenClipboard()) return; //获取谱图图像 GetWaveGraphy(); EmptyClipboard(); SetClipboardData(CF_BITMAP, (HBITMAP)m_bitmapGraphy); CloseClipboard(); CRect rect; GetClientRect(&rect); CDC *hdc = GetDC(); HDC memDC = CreateCompatibleDC(*hdc); // 绘图内存DC HBITMAP mybitmap = CreateCompatibleBitmap(*hdc, rect.Width(), rect.Height()); SelectObject(memDC,mybitmap); BitBlt(memDC,0,0, rect.right-rect.left+1, rect.bottom-rect.top+1, *hdc,0,0,SRCCOPY); if(OpenClipboard()) { EmptyClipboard(); SetClipboardData(CF_BITMAP, (HBITMAP)mybitmap); CloseClipboard(); }我是这样截取的 已经可以获得了 、但我是用右键菜单截取的,菜单也会显示出来,如何去掉菜单呢? HDC hDCMem = CreateCompatibleDC(NULL); RECT rect; HBITMAP hBmp = NULL; HDC hDC=::GetDC(m_hWnd); ::GetClientRect(m_hWnd, &rect); hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top); ::ReleaseDC(m_hWnd, hDC ); HGDIOBJ hOld = SelectObject(hDCMem, hBmp); ::PrintWindow(m_hWnd, hDCMem, 0 ); SelectObject(hDCMem, hOld); DeleteObject(hDCMem); if (OpenClipboard()) { EmptyClipboard(); SetClipboardData(CF_BITMAP, hBmp); CloseClipboard(); }可以去掉菜单了 但被windows挡住的是黑色的 如何解决呢? 右键菜单应用时用TrackPopupMenu弹出的,菜单关闭后会返回(类似于模态对话框阻塞在这儿的),如果菜单里选择的是“截屏”,那么TrackPopupMenu返回后你再运行你的截屏函数就可以了 6楼 7楼的方法都不能截取被windows挡住的部分? 还有别的方法么? 这代码应该可以的下面代码是我以前用的,窗口不在最前面也可以截图,你可以试试:菜单遮挡的问题按我8楼的方法试试看,等TrackPopupMenu返回了再截图RECT drt; HWND dWnd = m_hWnd; ::GetWindowRect(dWnd,&drt); HDC dhdc = ::GetDC(dWnd); HDC memhdc = CreateCompatibleDC(dhdc); HBITMAP membmp = (HBITMAP)CreateCompatibleBitmap(dhdc,drt.right-drt.left,drt.bottom-drt.top); (HBITMAP)SelectObject(memhdc,membmp); BitBlt(memhdc,0,0,drt.right,drt.bottom,dhdc,0,0,SRCCOPY); To 10楼 and 11楼你们的代码都是一样的问题 就是当窗口不在Windows显示区域,有部分不在显示器内,截取的那部分就都是黑色的 是什么系统我项目里就是这么用的只是没有把全部代码贴出来但是原理就是这样不过我的操作系统是xp另外这篇博客里我也是用类似的方法获取窗口内容生成打印预览的http://blog.csdn.net/xianglitian/archive/2010/10/23/5960970.aspx 我的也是XP你截取的窗口如果在PC显示器下面,就是没有全部显示也能截取全部?我没显示的部分是黑色的 To xianglitian7楼是我写的代码,您看看哪的问题?哪里错了? To xianglitian7楼是我写的代码,您看看哪的问题?哪里错了? 我是MDI程序,被主窗口的一些窗体遮挡也是不行的,只能全部显示才可以 我试你的代码了,如下图,在1,2是不能截取全的,只有3可以。图是我直接print显示器窗口的。代码是:CRect rectWnd; CBitmap *pOldBitmap; CDC* pDC = GetDC(); CDC* pMemDC = new CDC; //获取窗口位图 GetWindowRect(rectWnd); CBitmap bitmapPrint; bitmapPrint.DeleteObject(); bitmapPrint.CreateCompatibleBitmap(pDC, rectWnd.Width(), rectWnd.Height()); pMemDC->CreateCompatibleDC(pDC); pOldBitmap = pMemDC->SelectObject(&bitmapPrint); PrintWindow(pMemDC, 0); pMemDC->SelectObject(pOldBitmap); //释放内存 ReleaseDC(pMemDC); delete pMemDC; if (OpenClipboard()) { EmptyClipboard(); SetClipboardData(CF_BITMAP, bitmapPrint); CloseClipboard(); } 下载我的“ScrollBitmap.rar”参考,可以满足你的要求 HDC hDCMem = CreateCompatibleDC(NULL); RECT rect; HBITMAP hBmp = NULL; HDC hDC=::GetDC(m_hWnd); ::GetClientRect(m_hWnd, &rect); hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top); ::ReleaseDC(m_hWnd, hDC ); HGDIOBJ hOld = SelectObject(hDCMem, hBmp); ::PrintWindow(m_hWnd, hDCMem, 0 ); SelectObject(hDCMem, hOld); DeleteObject(hDCMem); if (OpenClipboard()) { EmptyClipboard(); SetClipboardData(CF_BITMAP, hBmp); CloseClipboard(); } 我这不是一个dialog,而是在视图上画的,你的代码我出来的只是一个什么都没有的窗口,难道我编错了 能把你的主要代码贴一下么? UINT ID=::GetDlgCtrlID(m_hWnd); // afxDump << ID << " ID\n"; // size CRect rc; if(m_hWnd == 0) { ID=0; GetWindowRect(&rc);// the dialog } else { ::GetWindowRect(m_hWnd, &rc); } // create dc CClientDC dc(this); CDC dcMem; dcMem.CreateCompatibleDC(&dc); // create empty bmp HBITMAP bmp=CreateCompatibleBitmap(dc /* not dcMem */, rc.Width(),rc.Height()); dcMem.SelectObject(bmp); this->SendMessage(WM_PRINT,(WPARAM)dcMem.m_hDC, (LPARAM)(PRF_NONCLIENT | PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_OWNED)); // move bmp to clipboard CBitmap *pbmp=dcMem.GetCurrentBitmap(); OpenClipboard(); EmptyClipboard(); SetClipboardData(CF_BITMAP,pbmp->GetSafeHandle()); CloseClipboard(); // DeleteObject(bmp); http://www.xuyibo.org/kb/282.htm看下这个,希望对你有帮助 也是通过BitBlt画在实例上的 不是OnDraw 借用一个前辈的代码,直接画在视图类上 学习完会总结的 你的代码我出来的只是一个什么都没有的窗口,不是有2个按钮吗,“open”可以打开一个bmp,在项目下有一个“金山词霸” 呵呵,难不成是“当前窗口的图像”这个说法造成的误会,LZ实际想做的应该是将视图客户区中的显示内容变成位图数据、放到剪贴板上,是这样么?如此的话就更简单了,DC操作而已。 前提是绘制流程是独立的,而DC作为参数传递(设计模式中的策略模式),这样的话只要传入内存DC指针或句柄,执行一遍绘制流程就可以了。 怎么在vs2008中添加控件和组件? 【关于afxhtml的小问题?】 请教:如何在桌面(屏幕)上层用鼠标画一个矩形?注意不能影响桌面本身,也就是桌面还是正常使用的。 高分求visual c++图形用户界面开发指南的光盘实例 如何将视频文件的第一帧画面取出存成BMP文件? vc文件操作问题:如果在一个已经执行的文件中修改自己的数据 Dll问题 急,向高手请教:怎样快速的为区域绘制边指定大小的边框? 现在社会上看重的是证书还是经验? MFC中字符输入不了,功能实现不了,帮忙看看~ VC+ado+sql2005使用例子 mkfs.ext2格式化存储卡分区
2、使用BitBlt方法将窗口DC的内容拷贝到内存DC;
3、将位图内容拷贝至剪贴板,或直接存储为位图文件。如果当前窗口显示不全,比如超出屏幕边缘,或者被其它窗口覆盖,则无法抓到全图。
2、使用CWnd::PrintWindow方法将窗口绘制到内存DC;
3、将位图内容拷贝至剪贴板,或直接存储为位图文件。
至于操作剪切板你可以参考以下代码
if(!OpenClipboard())
return; //获取谱图图像
GetWaveGraphy(); EmptyClipboard();
SetClipboardData(CF_BITMAP, (HBITMAP)m_bitmapGraphy);
CloseClipboard();
GetClientRect(&rect);
CDC *hdc = GetDC();
HDC memDC = CreateCompatibleDC(*hdc); // 绘图内存DC
HBITMAP mybitmap = CreateCompatibleBitmap(*hdc, rect.Width(), rect.Height());
SelectObject(memDC,mybitmap); BitBlt(memDC,0,0, rect.right-rect.left+1, rect.bottom-rect.top+1, *hdc,0,0,SRCCOPY); if(OpenClipboard())
{
EmptyClipboard();
SetClipboardData(CF_BITMAP, (HBITMAP)mybitmap);
CloseClipboard();
}我是这样截取的 已经可以获得了 、但我是用右键菜单截取的,菜单也会显示出来,如何去掉菜单呢?
RECT rect;
HBITMAP hBmp = NULL;
HDC hDC=::GetDC(m_hWnd);
::GetClientRect(m_hWnd, &rect); hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
::ReleaseDC(m_hWnd, hDC ); HGDIOBJ hOld = SelectObject(hDCMem, hBmp); ::PrintWindow(m_hWnd, hDCMem, 0 );
SelectObject(hDCMem, hOld);
DeleteObject(hDCMem); if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
}可以去掉菜单了 但被windows挡住的是黑色的 如何解决呢?
6楼 7楼的方法都不能截取被windows挡住的部分? 还有别的方法么?
这代码应该可以的
下面代码是我以前用的,窗口不在最前面也可以截图,你可以试试:
菜单遮挡的问题按我8楼的方法试试看,等TrackPopupMenu返回了再截图
RECT drt;
HWND dWnd = m_hWnd;
::GetWindowRect(dWnd,&drt);
HDC dhdc = ::GetDC(dWnd);
HDC memhdc = CreateCompatibleDC(dhdc);
HBITMAP membmp = (HBITMAP)CreateCompatibleBitmap(dhdc,drt.right-drt.left,drt.bottom-drt.top);
(HBITMAP)SelectObject(memhdc,membmp);
BitBlt(memhdc,0,0,drt.right,drt.bottom,dhdc,0,0,SRCCOPY);
我项目里就是这么用的
只是没有把全部代码贴出来
但是原理就是这样
不过我的操作系统是xp
另外这篇博客里我也是用类似的方法获取窗口内容生成打印预览的
http://blog.csdn.net/xianglitian/archive/2010/10/23/5960970.aspx
我是MDI程序,被主窗口的一些窗体遮挡也是不行的,只能全部显示才可以
CRect rectWnd;
CBitmap *pOldBitmap;
CDC* pDC = GetDC();
CDC* pMemDC = new CDC; //获取窗口位图
GetWindowRect(rectWnd);
CBitmap bitmapPrint;
bitmapPrint.DeleteObject();
bitmapPrint.CreateCompatibleBitmap(pDC, rectWnd.Width(), rectWnd.Height());
pMemDC->CreateCompatibleDC(pDC);
pOldBitmap = pMemDC->SelectObject(&bitmapPrint);
PrintWindow(pMemDC, 0); pMemDC->SelectObject(pOldBitmap); //释放内存
ReleaseDC(pMemDC);
delete pMemDC; if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData(CF_BITMAP, bitmapPrint);
CloseClipboard();
}
RECT rect;
HBITMAP hBmp = NULL;
HDC hDC=::GetDC(m_hWnd);
::GetClientRect(m_hWnd, &rect); hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
::ReleaseDC(m_hWnd, hDC ); HGDIOBJ hOld = SelectObject(hDCMem, hBmp); ::PrintWindow(m_hWnd, hDCMem, 0 );
SelectObject(hDCMem, hOld);
DeleteObject(hDCMem); if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
}
我这不是一个dialog,而是在视图上画的,你的代码我出来的只是一个什么都没有的窗口,难道我编错了
能把你的主要代码贴一下么?
UINT ID=::GetDlgCtrlID(m_hWnd);
// afxDump << ID << " ID\n";
// size
CRect rc;
if(m_hWnd == 0)
{
ID=0;
GetWindowRect(&rc);// the dialog
}
else
{
::GetWindowRect(m_hWnd, &rc);
}
// create dc
CClientDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
// create empty bmp
HBITMAP bmp=CreateCompatibleBitmap(dc /* not dcMem */, rc.Width(),rc.Height());
dcMem.SelectObject(bmp);
this->SendMessage(WM_PRINT,(WPARAM)dcMem.m_hDC,
(LPARAM)(PRF_NONCLIENT | PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_OWNED));
// move bmp to clipboard
CBitmap *pbmp=dcMem.GetCurrentBitmap();
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,pbmp->GetSafeHandle());
CloseClipboard();
//
DeleteObject(bmp);
看下这个,希望对你有帮助
也是通过BitBlt画在实例上的
不是OnDraw 借用一个前辈的代码,直接画在视图类上 学习完会总结的
呵呵,难不成是“当前窗口的图像”这个说法造成的误会,LZ实际想做的应该是将视图客户区中的显示内容变成位图数据、放到剪贴板上,是这样么?如此的话就更简单了,DC操作而已。
这样的话只要传入内存DC指针或句柄,执行一遍绘制流程就可以了。