WPF 屏幕保护程序助手





4.00/5 (9投票s)
一个帮助器 DLL,
https://nuget.net.cn/packages/ScreenSaver.Helper
引言
这是我的屏幕保护程序助手库的介绍。其目的是尽可能多地处理创建屏幕保护程序相关的琐碎细节。本质上,屏幕保护程序是一个常规的 exe 文件,只是扩展名更改为 .scr。在实际操作中,要使其正常工作需要多个组件。处理各种命令行参数、监听键盘和鼠标事件、允许配置、提供用于预览模式的 Win32 子窗口、多显示器支持等。此助手旨在尽可能简化这些方面。
背景
这是我第一次向 Code Project 贡献内容,但我从这里的所有专家那里受益匪浅,我认为是时候尝试回馈社区了。与其说是“如何做”,不如说这是一个您可以在开发屏幕保护程序时使用的工具。信不信由你,是的,屏幕保护程序的开发仍然有需求。在我的例子中,我有多个面向客户的自助服务终端,为了避免屏幕灼伤,我需要一个自定义的屏幕保护程序。在这种情况下,我想使用我们公司的 Facebook 页面,但这又是另一个话题。
使用代码
一旦您有了一个想要制作成屏幕保护程序的 WPF 应用程序,请引用 ScreenSaver.Helper.dll 和 log4net.dll,然后打开您的 App.xml,删除/注释掉现有的 StartupUri 并添加一个 Startup 方法。
<Application x:Class="WPF_App_Tester.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_OnStartup">
<!--StartupUri="YourWindow">-->
...
</Application>
完成此操作后,转到您的 App.xaml.cs 文件,使用 ScreensaverApp 特性将您的应用程序链接到 ScreenSaver 助手子系统。唯一必需的参数是主窗口(您的主要屏幕保护程序窗口),在下面的示例中,我们将其命名为“MainWindow”。有多个可选参数:ConfigWindow(窗口){这是您希望 Windows 使用的配置窗口}、RestartOnUnhandled(布尔值)、RepeatOnEachMonitor(布尔值)、StretchAcrossMonitors(布尔值)。
在您刚刚创建的 **App_OnStartup** 方法中,您应该将现有的参数(sender 和 e)传递给 Core.App_Startup 方法。这将在稍后为您处理多种因素(稍后介绍)。
您可能还希望挂钩 Core.UnhandledException 事件来处理任何意外的异常。默认情况下,该库使用 log4net 并创建一个滚动日志文件,存储在 AppData/AppName 中,在关闭之前记录异常。
using System.Windows;
using ScreenSaver.Helper;
namespace WPF_App_Tester
{
[ScreensaverApp(typeof(MainWindow),typeof(ConfigWindow))]
public partial class App : Application
{
private void App_OnStartup(object sender, StartupEventArgs e)
{
Core.UnhandledException += Core_UnhandledException;
Core.App_Startup(sender, e);
}
private void Core_UnhandledException(object sender, ref System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
// Your exception handling logic.
// If you have resolved the exception
// set e.Handled = true;
}
}
}
自定义设置提供程序
屏幕保护程序在访问链接回 WinNT 文件/文件夹的八个字符命名限制的文件/文件夹方面有一个怪癖,这会干扰默认的设置提供程序。与其调整这个,我们不如使用注册表的 HKCU 部分来存储我们的设置。该库提供了一个自定义设置提供程序来实现这一点。要使用它,请导航到您项目的设置文件,然后点击 **<> 查看代码** 按钮。Visual Studio 应该会将您带到您的 Settings.cs 文件。
添加对 **ScreenSaver.Helper.SettingsProviders** 的 using 引用,并添加两个属性。第一个,
[SettingsProvider(typeof(SettingsProviderEx))]
这告诉设置系统使用我们的备用提供程序,第二个,
[SettingsProviderEx.SettingsHelper(typeof(RegCurrentUserHelper))]
通知 **SettingsProviderEx** 使用我们之前讨论过的 HKCU 键。
using System.Configuration;
using ScreenSaver.Helper.SettingsProviders;
namespace WPF_App_Tester.Properties {
[SettingsProviderEx.SettingsHelper(typeof(RegCurrentUserHelper))]
[SettingsProvider(typeof(SettingsProviderEx))]
internal sealed partial class Settings {...}
...
}
命令行参数
如果您此时构建您的应用程序,它应该可以接受多个命令行参数了。
/s - 这是 Windows 屏幕保护程序必需的参数,它将显示您在 App.xaml.cs 的 MainWindow 属性中标识的窗体。在 IDE 中,它强制将窗口的 TopMost 设置为 false,以便进行调试断点和异常处理。当未附加调试器时,TopMost 设置为 true。
在显示模式下,鼠标和键盘事件监听器会被注入到 MainWindow 中,以允许传统屏幕保护程序通常具有的关闭事件。
默认情况下,如果存在多个显示器,则会在除被识别为主显示器的显示器之外的每个显示器上加载一个“遮罩”窗口。主显示器接收您的 MainWindow。
您可以根据需要使用 RepeatOnEachMonitor(bool) 或 StretchAcrossMonitors(bool) 来覆盖此行为。
/p IntPtr 使用 Windows 在选择屏幕保护程序时通常传递的 IntPtr,助手会将您的 MainWindow 设为预览模式的子窗口,但不注入任何鼠标/键盘关闭事件。
/c 打开您传递给 ScreenSaverApp 属性的 ConfigWindow 参数的 ConfigWindow。
/i 通过首先更改主文件扩展名(如果需要),将 .exe 更改为 .scr,然后更新注册表将您的屏幕保护程序设置为默认值,然后打开 Windows 屏幕保护程序配置窗口来安装屏幕保护程序。
附加助手类
日志记录
如前所述,助手库使用 log4Net 进行日志记录。您可以通过在添加对 **LogHelper** 类和 **log4net** 的引用后,使用提供的扩展方法来提供您自己的附加日志记录。
第一个 **Log()** 仅记录您的消息,并可选择添加一个异常对象。
this.Log().Warning("YOUR WARNING MESSAGE",ex);
第二个 **LogP()** 也记录您的消息,但还会将调用类的公共属性添加到日志中。
this.LogP().Error("YOUR ERROR MESSAGE",ex);
AnimationHelper
这是一个基于任务的动画助手,支持异步操作,另外,还提供了一个 Fade 方法,该方法调整 UIElement 或 IEnumerable<UIElement> 的不透明度以实现淡入/淡出。
用法:
await Image.Fade(); // Fades Image opacity to 0 in 3 seconds
await Image.Fade(1); // Fades Image opacity to 1 in 3 seconds
await Image.Fade(1,6.Secs()); // Fades Image opacity to 1 in 6 seconds *Using included TimeSpanExtensions
ListExtensions
随机化对象列表的方法。
MyList.Shuffle();
并将 List<string> 转换为 CSV 列表并返回。
string myCsvString = MyList.ToCsvLine();
List<string> MyList = myCsvString.FromCsvLine();
BitmapExtensions
将 Bitmap 转换为 ImageSource。
Image.Source = Properties.Resources.MyResourceBitmap.ToImageSource();
历史
2015/11/8 - 初始帖子
2016/7/9 - 清理了一些错别字。