很多时候登QQ只是为了截图..虽然系统有截屏键,浏览器什么的都有截屏插件,但总觉得QQ是做的做好的。只此一家别无分号。但有时候断网就悲催了。

于是周六周末摸索着自己实现了一下它的两个基本功能,截屏到剪切板和保存到文件。参考了两个版本的代码 。一个是VC 驿站上的QQ2008版本的截屏。它采用了橡皮筋类。一种是之前CSDN上一个牛人放出的模拟ipad效果的源代码里面的截屏功能。 1 先说QQ2008版本的 在程序启动后,鼠标会变成一个彩色的箭头。拖动后就会显示一个虚线框。这是通过 CRectTracker 派生的一个橡皮筋类 。之所以不直接使用基类,源代码的注释中说是 更新窗口,消除TRACK时的虚线框 接下来就是在程序中对橡皮筋类的初始化
//初始化像皮筋类 m_RectTracker.m_nStyle=CRectTracker::resizeInside|CRectTracker::dottedLine; m_RectTracker.m_rect.SetRect(-1,-1,-1,-1);
获取屏幕分辨率 截取屏幕到位图中 获取要更新的区域 和设置鼠标为彩色等一系列活动。具体看源代码。
最核心的一个函数就是拷贝屏幕 源代码如下
HBITMAP CScreenSpyDlg::CopyScreenToBitmap(LPRECT lpRect,BOOL bSave)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > m_xScreen)
nX2 = m_xScreen;
if (nY2 > m_yScreen)
nY2 = m_yScreen;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
if(bSave)
{
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
dcCompatible.SelectObject(m_pBitmap);
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
dcCompatible, nX, nY, SRCCOPY);
}
else
{
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
}
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//得到屏幕位图的句柄
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
if(bSave)
{
if (OpenClipboard())
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
//hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
}
return hBitmap;
}这里就完成了截取屏幕到剪切板的操作。
还有一点可能是我们这种菜鸟犯晕的地方,就是它如何做到在屏幕上画出一个虚线框的。这一点,实际上它是通过设置透明窗体实现的。所以看上去像是直接在桌面上画图。这个方法是一开始初始化就调用
CopyScreenToBitmap 这个函数 获取整个屏幕//截取屏幕到位图中
然后处理 WM_ERASEBKGND 消息 将获取到的屏幕设置为背景。所以看上去似乎是在桌面绘图。
m_pBitmap=CBitmap::FromHandle(CopyScreenToBitmap(&rect));
BOOL CScreenSpyDlg::OnEraseBkgnd(CDC* pDC)
{
BITMAP bmp;
m_pBitmap->GetBitmap(&bmp);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(m_pBitmap);
CRect rect;
GetClientRect(&rect);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
return TRUE;
} 收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2314
- 用户1336
- 访客11812443
每日一句
Let's seek joy in the simple, quiet moments.
让我们在简单宁静的时刻中寻找快乐。
让我们在简单宁静的时刻中寻找快乐。