远程桌面镜像技术解析

在Windows操作系统中,实现远程计算机的桌面镜像功能,可以通过安装显示镜像驱动程序来实现。镜像驱动程序自Windows 2000以来就存在。然而,对于Windows 8及更高版本,镜像驱动程序不再被安装。尽管如此,微软还是提供了替代方案。

这种替代方案被称为桌面复制API(Desktop Duplication API),它是DirectX11的一部分,更确切地说,是DXGI 1.2更新的一部分。实际上,DirectX 11 API可以在系统不支持DirectX 11的情况下回退到版本10或9,但DXGI不行。此外,Windows 7和Vista不会有DXGI 1.2版本——需要Windows 8或更高版本。

为了熟悉桌面复制API,研究了微软提供的示例。事实上,很难在其他地方找到更多的示例。

微软提供的示例适用于单个桌面,这完全符合其目的。DirectX是基于COM的,这意味着需要精通C或C++来正确处理它,对吗?不完全是这样,Delphi也非常适合处理COM接口。会说,使用Delphi,COM甚至可能更容易,因为它管理引用计数。

示例

制作了两个示例:

第一个示例模仿了微软的示例。称之为控制台示例,尽管实际上并没有控制台。它使用Windows API创建一个窗口,启动一个或多个线程进行桌面复制,然后进入一个无尽的消息循环,以更新创建的窗口与捕获的帧。

第二个示例更符合Delphi的做事方式。在这里,创建了一个VCL表单,捕获的帧更新表单内的TPanel组件。选择了TPanel,因为它是TWinControl的后代,所以有一个HWND。

细节

DirectX头文件来自下面的参考3。非常好的工作(确实很多!)

像素着色器和顶点着色器并不是直接由示例编译的。相反,将预编译的结果插入到PixelShader和VertexShader单元中。

参考资料

  • 桌面复制API
  • DXGI桌面复制示例
  • DelphiDX12头文件

代码示例

以下是使用Delphi实现桌面复制API的示例代码:

unit DesktopDuplicationAPI; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComObj, Direct3D11, DXGI; type TDesktopDuplicationForm = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var DesktopDuplicationForm: TDesktopDuplicationForm; implementation {$R *.dfm} procedure TDesktopDuplicationForm.Button1Click(Sender: TObject); var pDevice: ID3D11Device; pDXGIFactory: IDXGIFactory2; pAdapter: IDXGIAdapter; pOutput: IDXGIOutput; pDesktopDevice: ID3D11Device; pDesktopResource: IDXGIResource; pDesktopTexture2D: ID3D11Texture2D; pDesktopDuplication: IDXGIOutputDuplication; begin // 初始化Direct3D11设备 D3D11CreateDevice(nil, D3D_DRIVER_TYPE_HARDWARE, nil, 0, nil, 0, D3D11_SDK_VERSION, pDevice, nil, nil); // 获取DXGI工厂 CreateDXGIFactory1(pDXGIFactory); pDXGIFactory.EnumAdapters(0, pAdapter); pAdapter.EnumOutputs(0, pOutput); // 获取桌面设备 pOutput.GetDevice(pDesktopDevice); // 创建桌面复制接口 pOutput.QueryInterface(IID_IDXGIOutputDuplication, pDesktopDuplication); // 获取桌面资源 pDesktopDuplication.AcquireNextFrame(500, nil, pDesktopResource); pDesktopResource.QueryInterface(IID_ID3D11Texture2D, pDesktopTexture2D); // 处理桌面资源 // ... // 释放资源 pDesktopTexture2D := nil; pDesktopResource := nil; pDesktopDuplication := nil; pAdapter := nil; pOutput := nil; pDXGIFactory := nil; pDevice := nil; end; end.

以上代码展示了如何在Delphi中使用Desktop Duplication API来捕获桌面。首先,初始化Direct3D11设备,然后获取DXGI工厂、适配器、输出接口和桌面设备。接着,创建桌面复制接口并获取桌面资源。最后,处理桌面资源并释放所有资源。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485