.net 在Microsoft团队上共享主窗口时,透明子窗口呈现为黑色
问题描述.net 在Microsoft团队上共享主窗口时,透明子窗口呈现为黑色,.net,wpf,windows,pinvoke,microsoft-teams,.net,Wpf,Windows,Pinvoke,Microsoft Teams,问题描述 我有一个WPF子窗口和一个WPF主窗口。主窗口被设置为子窗口的所有者。子窗口具有透明背景,位于主窗口顶部 当我共享整个屏幕时,会议来宾可以看到主窗口和子窗口以及两个窗口的所有内容。 当我只共享主窗口时,会议来宾会看到子窗口的背景为黑色而不是透明 在我自己的屏幕上,两个窗口都呈现得很好——不管它们是如何共享的 该问题可在Microsoft团队中重现,但在Zoom上无法重现 这就是应用程序在我的计算机上呈现的方式—无论我如何共享屏幕: 这就是当我分享我的整个屏幕时,会议参与者看到应用程序
我有一个WPF子窗口和一个WPF主窗口。主窗口被设置为子窗口的所有者。子窗口具有透明背景,位于主窗口顶部 当我共享整个屏幕时,会议来宾可以看到主窗口和子窗口以及两个窗口的所有内容。 当我只共享主窗口时,会议来宾会看到子窗口的背景为黑色而不是透明 在我自己的屏幕上,两个窗口都呈现得很好——不管它们是如何共享的 该问题可在Microsoft团队中重现,但在Zoom上无法重现 这就是应用程序在我的计算机上呈现的方式—无论我如何共享屏幕:
这就是当我分享我的整个屏幕时,会议参与者看到应用程序的方式(屏幕截图仅说明应用程序,但显然整个屏幕对参与者可见):
这就是当我只共享主窗口时,会议参与者对应用程序的看法(黑色部分是子窗口的背景,应该是透明的而不是黑色):
如果我将子窗口的背景更改为例如
画笔.绿色
,而不是画笔.透明
,它将正确呈现参与者看到的:
因此,在传输透明子窗口的捕获时,显然存在一个问题
使用的技术C#,WPF,.NET Framework 4.8(如果相同的问题出现在其他目标框架上,例如.NET Core,则尚未测试,但无法更改目标框架) 复制问题的最小示例代码
MainWindow.xaml
:
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="600"
Background="LightBlue"
WindowStartupLocation="CenterScreen">
<Grid Height="500" Width="500" Background="CornflowerBlue" />
</Window>
约束
- 在实际应用程序中,主窗口是第三方本机Win32应用程序。但是,子窗口与主窗口位于同一进程空间中
- 子窗口必须以透明背景显示,并且能够包含完全不透明的内容
- 我必须对子窗口使用WPF/.NET。WPF内容可能托管在WinForms
表单中,并带有
或原始ElementHost
,如果这样可以解决任何问题的话HwndSource
- 我不在乎我是否必须使用PInvoke、Windows挂钩等,我已经广泛使用了
- 在屏幕共享时,不显示子窗口(如参与者所见)是可以接受的
- 我尝试过不让主窗口成为子窗口的所有者,但这会消除所有者关系中的良好行为:例如,子窗口始终位于所有者之上(不使用
最上面的
),子窗口与主窗口一起最小化、最大化、恢复和关闭。此外,共享主窗口时,子窗口根本不显示。作为最后的手段,这是可以接受的,因为我不希望子窗口出现在屏幕共享会话上,也不希望它显示为黑色
- 我曾尝试使用PInvoke
手动设置所有者关系(我猜这就是SetWindowLong
所做的)。参考:window.owner
- 我已尝试PInvoke
并清除SetWindowLong
和WS\u弹出窗口
标志,并设置WS\u重叠
,然后调用WS\u子项
,以创建“可视”父/子关系,而不是SetParent
创建的逻辑所有者关系。这在window.owner
的文档中指定:。这实际上解决了问题,但在其他场景中会产生视觉故障SetParent
- 我尝试使用
在子窗口上PInvokeLWA_COLORKEY
,然后将子窗口的背景设置为洋红色,然后将该颜色代码指定为透明颜色键。这实际上修复了黑色背景,但窗口渲染时没有内容和奇怪的边框。我已经读到,这可能发生,因为WPF是在Direct3D上构建的,SetLayeredWindowAttributes
实际上是用于使用GDI渲染的窗口。根据这篇博客(然而,相当古老,因此可能无法反映当今世界),这也可能是因为SetLayeredWindowAttributes
将窗口置于所谓的“系统重定向内容模式”,这是WPF不支持的SetLayeredWindowAttributes
- 我已尝试PInvoke
将子窗口显示affinity设置为SetWindowDisplayAffinity
和WDA\u监视器
。对于我来说,排除子窗口捕获可能是一个可行的选择,但是,Microsoft团队似乎使用忽略此设置的方法来捕获窗口WDA\u EXCLUDEFROMCAPTURE
- 我试图通过设置
来禁用硬件加速RenderOptions.ProcessRenderMode=RenderMode.SoftwareOnly
- 当从具有不同硬件的不同机器共享时,该问题是可复制的
坦率地说,对于如何解决这个问题,我有点不知所措。可能主要是因为我不明白为什么这个问题首先会发生。我在互联网上搜索了一下,发现没有人有类似的问题。我希望有人能透露一些信息-如果没有解决方案,那么至少可以说明问题发生的原因。您是否尝试过更新图形驱动程序或更改硬件加速设置?也许这些建议中的一些会有所帮助,尽管所提到的问题并不完全相同,但这并不是你的错。一个进程可以有多个窗口,每个窗口
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyApp
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
ContentRendered += delegate { CreateChildWindow(); };
}
private void CreateChildWindow()
{
var childWindow = new Window
{
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Background = Brushes.Transparent,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Height = 400,
Width = 400,
ShowInTaskbar = false,
Content = new Grid {Background = Brushes.Red, Height = 100, Width = 100},
Owner = this
};
childWindow.Show();
}
}
}