Search code examples
c#wpfscreensaver

How to show a preview of screen saver inside WPF window


I want to be able to show a preview of a screen saver inside WPF window. (using a container or control or ...) I know that Windows itself passes "/p" argument to the screen saver to get a preview. But how can I show that preview inside my WPF application? Should I get a handle of it and change its parent to my container o control? How?


Solution

  • You need to use Windows.Forms interop, because screen savers expect windows handles (HWND) and in WPF, only top-level windows have them.

    MainWindow.xaml

    <Window x:Class="So18547663WpfScreenSaverPreview.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:forms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
            Title="Screen Saver Preview" Height="350" Width="525"
            Loaded="MainWindow_OnLoaded" Closed="MainWindow_OnClosed"
            SizeToContent="WidthAndHeight">
        <StackPanel Orientation="Vertical" Margin="8">
            <TextBlock Text="Preview"/>
            <WindowsFormsHost x:Name="host" Width="320" Height="240">
                <forms:Control Width="320" Height="240"/>
            </WindowsFormsHost>
        </StackPanel>
    </Window>
    

    MainWindow.xaml.cs

    using System;
    using System.Diagnostics;
    using System.Windows;
    
    namespace So18547663WpfScreenSaverPreview
    {
        public partial class MainWindow
        {
            private Process saver;
    
            public MainWindow ()
            {
                InitializeComponent();
            }
    
            private void MainWindow_OnLoaded (object sender, RoutedEventArgs e)
            {
                saver = Process.Start(new ProcessStartInfo {
                    FileName = "Bubbles.scr",
                    Arguments = "/p " + host.Child.Handle,
                    UseShellExecute = false,
                });
            }
    
            private void MainWindow_OnClosed (object sender, EventArgs e)
            {
                // Optional. Screen savers should close themselves
                // when the parent window is destroyed.
                saver.Kill();
            }
        }
    }
    

    Assembly references

    • WindowsFormsIntegration
    • System.Windows.Forms

    Related links