WPF 制作 Windows 屏保

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 制作 Windows 屏保相关的知识,希望对你有一定的参考价值。

 分享如何使用WPF 制作 Windows 屏保

WPF 制作 Windows 屏保

作者:驚鏵

原文链接:https://github.com/yanjinhuagood/ScreenSaver

  • 框架使用.NET452

  • Visual Studio 2019;

  • 项目使用 MIT 开源许可协议;

  • 更多效果可以通过GitHub[1]|码云[2]下载代码;

  • 也可以自行添加天气信息等。

 正文

  • 屏保程序的本质上就是一个 Win32 窗口应用程序;

    • 把编译好一个窗口应用程序之后,把扩展名更改为 scr,于是你的屏幕保护程序就做好了;

    • 选中修改好的 scr 程序上点击右键,可以看到一个 安装 选项,点击之后就安装了;

    • 安装之后会立即看到我们的屏幕保护程序已经运行起来了;

  • 处理屏幕保护程序参数如下

    • /s 屏幕保护程序开始,或者用户点击了 预览 按钮;

    • /c 用户点击了 设置按钮;

    • /p 用户选中屏保程序之后,在预览窗格中显示;

1)MainWindow.xaml 代码如下;

<Window x:Class="ScreenSaver.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:drawing="http://www.microsoft.net/drawing"
        xmlns:local="clr-namespace:ScreenSaver"
        mc:Ignorable="d" WindowStyle="None"
        Title="MainWindow" Height="450" Width="800">
    <Grid x:Name="MainGrid">
        <drawing:PanningItems ItemsSource="Binding stringCollection,RelativeSource=RelativeSource AncestorType=local:MainWindow"
                              x:Name="MyPanningItems">
            <drawing:PanningItems.ItemTemplate>
                <DataTemplate>
                    <Rectangle>
                        <Rectangle.Fill>
                            <ImageBrush ImageSource="Binding ."/>
                        </Rectangle.Fill>
                    </Rectangle>
                </DataTemplate>
            </drawing:PanningItems.ItemTemplate>
        </drawing:PanningItems>
        <Grid  HorizontalAlignment="Center" 
               VerticalAlignment="Top"
                Margin="0,50,0,0">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="90"/>
                    <Setter Property="FontWeight" Value="Black"/>
                    <Setter Property="Foreground" Value="White"/>
                </Style>
            </Grid.Resources>
            <WrapPanel>
                <TextBlock Text="Binding Hour,RelativeSource=RelativeSource AncestorType=local:MainWindow"/>
                <TextBlock Text=":" x:Name="PART_TextBlock">
                    <TextBlock.Triggers>
                        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="00:00:01"
                                                 From="1"
                                                 To="0"
                                                 Storyboard.TargetName="PART_TextBlock"
                                                 Storyboard.TargetProperty="Opacity"
                                                 RepeatBehavior="Forever"
                                                 FillBehavior="Stop"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </TextBlock.Triggers>
                </TextBlock>
                <TextBlock Text="Binding Minute,RelativeSource=RelativeSource AncestorType=local:MainWindow"/>
            </WrapPanel>
            <TextBlock Grid.Row="1" FontSize="45" HorizontalAlignment="Center" Text="Binding Date,RelativeSource=RelativeSource AncestorType=local:MainWindow"/>
        </Grid>
    </Grid>
</Window>

2) MainWindow.xaml.cs 代码如下;

  • 当屏保启动后需要注意如下

    • 将鼠标设置为不可见Cursors.None;

    • 将窗体设置为最大化WindowState.Maximized;

    • WindowStyle设置为"None";

    • 注意监听鼠标按下键盘按键则退出屏保;

using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace ScreenSaver

    /// <summary>
    ///     MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    
        public static readonly DependencyProperty stringCollectionProperty =
            DependencyProperty.Register("stringCollection", typeof(ObservableCollection<string>), typeof(MainWindow),
                new PropertyMetadata(null));

        public static readonly DependencyProperty HourProperty =
            DependencyProperty.Register("Hour", typeof(string), typeof(MainWindow), new PropertyMetadata(null));

        public static readonly DependencyProperty MinuteProperty =
            DependencyProperty.Register("Minute", typeof(string), typeof(MainWindow), new PropertyMetadata(null));

        public static readonly DependencyProperty SecondProperty =
            DependencyProperty.Register("Second", typeof(string), typeof(MainWindow), new PropertyMetadata(null));

        public static readonly DependencyProperty DateProperty =
            DependencyProperty.Register("Date", typeof(string), typeof(MainWindow), new PropertyMetadata());

        private readonly DispatcherTimer timer = new DispatcherTimer();

        public MainWindow()
        
            InitializeComponent();
            Loaded += delegate
            
                WindowState = WindowState.Maximized;
                Mouse.OverrideCursor = Cursors.None;
                var date = DateTime.Now;
                Hour = date.ToString("HH");
                Minute = date.ToString("mm");
                Date =
                    $"date.Month / date.Day   CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(date.DayOfWeek)";
                stringCollection = new ObservableCollection<string>();
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Images");
                var directoryInfo = new DirectoryInfo(path);
                foreach (var item in directoryInfo.GetFiles())
                
                    if (Path.GetExtension(item.Name) != ".jpg") continue;
                    stringCollection.Add(item.FullName);
                

                timer.Interval = TimeSpan.FromSeconds(1);
                timer.Tick += delegate
                
                    date = DateTime.Now;
                    Hour = date.ToString("HH");
                    Minute = date.ToString("mm");
                    Date =
                        $"date.Month / date.Day   CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(date.DayOfWeek)";
                ;
                timer.Start();
            ;
            MouseDown += delegate  Application.Current.Shutdown(); ;
            KeyDown += delegate  Application.Current.Shutdown(); ;
        

        public ObservableCollection<string> stringCollection
        
            get => (ObservableCollection<string>)GetValue(stringCollectionProperty);
            set => SetValue(stringCollectionProperty, value);
        


        public string Hour
        
            get => (string)GetValue(HourProperty);
            set => SetValue(HourProperty, value);
        

        public string Minute
        
            get => (string)GetValue(MinuteProperty);
            set => SetValue(MinuteProperty, value);
        

        public string Second
        
            get => (string)GetValue(SecondProperty);
            set => SetValue(SecondProperty, value);
        


        public string Date
        
            get => (string)GetValue(DateProperty);
            set => SetValue(DateProperty, value);
        
    

参考①[3]参考②[4]

参考资料

[1]

GitHub: https://github.com/yanjinhuagood/ScreenSaver

[2]

码云: https://gitee.com/yanjinhua/ScreenSaver

[3]

参考①: https://blog.walterlv.com/post/write-a-windows-screen-saver-using-wpf.html

[4]

参考②: https://wbsimms.com/create-screensaver-net-wpf/

以上是关于WPF 制作 Windows 屏保的主要内容,如果未能解决你的问题,请参考以下文章

Windows屏保多实例

04-fliqlo时钟屏保安装

由按钮触发时从屏幕边缘滑动的 WPF 应用程序

梵高数字时钟电脑屏保「windows电脑屏幕保护」

打开显示并终止屏幕保护程序

如何彻底卸载不需要的Mac屏保