关于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/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,Aero功能需要满足Windows 7上的WDDM(Windows驱动程序显示模型)。因此,要启用Aero功能,需要确保计算机的显卡驱动程序已经安装并且是最新版本。如果您的计算机已经安装了最新版本的显卡驱动程序,但仍然无法启用Aero功能,则可能需要检查您的计算机是否满足Aero功能的硬件要求。如果您的计算机不满足Aero功能的硬件要求,则无法启用Aero功能。 如果您的计算机满足Aero功能的硬件要求,并且已经安装了最新版本的显卡驱动程序,但仍然无法启用Aero功能,则可能需要尝试以下步骤: 1. 确保您的计算机已经启用了Aero功能。要启用Aero功能,请右键单击桌面,选择“个性化”,然后选择“窗口颜色和外观”。在“颜色方案”下拉菜单中,选择“Aero”选项。 2. 确保您的计算机已经启用了桌面窗口管理器服务。要启用桌面窗口管理器服务,请按下“Win + R”键,输入“services.msc”,然后按下“Enter”键。在“服务”窗口中,找到“桌面窗口管理器”服务,确保该服务正在运行。 3. 确保您的计算机已经启用了透明玻璃效果。要启用透明玻璃效果,请右键单击桌面,选择“个性化”,然后选择“窗口颜色和外观”。在“颜色方案”下拉菜单中,选择“Aero”选项。然后,单击“窗口颜色”链接,确保“启用透明玻璃效果”复选框已经选中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值