如何在WPF窗口中展示屏幕保护程序的预览

3

我希望能在WPF窗口中显示屏幕保护程序的预览(使用容器或控件等)。我知道Windows本身会传递“/p”参数给屏幕保护程序来获取预览。但是我该如何在我的WPF应用程序中显示该预览呢?我应该获得它的句柄并将其父级更改为我的容器或控件吗?如何实现?

1个回答

2

您需要使用Windows.Forms互操作,因为屏幕保护程序期望窗口句柄(HWND),而在WPF中,只有顶级窗口才有这些句柄。

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

程序集引用

  • WindowsFormsIntegration(Windows窗体集成)
  • System.Windows.Forms(Windows窗体系统)

相关链接


更新了代码,现在的代码后台更少了。Windows.Forms.Control 在 XAML 中被创建。这是我第一次使用 Windows Forms 互操作;看起来 MSDN 上的指示使事情变得有点复杂。 - Athari
我该如何在主机中加载另一个屏幕保护程序?我尝试了以下代码:if(saver != null && saver.HasExited == false) saver.Kill(); saver = new Process(); saver = Process.Start(new ProcessStartInfo { FileName = (comboScreenSavers.SelectedItem as ComboBoxItem).Tag.ToString(), Arguments = "/p " + hostScreenSaver.Child.Handle, UseShellExecute = false, }); 但是它很混乱... - SepehrM
不,我有一个窗口,就像Windows的屏幕保护设置一样。当用户从comboBox选择屏幕保护程序时,formshost控件应该显示所选屏幕保护程序的预览。问题是,第一次将预览加载到主机控件中后,如果我尝试预览另一个屏幕保护程序,它们会混在一起,主机控件会快速闪烁并重复显示两个预览!如何取消当前的预览并加载另一个预览? - SepehrM
结束进程应该在任何情况下都能正常工作。我不知道为什么它对你不起作用。 - Athari
谢谢。它起作用了!我对页面生命周期有一些误解...我不应该检查(saver != null)来终止进程。只需检查是否为第一次初始化即可。 - SepehrM
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接