Domanda

Voglio disegnare il contenuto di DirectX in modo che sembri fluttuare sopra il desktop e qualsiasi altra applicazione in esecuzione. Devo anche essere in grado di rendere il contenuto di directx semitrasparente, quindi altre cose vengono visualizzate. C'è un modo per farlo?

Sto usando Managed DX con C #.

È stato utile?

Soluzione

Ho trovato una soluzione che funziona su Vista, a partire dal link fornito da OregonGhost. Questo è il processo di base, nella sintassi C #. Questo codice appartiene a una classe che eredita da Form. Non sembra funzionare se in un 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();
}

Infine, un modulo con impostazione predefinita avrà uno sfondo parzialmente trasparente dall'aspetto vetroso. Imposta FormBorderStyle su " none " e sarà trasparente al 100% con solo i tuoi contenuti galleggianti sopra ogni cosa.

Altri suggerimenti

Puoi usare DirectComposition, LayeredWindows, DesktopWindowManager o WPF. Tutti i metodi hanno i loro vantaggi e svantaggi:

-DirectComposition è il più efficiente, ma ha bisogno di Windows 8 ed è limitato a 60Hz.

-LayeredWindows è difficile per lavorare con D3D tramite Direct2D-interop usando DXGI.

-WPF è relativamente facile da usare tramite D3DImage, ma è anche limitato a 60Hz e DX9 e senza MSAA. È possibile interagire con versioni DX superiori tramite DXGI, inoltre è possibile utilizzare MSAA quando MSAA-Rendertarget viene risolto sulla superficie nativa non MSAA.

-DesktopWindowManager è ottimo per le alte prestazioni disponibili da Windows Vista, ma le versioni DirectX sembrano essere limitate dalla versione utilizzata da DWM (sempre DX9 su Vista). Soluzioni alternative per versioni DX superiori dovrebbero essere possibili tramite DXGI ove disponibile.

Se non è necessario per pixel aplha, è anche possibile utilizzare il valore di opacità di una forma semitrasparente.

Oppure usi il metodo nativo Win32 per l'alfa globale di Window (Ricorda che un alfa di 0 non catturerà l'input del mouse):

SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
COLORREF color = 0;
BYTE alpha = 128;
SetLayeredWindowAttributes(hWnd, color, alpha, LWA_ALPHA);

Sono stato in grado di utilizzare tutte le tecniche descritte con C # e SharpDX, ma in caso di DirectComposition, LayeredWindows e Win32 nativo era necessario un po 'di C ++ - Wrappercode. Per i principianti suggerirei di passare tramite WPF.

Suppongo che sarà difficile senza utilizzare Desktop Window Manager, ovvero se si desidera supportare Windows XP. Con DWM, sembra essere piuttosto facile però

Se la velocità non è un problema, è possibile cavarsela con il rendering su una superficie e quindi copiare l'immagine renderizzata su una finestra a più livelli. Non aspettarti che sia veloce.

WPF è anche un'altra opzione.

  

Sviluppato da Microsoft, Windows Presentation Foundation (o WPF) è un sottosistema grafico per software per il rendering di interfacce utente in applicazioni basate su Windows.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top