【问题标题】:Win32 native control in layered (transparent) WPF window is invisible分层(透明)WPF窗口中的Win32本机控件不可见
【发布时间】:2018-09-25 09:58:37
【问题描述】:

我想在 WPF 窗口中托管本机 Win32(Qt 小部件)控件。 我的问题是,如果我将它托管在普通的 WPF 窗口中,一切正常,但是当我将 WPF 窗口的AllowsTransparency 设置为true 时,将不再呈现本机内容。我制作了一个简单的测试应用程序,它只创建了一个 Win32 按钮来查看 Qt 是否是罪魁祸首,但事实并非如此。

这是我拥有的HwndHost 实现:

using System;
using System.Runtime.InteropServices;
using System.Windows.Interop;

namespace WpfHwndHostLayeredWindow
{
    class NativeButton : HwndHost
    {
        protected override HandleRef BuildWindowCore(HandleRef hwndParent)
        {
            var hwnd = PInvoke.User32.CreateWindowEx(
                0, // EX_STYLE
                "BUTTON",
                "Win32 Button",
                PInvoke.User32.WindowStyles.WS_CHILD,
                0, 0, 100, 100,
                hwndParent.Handle,
                IntPtr.Zero, // hMenu
                new IntPtr(PInvoke.User32.GetWindowLong(hwndParent.Handle, PInvoke.User32.WindowLongIndexFlags.GWLP_HINSTANCE)),
                IntPtr.Zero // lParam
            );

            return new HandleRef(this, hwnd);
        }

        protected override void DestroyWindowCore(HandleRef hwnd)
        {
            PInvoke.User32.DestroyWindow(hwnd.Handle);
        }
    }
}

以及 WPF 窗口的 XAML:

<Window x:Class="WpfHwndHostLayeredWindow.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"
        xmlns:local="clr-namespace:WpfHwndHostLayeredWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        WindowStyle="None" ResizeMode="CanResizeWithGrip" AllowsTransparency="True">
    <Grid>
        <TextBlock Text="If you see this, the native control doesn't render properly"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"/>

        <local:NativeButton Margin="16"/>
    </Grid>
</Window>

我已尝试设置 WS_EX_LAYERED 标志,但它没有做任何事情。

有什么方法可以让它工作还是它是 WPF/HwndHost 的(已知)限制?

【问题讨论】:

  • 许多旧的显示技术不支持适当的透明度。例如,Windows 窗体从未具有“真正的”透明度docs.microsoft.com/en-us/dotnet/framework/winforms/controls/…,MS 承认“Windows 窗体控件不支持真正的透明度。透明 Windows 窗体控件的背景由其父级绘制。”。因此,没有这种方法的可能性不大。假设没有人有更好的信息,假设你想要的组合是不可能的。
  • AFAIK 因为支持 Windows 2000 分层窗口,如果您设置 AllowsTransparency,它会将 WS_EX_LAYERED 标志添加到窗口的扩展样式中。这将自动将该窗口与下面的所有其他窗口以及桌面背景混合在一起。

标签: c# wpf winapi wpf-interop


【解决方案1】:

分层窗口是将其内容绘制到屏幕外的窗口。这意味着系统会自动组合和重新绘制分层窗口和底层应用程序的窗口。

如果我们将原生窗口嵌入到分层窗口中,由于某些环境下的窗口类型冲突,子窗口内容可能无法绘制。

https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#layered-windows

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 2017-09-28
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 2011-05-31
    相关资源
    最近更新 更多