2013-04-08 22 views
6

Ich habe ein WPF Fenster, das sich als Overlay eines Fensters in einer laufenden Anwendung von Drittanbietern verhalten muss. Mein WPF-Fenster muss größtenteils transparent mit einigen sichtbaren Steuerelementen sein, immer direkt über dem anderen Fenster in der Z-Reihenfolge positioniert sein, sich damit bewegen usw. Kurz gesagt: Ich möchte, dass es sich wie ein untergeordnetes Fenster verhält.WPF Kind-Fenster gehostet in Anwendung von Drittanbietern unsichtbar unter Windows 7 Aero-Themen

Ich habe die angebotenen Techniken here (WPF HwndSource Technik) und here (WPF SetParent Technik) überprüft. Die HwndSource-Technik funktioniert überhaupt nicht. Die SetParent-Technik funktioniert unter Windows 7, jedoch nur mit dem Basisthema. Mit Windows 7 Aero Themes funktioniert es nicht: mein Kindfenster ist unsichtbar.

Ich bin auf der Suche nach einer Lösung, die auf allen Windows 7-Themen funktioniert.

Meine Testanwendung erstellt ein Testfenster und ruft SetParent auf, um es zu einem untergeordneten Fenster eines (fest codierten HWND to) Notepad Fensters zu machen.

Unter dem Grundthema, es sieht aus wie so:

Basic Theme

Unter dem Windows 7 Thema, ich sehe es nicht:

Aero Theme

Kinder Fenster 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> 

Der untergeordnete Formular-Load-Handler-Code:

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); 

(Ich habe versucht, den WS_POPUP-Stil zu deaktivieren. Es hat keine Wirkung.)

+1

Nur ein Gedanke, haben Sie versucht, Tests mit jedem Fenster (zB calc.exe) als Editor? Ich habe gerade keinen Zugriff auf einen Windows 7-PC, aber ich kann das Problem mit Notepad reproduzieren, aber nicht mit calc.exe, mit genau Ihrem Code auf Windows 8. Unter Win8, mit Ihrem Code, erscheint das untergeordnete Fenster im Editor , aber sobald ich das Notizblockfenster aktiviere, wird das Kindfenster unsichtbar, also denke ich, dass Notepad etwas tut, um seine Textbox über allen anderen Kindern zu halten. –

+0

Hmmm ... danke für diesen Gedanken, @AndreiPana. Ich werde mit anderen Fenstern testen und überprüfen, wie das auch in Windows 8 funktioniert. –

Antwort

3

Anstatt SetParent zu verwenden, setzen Sie WindowInteropHelper.Owner Ihres WPF "untergeordneten" Fensters auf das Fenster, das Sie oben anzeigen möchten.

Beachten Sie, dass in .NET 3.5, wenn Sie dies in einem der Ereignisbehandlungsroutinen des "untergeordneten" Fensters tun, sogar so früh wie OnSourceInitialized, wird der Fensterbesitzer nicht wirklich festgelegt. Anscheinend ist es zu spät, um einen Besitzer an diesem Punkt zu setzen.

Setzen Sie den Besitzer stattdessen in den Code, der das Fenster erstellt, bevor Sie Show() aufrufen. .NET 4 scheint es zu ermöglichen, den Besitzer innerhalb von SourceInitialized festzulegen.

  • Jack
+0

Danke Jack! Das hat perfekt funktioniert. –

+0

Ich habe ein ähnliches Problem, aber es scheint, ich kann auf das Fenster von Notepad nicht zugreifen, indem ich 'this.Owner = HwndSource.FromHwnd (hwnd_notepad) .RootVisual als Window;'. Wie hast du das erreicht? – Benj