最近在工作中要实现一个截图的功能,由于之前没接触过这类东西,搜索了大部分资料,终于完成了,总结下;
首先,所谓的桌面截图其实并不是在真正的桌面上截图,只是把当前屏幕的图片复制的自己创建的对话框中,作为对话框的背景,然后在自己的对话框中截图,好了废话不多说了,说说实现了;
1 要获取到桌面的截图,首先要获取到桌面的DC,得到桌面dc后,根据桌面dc,创建一个内存兼容的内存dc和内存位图bmp,然后把bmp选入当前内存dc,最后调用BitBlt把桌面dc复制到内存dc中(创建内存dc是为了双缓冲,防止屏幕闪烁)。
HDC dcScreen;2 在对话框的OnPaint函数中,把内存dc复制到对话框dc中,这样对话框就有桌面的图片了
HBITMAP m_bmpScreen;
HBITMAP hOldBitmap;
HDC m_dcMem;
dcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); //创建屏幕设备dc
m_size.cx = GetDeviceCaps(dcScreen, HORZRES);
m_size.cy= GetDeviceCaps(dcScreen, VERTRES);
m_dcMem = CreateCompatibleDC(dcScreen); //创建与设备dc兼容的内存dc
m_bmpScreen = CreateCompatibleBitmap(dcScreen, m_size.cx,m_size.cy);//创建于屏幕dc兼容的位图
hOldBitmap = (HBITMAP)SelectObject(m_dcMem,m_bmpScreen);
BitBlt(m_dcMem, 0, 0,m_size.cx, m_size.cy,dcScreen, 0, 0, SRCCOPY);
StretchBlt(dc,0,0,m_size.cx, m_size.cy,
m_dcMem,3 实现截图,截图首先要随着鼠标移动,画一个矩形区域,此处也要用到双缓冲技术
0,0,m_size.cx, m_size.cy,
SRCCOPY);
HDC mydc;4 截图功能 仿照qq截图,要把图片内容存入剪贴板
mydc = CreateCompatibleDC(dc);
HBITMAP bmp,oldbmp;
bmp = CreateCompatibleBitmap(dc,m_size.cx,m_size.cy);
oldbmp = (HBITMAP)SelectObject(mydc,bmp);
BitBlt(mydc,0,0,m_size.cx,m_size.cy,m_dcMem,0,0,SRCCOPY);
HPEN hPen = ::CreatePen(PS_DASHDOT, 1, RGB(255, 0, 0));
HBRUSH brush = (HBRUSH)GetStockObject(NULL_BRUSH);
HPEN oldpen = (HPEN)SelectObject(mydc,hPen);
HBRUSH oldbrush = (HBRUSH)SelectObject(mydc,brush);
MoveToEx(mydc,p_begin.x, p_begin.y,NULL);
LineTo(mydc,X, p_begin.y);
LineTo(mydc,X, Y);
LineTo(mydc,p_begin.x, Y);
LineTo (mydc,p_begin.x, p_begin.y);
p_end.x = X;
p_end.y = Y;
AnsiString str = "当前图片大小为:";
str += IntToStr((int)a);
str += "*";
str += IntToStr((int)b);
TextOut(mydc,X,Y+10,str.c_str(),strlen(str.c_str()));
StretchBlt(dc,0,0,m_size.cx, m_size.cy,
mydc,
0,0,m_size.cx, m_size.cy,
SRCCOPY);
SelectObject(mydc,oldpen);
SelectObject(mydc,oldbrush);
DeleteDC(mydc);
DeleteObject(bmp);
ReleaseDC(this->Handle, dc);
HDC dcSave;
state = 1;
dcSave = CreateCompatibleDC(NULL);
TPoint c_point;
c_point.x = ((t_begin.x - t_end.x)>0)?t_end.x:t_begin.x;
c_point.y = ((t_begin.y - t_end.y)>0)?t_end.y:t_begin.y;
BITMAP bm;
HBITMAP bitmap;
GetObject(m_bmpScreen,sizeof(bm),&bm);
bm.bmWidth = width;
bm.bmHeight = height;
bitmap = CreateBitmapIndirect(&bm);
HBITMAP bit = (HBITMAP)SelectObject(dcSave,bitmap);
StretchBlt(dcSave,0,0, width,height,
m_dcMem,c_point.x ,c_point.y,
width, height, SRCCOPY);
SelectObject(dcSave,bit);
if(::OpenClipboard(this->Handle))
{
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, bitmap);
::CloseClipboard();
}
5 从剪贴板取数据
if(::OpenClipboard(handle))6 存入本地 ,从剪贴板取得数据是HBITMAP,需要转化为TBitmap(保存本地有两种方法一种如下,两一种按照bmp的文件格式写文件)
{
bitmap = (HBITMAP)::GetClipboardData(CF_BITMAP);
::CloseClipboard();
return true;
}
Graphics::TBitmap *DrawBMP=new Graphics::TBitmap();
DrawBMP->Handle = bitmap;
DrawBMP->SaveToFile(filepath+".bmp");
delete DrawBMP;
ps:上述工程在c++ builder2009中用,在VC++ 中函数一样,写法可能会不一样
HBITMAP 是 bitmap的指针
CBitmap 是是mfc中封装bitmap的类;
BITMAP 是一个结构体,封装着bitmap的一些信息。定义了逻辑位图的高,宽,颜色格式和位值
三者之间的转化
HBITMAP hBitmap;
CBitmap bitmap;
BITMAP bm;
//下面是三者之间的联系:
bitmap.Attach(hBitmap);//由HBITMAP 得到关联的CBitmap
bitmap.GetBitmap(&bm); // 由CBitmap 得到关联的BITMAP
hBitmap=(HBITMAP)bitmap.GetSafeHandle();//由CBitmap得到相关的HBITMAP
工程地址(C++ builder ):点击打开链接
(MFC ): 点击打开链接