QQ2008和2012截屏の实现(C++源码)

很多时候登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 这个函数 获取整个屏幕//截取屏幕到位图中     
m_pBitmap=CBitmap::FromHandle(CopyScreenToBitmap(&rect));


然后处理 WM_ERASEBKGND 消息 将获取到的屏幕设置为背景。所以看上去似乎是在桌面绘图。


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;
}


源代码已经上传 有需要的同学可以看一下。高手请无视^_^ 












接下来是QQ2012这种方式
    QQ2012摒弃了08版的虚线框形式。而是采用了更炫的效果,首先在启动的时候讲这个屏幕弄的灰不溜秋的。然后将截取出来的区域正常显示,就造成了一种高亮效果。


     之前一直没弄明白它是怎么做的这个效果(郁闷的菜鸟ing..)后来参考了一下别人的源代码。它的实现方式是贴图。大量的贴图。不禁肃然起敬。这样都可以!.#$$%


      它的源代码和08的并没有多少本质的区别,所以就不多赘述了。主要就是那个灰色背景效果。还有就是多了一个加载工具栏的功能。工具栏提供了设置截屏为桌面壁纸的功能,保存为磁盘文件的功能。(设置为壁纸的功能存在BUG,暂时没时间去Review。深表惭愧。)因为有源码。就不多贴代码片段了,需要指出的是,这个版本的源代码我写的比较乱(可能程序员看别人的代码都是一团乱糟糟吧^_^),有些没有用到的类,函数都放在里面,只是简单的注销了。有的甚至没有屏蔽。希望不会给看代码的人带来困惑。


^_^  witch_2012_06








QQ2008版截屏工具源代码地址  :


    http://download.csdn.net/detail/witch_soya/4370139


QQ2012版截屏工具源代码地址  :


    http://download.csdn.net/detail/witch_soya/4370199


/*




最后衷心感谢提供 08 源代码的VC BASE 
          以及Deskpad源代码的网友。 
╰Witchつ
2012_06_13
*/
 
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值