我现在正在尝试创建一个屏幕捕获程序。上周我尝试了GetFrontBufferData方法并且成功了。但是,它的性能非常糟糕,只能捕获桌面图像。这意味着当我开始运行全屏游戏时,GetFrontBufferData方法将一无所获。但我想要的是抓住全屏游戏而不是桌面图像。
在GetFrontBufferData解决方案中,我创建了一个设备并让HWND参数为NULL。我想知道我是否可以获得顶层窗口的句柄(意思是全屏游戏的句柄),并将其传递给CreateDevice方法,我可以抓住它的屏幕截图。
实际上我已经尝试了几种基于DX9的屏幕截图方法。我研究了问题Fastest method of screen capturing并尝试将GetRenderTarget()方法与GetRenderTargetData()一起使用。问题是我只能获得程序本身呈现的渲染数据。与GetBackBuffer()相同。
所以问题来了,如果我能得到顶层窗口的句柄,我可以得到一个特定的窗口图像(比如一些运行全屏游戏)吗?我检查了Win32 - Get Main Wnd Handle of application中描述的EnumWindow方法。这段代码似乎得到的窗口只根据我的测试由程序自己创建。但是我需要通过其他程序创建一些窗口。
所以,这是我的问题。总之,我想知道两件事:1,我的方法是否获得其他窗口的句柄然后将其传递给CreateDevice并使其屏幕截图正确? 2,如果是对的,如何拿到手柄;如果它是错误的,捕获全屏游戏的方法是什么?
答案 0 :(得分:0)
这是不对的,传递给CreateDevice的窗口句柄与屏幕捕获无关,它是在应用程序进入后台时提醒Direct3D的窗口。因为你想从另一个应用程序中捕获屏幕数据流,所以这里的窗口句柄无法帮助你。
由于性能至关重要,而且GetFrontBufferData很耗时,所以我认为适合你需要的唯一方法是挂钩Direct3D,中断对Present的调用,并从backbuffer获取数据,那么你可以做什么你想要的,这只是一个想法,我不熟悉挂钩,我从来没有挂过Direc3D。
以下是CreateDevice中使用的两个窗口句柄(来自DirectX SDK文档)
创建Direct3D设备时,提供两个不同的窗口 参数:焦点窗口(hFocusWindow)和设备窗口( 在D3DPRESENT_PARAMETERS中的hDeviceWindow)。每个窗口的目的 is:焦点窗口在应用程序切换时警告Direct3D 前景模式到背景模式(通过Alt-Tab,鼠标单击,或 其他一些方法)。每个设备共享一个焦点窗口 由应用程序创建。设备窗口确定位置 和屏幕上后缓冲区的大小。当Direct3D使用它时 在
期间,后台缓冲区内容被复制到前台缓冲区
存在。