BitBlt无法正确捕获标题栏

3

我正在使用下面的代码通过bltblt捕获窗口的截图。 但是标题栏在捕获的截图中完全变成黑色。 我正在Windows 8.1上运行代码。 有没有办法正确地捕获标题栏。

// Retrieve the handle to a display device context for the sourceWindow
hdcScreen = GetDC(ss);
// Retrieve the handle to a display device context for the dest window
hdcWindow = GetDC(hWnd);

//Get the client area for size calculation
RECT rcClient;
GetWindowRect(ss, &rcClient);

if (!BitBlt(hdcWindow,
    0, 0,
    rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
    hdcScreen,
    0, 0,
    SRCCOPY|CAPTUREBLT))
{
    MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);
    goto done;
}

屏幕截图,标题栏由红色矩形框突出显示。

编辑: 我显示屏幕截图的窗口将覆盖整个桌面,并不断更新其后面窗口的截图。此外,显示屏幕截图的窗口始终是最顶部的窗口。


可能会对你感兴趣:https://dev59.com/SkjSa4cB1Zd3GeqPF34K。 - Jonathan Potter
我已经检查过了,但不幸的是这对我行不通,因为我显示截图的窗口将覆盖整个屏幕,所以我无法捕获整个桌面并裁剪它以包括我想要的窗口。 - thunderbird
也许可以看一下DWM缩略图 - Jonathan Potter
我也需要像素数据...这是使用“DWM”缩略图无法实现的。 - thunderbird
为什么不直接捕获客户区域,并将其放入您自己的标准化、最大化的窗口中,使用相同的标题栏文本?您需要额外的工作来处理最小化等事项,但效果可能是相同的。 - icabod
不同的窗口将有不同的标题栏(屏幕截图中的一个有左侧四个按钮),因此这是不可行的,而且如果我想在屏幕截图中显示多个窗口,则无法工作...除了我要显示屏幕截图的窗口外,我将没有任何标题栏或框架边框。 - thunderbird
1个回答

0

你想要的信息并不全都可以从窗口DC中获取。主题会覆盖在上面。

如果你想要精确的可视化表示,你需要找到窗口(或其部分)的屏幕坐标,然后从屏幕DC中复制。


如果窗口没有显示,可能会遇到无法克服的问题。据我所知,在至少Windows Vista以来,主题不是Window DC的一部分,而是使用非GDI技术在其上绘制的。GDI根本没有能力绘制复杂的混合和透明度效果。直到Windows 8,仍然可以选择旧的经典主题,但现在它们已经消失了。您可能会发现标题栏不再在NCPAINT处理程序中绘制。


桌面屏幕将完全被我要显示并不断更新截图的窗口覆盖,因此桌面屏幕只会返回我的窗口显示截图。 - thunderbird
你应该编辑你的问题——这是你忘记提及的关键信息。如果你把窗口遮住了,你怎么知道它的真实样子? - david.pfx
我编辑了我的问题...我将立即显示在显示屏幕截图的窗口后面的窗口...同时,显示屏幕截图的窗口将始终是最顶部的窗口。 - thunderbird
屏幕截图窗口中始终会有一个窗口显示,因为桌面始终可见(如果没有其他窗口在桌面上方,则仅为壁纸部分)...此外,是否有一种方法可以获取当前主题并手动绘制到通过BitBlt捕获的任何内容上?我可能可以存储一个位图,其中仅包含标题栏和框架以及透明客户端区域,并使用WindowDC截图进行AlphaBlend,但这可能非常慢,特别是因为我考虑在ScreenCapture窗口后面显示所有可见窗口,而不仅仅是紧挨着它的窗口。 - thunderbird
有一个完整的API专门用于主题,但如果这是问题,那将是一个新问题。 - david.pfx
即使需要使用主题API进行一些后期处理,也要正确地捕获带标题栏的屏幕截图。我会研究主题API。 - thunderbird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接