zoukankan      html  css  js  c++  java
  • 关于AERO或WB主题等半透明窗口无法截图的解决

    最近试过几套截图软件,发现其中有些无法实现对半透明窗口或主题的图片截取,包括早期版本的QQ截图工具也无法截取,于是打算写一个简单抓屏函数的来测试下,以下采用Win32 API方式编写:

    HBITMAP CapScreen()
    {
         HDC hDispDC,hMemDC;
         // 获取屏幕DC
         hDispDC = CreateDC("DISPLAY",NULL,NULL,NULL);
         hMemDC = CreateCompatibleDC(hDispDC);

         int  cx,cy;
         cx = GetSystemMetrics(SM_CXSCREEN);
         cy = GetSystemMetrics(SM_CYSCREEN);

         HBITMAP hSnapBt,hOldBt;
         hSnapBt = CreateCompatibleBitmap(hDispDC,cx,cy);

         hOldBt = (HBITMAP)SelectObject(hMemDC,hSnapBt);
         BitBlt(hMemDC,0,0,cx,cy,hDispDC,0,0,SRCCOPY);

         // cleanup
         SelectObject(hMemDC,hOldBt);
         DeleteDC(hMemDC);
         DeleteDC(hDispDC);

         return  hSnapBt;
    }

    测试发现果然无法截取到使用WindowBlinds模拟vista半透明主题的窗口栏,还有所有半透明的窗口!

    利用Spy++对以上无法截取到的窗口进行抓捕,发现这些窗口都具有WS_EX_LAYERED 这个扩展属性,又仔细看了下MSDN中关于BitBlt的说明,原型如下:

    BOOL BitBlt(
      HDC hdcDest, // handle to destination DC
      int  nXDest,  // x-coord of destination upper-left corner
      int  nYDest,  // y-coord of destination upper-left corner
      int  nWidth,  // width of destination rectangle
      int  nHeight, // height of destination rectangle
      HDC hdcSrc,  // handle to source DC
      int  nXSrc,   // x-coordinate of source upper-left corner
      int  nYSrc,   // y-coordinate of source upper-left corner
      DWORD dwRop  // raster operation code
    );

    对于其他参数我们并不用关心,主要该注意下最后这个参数dwRop

    [in] Specifies a raster-operation code. These codes define how the color data for the source rectangle is to be combined with the color data for the destination rectangle to achieve the final color. The following list shows some common raster operation codes.

    反复看过几次所有参数的含义后发现对于参数CAPTUREBLT ,有如下描述:

    Windows 98, Windows 2000: Includes any windows that are layered on top of your window in the resulting image. By default, the image only contains your window.

    猜想大概就是这个了,不过在引用这个参数时貌似要先更新vc6的SDK,否则会提示CAPTUREBLT未定义,不过也可以手工来给它作个宏定义:

    #ifndef  CAPTUREBLT
    #define  CAPTUREBLT 0x40000000
    #endif

    然后试着再调用BitBlt时组合上这个参数,结果果然可以截获半透明窗口了!

    上述截屏函数也可以用MFC方式来写:

    HBITMAP CapScreen()
    {
         CDC dispDC,memDC;
         dispDC.CreateDC("DISPLAY",NULL,NULL,NULL);
         memDC.CreateCompatibleDC(&dispDC);
         
         int  cx,cy;
         cx = GetSystemMetrics(SM_CXSCREEN);
         cy = GetSystemMetrics(SM_CYSCREEN);
         
         CBitmap snapBt,*pOldBt;
         snapBt.CreateCompatibleBitmap(&dispDC,cx,cy);
         
         pOldBt = memDC.SelectObject(&snapBt);
         // BitBlt使用CAPTUREBLT参数
         memDC.BitBlt(0,0,cx,cy,&dispDC,0,0,SRCCOPY | CAPTUREBLT );
         
         // cleanup
         memDC.SelectObject(pOldBt);

         // 不能返回snapBt.m_hObject或snapBt.GetSafeHandle()
         // 因为CBitmap对象在析构时会调用DeleteObject来释放位图句柄
         return  (HBITMAP)snapBt.Detach();
    }

     

     

    http://wzoot.blog.163.com/blog/static/41638800200889834988/

  • 相关阅读:
    [转]在SQL Server中,关于with as使用介绍
    系统设计笔记【不断更新中】
    关于PHPZend framework2 框架 学习过程。 阅前须知: ZF2中的配置文件是可以静态文件配置来注册和通过相关函数动态注册。 1.EventManager(事件驱动),关于事件驱动,在ZF2相关资料没有详细说明,可以参考ANDROID的事件驱动,MFC的消息响应/事件驱动。
    http://www.mwop.net/blog/248IntroducingtheZF2PluginBroker.html
    Introducing AkrabatSession zf2
    http://127.0.0.1/loginapi/JsonPacket/example/loginrequestdemo.php
    if ($this>getRequest()>isPost()) {
    email
    Quenz_i997_PDA_CHS.rar
    http://team.aiitec.net/?c=inbox
  • 原文地址:https://www.cnblogs.com/vc60er/p/3998635.html
Copyright © 2011-2022 走看看