关于Visual C ++:屏幕捕获在Vista中的MFC应用程序上不起作用

关于Visual C ++:屏幕捕获在Vista中的MFC应用程序上不起作用

Screen capture doesn't work on MFC application in Vista

我们已经使用MFC构建了一些内部应用程序,并带有OpenGL绘制例程。它们都使用相同的代码在屏幕上绘制,然后打印屏幕或将其保存为JPEG文件。在Windows XP中一切正常,并且我需要找到一种使它们在Vista上运行的方法。

在我们的三个应用程序中,一切正常。在剩下的一个中,我可以获得窗口边框,标题栏,菜单和任务栏,但内部永远不会显示。就像我说的那样,这些应用程序使用完全相同的代码来写入屏幕并捕获窗口图像,而我看到的唯一区别似乎是可能与之相关的是,有问题的应用程序使用了MFC多文档界面,而该工作使用单个文档界面。

要么答案不在网上,要么我在谷歌搜索方面比我想象的要差。我在MSDN论坛上问,唯一得到的实用建议是使用GDI +而不是GDI,这没有什么不同。在给定窗口指针的情况下,我对捕获,打印或保存的代码的每一部分都尝试了不同的方法,因此显然这与窗口本身有关。我还没有使用SDI重建有问题的应用程序,而且我真的没有其他想法。

有人看到过这样的东西吗?

我得到的是四个应用程序。他们使用许多通用代码,并共享实际的.h和.cpp文件,因此我知道绘图和屏幕捕获代码是相同的。

有一个使用* pWnd的WindowtoDIB()例程,以及一个源矩形和目标大小。它看起来像经过稍微修改的Microsoft代码,并且我在Microsoft网站上的此文件中找到了其他功能。在我的四个应用程序中,三个可以很好地处理此问题,但一个不能。最明显的区别是问题之一是MDI。

在我看来,* pWnd是问题。从长远来看,我不是MFC专家,在我看来,问题可能是我们在SDI中设置了一个窗口,而在MDI中设置了多个。我可能将错误的* pWnd传递给该函数。

同时,尽管它仍无法在32位Vista机器上运行,但它已开始在64位Vista测试机上正常工作。我不知道为什么。自上次测试以来,我什么都没有改变,而且我认为其他人也没有。 (在32位版本上,"打印屏幕"键可以按预期工作,但不会将屏幕另存为JPEG。)


如果这是您想要的CView的内容,那么是的,那应该是正确的。如果这是整个屏幕的内容(至少是内容,没有工具栏和状态栏),则应将其传递给CMainFrame(这是可能已更改的默认名称,该名称是从CMDIFrameWnd派生的) )。

您可以发布WindowToDIB()的代码吗?我已经尝试过了,并且对我有用(TM),但是视图中没有OpenGL代码。尝试将以下窗口传递给WindowToDIB()函数:

CMainFrame * mainfrm = static_cast(::AfxGetMainWnd());

1
2
3
4
5
- mainfrm

- mainfrm->MDIGetActive()

- mainfrm->MDIGetActive()->GetActiveView()

看看你得到什么。


您的问题标题提及屏幕截图,但您的实际问题未提及。请详细说明。您可以对三个应用程序进行屏幕捕获,而对第四个应用程序不进行屏幕捕获吗?您可以使用其他可以捕获OpenGL / DirectX窗口的屏幕捕获软件。这些表面由窗口管理器直接处理,不会以简单的" PrtScn"显示。

切换到GDI +将无法解决,切换到SDI也不会解决。


最终,我们通过创建一个不同的OpenGL上下文并对其进行绘制来解决此问题。我们放弃了屏幕截图。


抱歉,我还是不明白。您试图让"打印屏幕"键在所有四个应用程序上都可以使用吗?或者,您正在尝试使WindowtoDIB()函数正常工作,该函数需要对应用程序本身进行"截屏"(来自您自己的应用程序),以便可以将其另存为图像文件?

另外,"打印屏幕键可以按预期工作,但不能将屏幕另存为JPEG"是什么意思?"打印屏幕"仅复制到剪贴板,粘贴在"画图"中会怎样?

如果WindowtoDIB()函数仅"捕获"传递给它的窗口,那么可以,您的MDI子窗口将不会显示。


每个窗口的内容都是DirectX曲面,并且只能由图形卡中的窗口管理器来组装。除非您关闭新界面(DWM)或专门用于从DWM进行屏幕捕获的代码,否则您将无法捕获此内容。

维基百科对桌面窗口管理器(DWM)有很好的描述。


推荐阅读