我想绘制DirectX内容,使其看起来漂浮在桌面顶部和正在运行的任何其他应用程序上.我还需要能够使directx内容半透明,以便其他内容显示出来.有办法做到这一点吗?
我在C#中使用Managed DX.
我找到了一个适用于Vista的解决方案,从OregonGhost提供的链接开始.这是C#语法的基本过程.此代码位于继承自Form的类中.如果在UserControl中它似乎不起作用:
//this will allow you to import the necessary functions from the .dll using System.Runtime.InteropServices; //this imports the function used to extend the transparent window border. [DllImport("dwmapi.dll")] static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref Margins pMargins); //this is used to specify the boundaries of the transparent area internal struct Margins { public int Left, Right, Top, Bottom; } private Margins marg; //Do this every time the form is resized. It causes the window to be made transparent. marg.Left = 0; marg.Top = 0; marg.Right = this.Width; marg.Bottom = this.Height; DwmExtendFrameIntoClientArea(this.Handle, ref marg); //This initializes the DirectX device. It needs to be done once. //The alpha channel in the backbuffer is critical. PresentParameters presentParameters = new PresentParameters(); presentParameters.Windowed = true; presentParameters.SwapEffect = SwapEffect.Discard; presentParameters.BackBufferFormat = Format.A8R8G8B8; Device device = new Device(0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, presentParameters); //the OnPaint functions maked the background transparent by drawing black on it. //For whatever reason this results in transparency. protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; // black brush for Alpha transparency SolidBrush blackBrush = new SolidBrush(Color.Black); g.FillRectangle(blackBrush, 0, 0, Width, Height); blackBrush.Dispose(); //call your DirectX rendering function here } //this is the dx rendering function. The Argb clearing function is important, //as it makes the directx background transparent. protected void dxrendering() { device.Clear(ClearFlags.Target, Color.FromArgb(0, 0, 0, 0), 1.0f, 0); device.BeginScene(); //draw stuff here. device.EndScene(); device.Present(); }
最后,具有默认设置的表单将具有玻璃状的部分透明背景.将FormBorderStyle设置为"none",它将是100%透明的,只有您的内容浮动在所有内容之上.
您可以使用DirectComposition,LayeredWindows,DesktopWindowManager或WPF。所有方法都有其优点和缺点:
-DirectComposition是效率最高的一种,但需要Windows 8,并且限制为60Hz。
-LayeredWindows很难通过DXGI通过Direct2D-interop使用D3D。
-WPF通过D3DImage相对易于使用,但也限制为60Hz和DX9,无MSAA。可以通过DXGI对更高的DX版本进行互操作,并且当MSAA-Rendertarget解析为原始的非MSAA表面时,也可以使用MSAA。
自Windows Vista以来,-DesktopWindowManager非常适合提供高性能,但是DirectX版本似乎受到DWM使用的版本的限制(在Vista上仍为DX9)。更高的DX版本可以通过DXGI解决。
如果不需要每个像素的像素,您还可以使用半透明形式的不透明度值。
或者,您将本机Win32方法用于Window全局alpha(请记住,alpha为0不会捕获鼠标输入):
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED); COLORREF color = 0; BYTE alpha = 128; SetLayeredWindowAttributes(hWnd, color, alpha, LWA_ALPHA);
我已经能够将所有描述的技术用于C#和SharpDX,但是在DirectComposition,LayeredWindows和本机Win32的情况下,需要一点C ++-Wrappercode。对于初学者,我建议通过WPF。