2013-04-08 6 views
6

WPFウィンドウがあり、サードパーティの実行中のアプリケーションでウィンドウのオーバーレイとして動作する必要があります。私のWPFウィンドウは、ほとんどの場合、透明なコントロールで表示され、常に他のウィンドウの上にZオーダーで配置され、移動されなければなりません。要するに、子ウィンドウのように動作します。WPFサードパーティ製アプリケーションでホストされる子ウィンドウは、Windows 7のAeroテーマでは表示されません。

here(WPF HwndSource技法)とhere(WPF SetParent技法)で提供されるテクニックを見直しました。 HwndSourceテクニックはまったく動作しません。 SetParentテクニックはWindows 7で動作しますが、基本的なテーマでのみ動作します。 Windows 7 Aeroのテーマでは、私の子ウィンドウは見えません。

私はすべてのWindows 7のテーマで動作するソリューションを探しています。

私のテストアプリケーションは、テストウィンドウを作成し、SetParentを呼び出して、Notepadウィンドウ(ハードコードされたHWND)の子ウィンドウにします。基本的なテーマに

が、それはそうのようになります。Windows 7のテーマのもと

Basic Theme

、私はそれを見ることはありません。

Aero Theme

子ウィンドウ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スタイルの設定を解除しようとしました。 )

+1

だけの思考は、あなたがメモ帳以外の任意のウィンドウ(たとえばCALC.EXE)でテストを試してみましたか?今はWindows 7のPCにアクセスできないが、メモ帳で問題を再現することはできるが、Windows 8でコードを正確に使ってcalc.exeで再現することはできない。コードでWin8で、子ウィンドウがメモ帳に表示されるメモ帳のウィンドウを有効にするとすぐに子ウィンドウが見えなくなるので、メモ帳でテキストボックスを他のすべての子の上に置くことを考えているかもしれません。 –

+0

こんにちは...この考えをありがとう、@アンドレイパナ。私は他のウィンドウでテストし、Windows 8でも同様に動作するかをチェックします。 –

答えて

3

SetParentを使用する代わりに、WPFの「子」ウィ​​ンドウのWindowInteropHelper.Ownerを上に表示するウィンドウに設定します。

.NET 3.5では、OnSourceInitializedの早い段階でも、子のウィンドウのイベントハンドラのいずれかでこれを行うと、ウィンドウの所有者が実際に設定されないことに注意してください。明らかに、その時点でオーナーを設定するのは遅すぎます。

代わりに、Show()を呼び出す前に、ウィンドウを作成するコードにOwnerを設定します。 .NET 4は、SourceInitialized内からOwnerを設定できるようです。

  • ジャック
+0

ありがとうジャック!これは完全に機能しました。 –

+0

私は同様の問題を抱えていますが、 'this.Owner = HwndSource.FromHwnd(hwnd_notepad).RootVisual as Window 'を呼び出すことでメモ帳のウィンドウにアクセスできないようです。どのようにこれを達成しましたか? – Benj