2013-04-08 14 views
6

Ho una finestra WPF che deve comportarsi come una sovrapposizione di una finestra in un'applicazione in esecuzione di terze parti. La mia finestra WPF deve essere prevalentemente trasparente con alcuni controlli visibili, essere sempre posizionata proprio sopra l'altra finestra nell'ordine z, spostarsi con esso, ecc. In breve: voglio che si comporti come una finestra figlio.Finestra figlio WPF ospitata in un'applicazione di terze parti invisibile su Windows 7 temi Aero

Ho esaminato le tecniche offerte here (tecnica WPF HwndSource) e here (tecnica SetParent WPF). La tecnica HwndSource non funziona affatto. La tecnica SetParent funziona su Windows 7, ma solo con il tema di base. Con i temi Windows 7 Aero, non funziona: la mia finestra figlio è invisibile.

Sto cercando una soluzione che funzioni su tutti i temi di Windows 7.

La mia applicazione di test crea una finestra di test e chiama SetParent per renderlo una finestra secondaria di un (HWND codificato su) una finestra Notepad.

Sotto il tema di fondo, sembra in questo modo:

Basic Theme

Nell'ambito del tema di Windows 7, io non lo vedo:

Aero Theme

finestra Bambino 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> 

La finestra secondaria codice del gestore del carico modulo:

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

(ho provato un-impostare lo stile WS_POPUP. Non ha alcun effetto.)

+1

Solo un pensiero, hai provato il test con qualsiasi finestra (per esempio calc.exe) diverso da blocco note? Non ho accesso a un PC Windows 7 in questo momento, ma posso riprodurre il problema con il blocco note ma non con calc.exe, usando esattamente il tuo codice su Windows 8. Su Win8, con il tuo codice, la finestra figlia appare nel blocco note , ma non appena attivo la finestra del blocco note, la finestra secondaria diventa invisibile, quindi penso che forse il blocco note faccia qualcosa per mantenere la sua casella di testo sopra tutti gli altri bambini. –

+0

Hmmm ... grazie per questo pensiero, @AndreiPana. Verificherò con altre finestre e verificherò come funziona anche in Windows 8. –

risposta

3

Invece di utilizzare SetParent, impostare WindowInteropHelper.Owner della finestra "figlio" WPF nella finestra che si desidera visualizzare sopra.

Si noti che in .NET 3.5, se si esegue questa operazione in uno qualsiasi dei gestori di eventi della finestra "figlio", anche in OnSourceInitialized, il proprietario della finestra non viene impostato. Apparentemente è troppo tardi per impostare un proprietario in quel punto.

Invece, impostare il proprietario nel codice che crea la finestra, prima di chiamare Show(). .NET 4 sembra consentire l'impostazione del proprietario da SourceInitialized.

  • Jack
+0

Grazie Jack! Questo ha funzionato perfettamente. –

+0

Sto riscontrando un problema simile, ma sembra che non riesca ad accedere alla finestra del Blocco note chiamando "this.Owner = HwndSource.FromHwnd (hwnd_notepad) .RootVisual come Window;". Come hai ottenuto questo? – Benj

Problemi correlati