如何正确截屏Aero/DWM上的特定窗口 [英] How to correctly screencapture a specific window on Aero/DWM

查看:711
本文介绍了如何正确截屏Aero/DWM上的特定窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景信息: 我已经编写并使用了很长时间的MFC应用程序,当用户按下打印屏幕"/"Alt +打印屏幕"键时,它几乎自动将屏幕截图保存到硬盘上.直到现在我已经使用Windows 7 RC几周了,我才开始推迟使用与Aero相关的任何功能.

Background info: I have this MFC application I coded and been using for a long time that pretty much automatically saves screenshots to the hard disk when the user hits the Print Screen/Alt+Print Screen key. I have been putting off using anything related to Aero until now that I've been using Windows 7 RC for a couple of weeks.

问题: 我正在使用标准的GetDC/BitBlt方法来捕获窗口内容.在进行常规的全屏抓取(无论打开了多少窗口等)时,此方法都没有问题.当我尝试捕获前景窗口(Alt + PrintScreen)时出现问题.这是两个示例:

The problem: I'm using the standard GetDC/BitBlt method to capture the window contents. I have no problems with this method while doing regular full-screen grabs (no matter how many windows are opened etc). The problem arises when I try capturing the foreground window (Alt+PrintScreen). Here are two examples:

示例1 http://indiecodelabs.com/extern/example1.jpg

示例2 http://indiecodelabs.com/extern/example2.jpg

正如您所看到的,我在边界应该出现的地方越来越乱了.顶部越明显,我们可以在两个屏幕截图中看到工具栏的某些重复.

As you can see, I'm getting garbage where the borders should be. This is more noticeable towards the top, where we can see some duplication of the toolbar in both screenshots.

我已经搜索了好几个小时了,发现的文章说在DWM下,BitBtl/GetDC方法不起作用,但是找不到一个解释我们(开发人员)应做的事情的方法.确实能够在DWM上运行时在我们的应用程序中维持相同的功能.

I've been googling about this for hours now and all I can find are articles saying that under DWM the BitBtl/GetDC method won't work, but can't find a single one explaining what we (the developers) should do to be able to maintain the same functionality in our apps when running on DWM.

任何帮助,指示和建议将不胜感激.

Any help, pointers, suggestions will be greatly appreciated.

推荐答案

这是一个很好的问题,很遗憾,我不知道确切的答案.我的第一个想法是抢占整个桌面并从中切出有趣的部分.

It's an excellent question that I unfortuneatly don't know exact answer to. My first idea was to grab the whole desktop and cut interesting part out of it.

我已经研究了QT 4.5的源代码,以了解它们的工作方式,并发现了类似的内容.如果将GetClientRect切换为GetWindowRect并剥离QT样板代码,则应该获得所需的内容.看起来好像很黑:)

I've dug into QT 4.5 sources to see how they do it, and found something like this. If you switch GetClientRect to GetWindowRect and strip QT boilerplate code you should get what you want. It looks like a hack though :)


QPixmap QPixmap::grabWindow(WId winId, int x, int y, int w, int h )
{
    RECT r;
    GetClientRect(winId, &r);  
    if (w < 0) w = r.right - r.left;
    if (h < 0) h = r.bottom - r.top;  
    // Create and setup bitmap
    HDC display_dc = GetDC(0);
    HDC bitmap_dc = CreateCompatibleDC(display_dc);
    HBITMAP bitmap = CreateCompatibleBitmap(display_dc, w, h);
    HGDIOBJ null_bitmap = SelectObject(bitmap_dc, bitmap);

    // copy data
    HDC window_dc = GetDC(winId);
    BitBlt(bitmap_dc, 0, 0, w, h, window_dc, x, y, SRCCOPY);

    // clean up all but bitmap
    ReleaseDC(winId, window_dc);
    SelectObject(bitmap_dc, null_bitmap);
    DeleteDC(bitmap_dc);

    QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap);

    DeleteObject(bitmap);
    ReleaseDC(0, display_dc);

    return pixmap;
}

这篇关于如何正确截屏Aero/DWM上的特定窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆