2013-04-08 15 views
6

Tôi có cửa sổ WPF phải hoạt động như lớp phủ cửa sổ trong ứng dụng đang chạy của bên thứ ba. Cửa sổ WPF của tôi phải chủ yếu là trong suốt với một số điều khiển hiển thị, luôn được đặt ngay trên đầu cửa sổ khác theo thứ tự z, di chuyển với nó, v.v. Tóm lại: Tôi muốn nó hoạt động giống như cửa sổ con.WPF Cửa sổ con được lưu trữ trong ứng dụng của bên thứ ba ẩn trên Windows 7 Chủ đề Aero

Tôi đã xem xét các kỹ thuật được cung cấp here (kỹ thuật WPF HwndSource) và here (kỹ thuật SetParent WPF). Kỹ thuật HwndSource không hoạt động. Kỹ thuật SetParent hoạt động trên Windows 7, nhưng chỉ với chủ đề cơ bản. Với Windows 7 Aero chủ đề, nó không hoạt động: cửa sổ con của tôi là vô hình.

Tôi đang tìm một giải pháp sẽ hoạt động trên tất cả các chủ đề của Windows 7.

Ứng dụng thử nghiệm của tôi tạo ra một cửa sổ kiểm tra và gọi SetParent để biến nó thành cửa sổ con của (HWND cứng được mã hóa thành) một cửa sổ Notepad.

Với chủ đề cơ bản, có vẻ như vậy:

Basic Theme

Với chủ đề Windows 7, tôi không nhìn thấy nó:

Aero Theme

cửa sổ Child 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> 

Mã bộ xử lý tải biểu mẫu cửa sổ con:

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

(Tôi đã thử bỏ cài đặt kiểu WS_POPUP. Nó không có hiệu lực.)

+1

Chỉ cần một ý nghĩ, bạn đã cố gắng thử nghiệm với bất kỳ cửa sổ (nói calc.exe) khác với Notepad? Tôi không có quyền truy cập vào máy tính Windows 7 ngay bây giờ, nhưng tôi có thể tạo lại vấn đề với notepad nhưng không phải với calc.exe, sử dụng chính xác mã của bạn trên Windows 8. Trên Win8, với mã của bạn, cửa sổ con xuất hiện trong notepad , nhưng ngay sau khi tôi kích hoạt cửa sổ notepad, cửa sổ con trở nên vô hình, vì vậy tôi nghĩ có lẽ notepad làm điều gì đó để giữ hộp văn bản của nó trên đầu trang của tất cả các trẻ em khác. –

+0

Hmmm ... cảm ơn vì suy nghĩ này, @AndreiPana. Tôi sẽ kiểm tra với các cửa sổ khác và kiểm tra cách hoạt động của tính năng này trong Windows 8. –

Trả lời

3

Thay vì sử dụng SetParent, hãy đặt WindowInteropHelper.Owner của cửa sổ "con" WPF của bạn vào cửa sổ bạn muốn hiển thị ở trên. Lưu ý rằng trong .NET 3.5, nếu bạn làm điều này trong bất kỳ trình xử lý sự kiện "child" của cửa sổ, ngay cả khi OnSourceInitialized, chủ cửa sổ không thực sự được thiết lập. Dường như đã quá muộn để thiết lập một chủ sở hữu tại thời điểm đó.

Thay vào đó, hãy đặt Chủ sở hữu trong mã tạo cửa sổ, trước khi bạn gọi Hiển thị(). .NET 4 dường như cho phép thiết lập chủ sở hữu từ bên trong SourceInitialized.

  • Jack
+0

Cảm ơn Jack! Điều này làm việc hoàn hảo. –

+0

Tôi gặp vấn đề tương tự, nhưng có vẻ như tôi không thể truy cập cửa sổ Notepad bằng cách gọi 'this.Owner = HwndSource.FromHwnd (hwnd_notepad) .RootVisual as Window;'. Làm thế nào bạn đạt được điều này? – Benj

Các vấn đề liên quan