【问题标题】:WPF Child window hosted in third-party application invisible on Windows 7 Aero themes托管在第三方应用程序中的 WPF 子窗口在 Windows 7 Aero 主题上不可见
【发布时间】:2013-03-30 19:45:42
【问题描述】:

我有一个WPF 窗口,它必须在第三方运行的应用程序中充当窗口的叠加层。我的 WPF 窗口必须大部分是透明的,带有一些可见的控件,始终位于 z 顺序中另一个窗口的正上方,随它移动等等。简而言之:我希望它的行为类似于子窗口。

我已经回顾了here(WPF HwndSource 技术)和here(WPF SetParent 技术)提供的技术。 HwndSource 技术根本不起作用。 SetParent 技术适用于 Windows 7,但仅适用于基本主题。使用Windows 7 Aero 主题,它不起作用:我的子窗口是不可见的。

我正在寻找适用于所有 Windows 7 主题的解决方案。

我的测试应用程序创建一个测试窗口并调用 SetParent 使其成为Notepad 窗口(硬编码为 HWND)的子窗口。

在基本主题下,是这样的:

在 Windows 7 主题下,我看不到:

子窗口XAML:

<Window x:Class="WpfApplication22.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="300" Width="300" Background="#63000000" ShowInTaskbar="False" WindowStyle="None" Initialized="Window_Initialized" Loaded="Window_Loaded" AllowsTransparency="True">
    <Grid>
        <Ellipse Height="87" HorizontalAlignment="Left" Margin="12,12,0,0" Name="ellipse1" Stroke="Black" VerticalAlignment="Top" Width="167" Fill="#FFBE3A3A" />
    </Grid>
</Window>

子窗口窗体加载处理代码:

    var parentHwnd = new IntPtr(0x01DE0DFC); // Running Notepad
    var guestHandle = new WindowInteropHelper(this).Handle;

    var style = WS_VISIBLE | WS_CLIPSIBLINGS | WS_CHILD | WS_POPUP;
    SetWindowLong(guestHandle, GWL_STYLE, (int)(style));
    SetParent(guestHandle, parentHwnd);

(我试过取​​消设置 WS_POPUP 样式,没有效果。)

【问题讨论】:

  • 只是一个想法,您是否尝试过使用记事本以外的任何窗口(比如 calc.exe)进行测试?我现在无法访问 Windows 7 PC,但我可以使用记事本重现问题,但不能使用 calc.exe,完全使用您在 Windows 8 上的代码。在 Win8 上,使用您的代码,子窗口出现在记事本中,但是一旦我激活记事本的窗口,子窗口就会变得不可见,所以我在想记事本可能会做一些事情来将其文本框保持在其他所有子窗口之上。
  • 嗯...谢谢你的想法,@AndreiPana。我将使用其他 Windows 进行测试,并查看它在 Windows 8 中的工作原理。

标签: wpf winapi windows-7 aero childwindow


【解决方案1】:

不使用 SetParent,而是将 WPF“子”窗口的 WindowInteropHelper.Owner 设置为要在上方显示的窗口。

请注意,在 .NET 3.5 中,如果您在任何“子”窗口的事件处理程序中执行此操作,即使早在 OnSourceInitialized 时,窗口所有者也不会真正设置。显然,此时设置所有者为时已晚。

相反,在调用 Show() 之前,在创建窗口的代码中设置 Owner。 .NET 4 似乎允许在 SourceInitialized 中设置所有者。

  • 杰克

【讨论】:

  • 我遇到了类似的问题,但我似乎无法通过调用this.Owner = HwndSource.FromHwnd(hwnd_notepad).RootVisual as Window; 访问记事本的窗口。您是如何做到这一点的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
  • 2012-10-23
  • 2012-08-23
相关资源
最近更新 更多