Как нарисовать прозрачное содержимое DirectX в прозрачном окне?

Я хочу нарисовать содержимое DirectX так, чтобы оно казалось плавающим поверх рабочего стола и любых других запущенных приложений. Мне также нужно сделать содержимое DirectX полупрозрачным, чтобы можно было видеть другие вещи. Есть способ сделать это?

Я использую Managed DX с C#.

Разве многослойные окна не вариант?

Agnel Kurian 06.11.2008 08:00
msdn.microsoft.com/en-us/library/ms997507.aspx
Agnel Kurian 06.11.2008 08:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
2
14 031
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Думаю, это будет сложно без использования диспетчера окон рабочего стола, т.е. если вы хотите поддерживать Windows XP. Однако с DWM это похоже на довольно легко.

Если скорость не является проблемой, вы можете обойтись рендерингом на поверхность и последующим копированием визуализированного изображения в многоуровневое окно. Однако не ожидайте, что это будет быстро.

Беда, которая работает только с dx9, поскольку DWM в Vista - это dx9. Windows 7 будет использовать dx10, так что это будет хорошо.

Simon Buchan 20.02.2009 16:04
Ответ принят как подходящий

Я нашел решение, которое работает в 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% прозрачным, и только ваш контент будет парить над всем.

WPF - также другой вариант.

Developed by Microsoft, the Windows Presentation Foundation (or WPF) is a computer-software graphical subsystem for rendering user interfaces in Windows-based applications.

Хотя эта ссылка может дать ответ на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если ссылка на страницу изменится.

fglez 31.08.2012 17:18

Обратите внимание, как на этот вопрос ответили почти 4 года назад, во время бета-тестирования? Вопросы и ответы тогда были экспериментальными. Это, конечно, не блестящий ответ, но это является ответ, причем жизнеспособный. Ссылка действительна, как и ее содержание.

OJ. 01.09.2012 07:13

Вы можете использовать DirectComposition, LayeredWindows, DesktopWindowManager или WPF. Все методы имеют свои преимущества и недостатки:

-DirectComposition является наиболее эффективным, но требует Windows 8 и ограничен 60 Гц.

-LayeredWindows сложно заставить работать с D3D через Direct2D-взаимодействие с использованием DXGI.

-WPF относительно легко использовать через D3DImage, но он также ограничен 60 Гц и DX9 и не имеет MSAA. Возможны взаимодействия с более высокими версиями DX через DXGI, также можно использовать MSAA, когда цель MSAA-Rendertarget разрешена для собственной поверхности, отличной от MSAA.

-DesktopWindowManager отлично подходит для обеспечения высокой производительности, доступной с Windows Vista, но версии DirectX, похоже, ограничены версией, которую использует DWM (все еще DX9 в Vista). Обходные пути для более высоких версий DX должны быть возможны через DXGI, если они доступны.

Если вам не нужна аплха на пиксель, вы также можете использовать значение непрозрачности полупрозрачной формы.

Или вы используете собственный метод Win32 для глобальной альфы Window (помните, что альфа, равная 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.

Другие вопросы по теме