一款DYI动态桌面壁纸程序

一款DYI动态桌面壁纸程序

自己制作的动态桌面壁纸才能真正满足自己的需求。
通过窗口句柄遍历顶级窗口并在上加一层窗口用以播放视频文件实现动态桌面壁纸效果说起来也不繁琐。
以前有用过winFram设计动态桌面壁纸程序,发现运行时,将显示设置下的缩放与布局由100%改成更大时,全屏化窗口无法做到真正全屏,即窗口无法设置进行等比缩放。
而现在Windows10系统上WPF比winForm窗口程序集成好的多。所以我们用WPF来制作动态桌面壁纸程序。
程序所用CPU是与视频大小及清晰度相关,1分半100MB视频所占用的CPU几乎可以忽略不记,内存需要0.4GB左右。
但需要5%的GPU加速。

源代码

在Gird中加入一个MediaElement控件用于播放视频文件
Xaml

        <MediaElement x:Name="MediaElement" Loaded="MediaElement_Loaded" MediaEnded="MediaElement_MediaEnded" LoadedBehavior="Manual"/>

C#

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;

namespace Alice梦幻桌面
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        // 指向 Program Manager 窗口句柄
        private IntPtr programIntPtr = IntPtr.Zero;
        public MainWindow()
        {
            InitializeComponent();
        }
        public void Init()
        {
            // 通过类名查找一个窗口,返回窗口句柄。
            programIntPtr = Win32.FindWindow("Progman", null);

            // 窗口句柄有效
            if (programIntPtr != IntPtr.Zero)
            {

                IntPtr result = IntPtr.Zero;

                // 向 Program Manager 窗口发送 0x52c 的一个消息,超时设置为0x3e8(1秒)。
                Win32.SendMessageTimeout(programIntPtr, 0x52c, IntPtr.Zero, IntPtr.Zero, 0, 0x3e8, result);

                // 遍历顶级窗口
                Win32.EnumWindows((hwnd, lParam) =>
                {
                    // 找到包含 SHELLDLL_DefView 这个窗口句柄的 WorkerW
                    if (Win32.FindWindowEx(hwnd, IntPtr.Zero, "SHELLDLL_DefView", null) != IntPtr.Zero)
                    {
                        // 找到当前 WorkerW 窗口的,后一个 WorkerW 窗口。 
                        IntPtr tempHwnd = Win32.FindWindowEx(IntPtr.Zero, hwnd, "WorkerW", null);

                        // 隐藏这个窗口
                        Win32.ShowWindow(tempHwnd, 0);
                    }
                    return true;
                }, IntPtr.Zero);
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DirectoryInfo folder = new DirectoryInfo(Environment.CurrentDirectory + @"\MP4");//定位到应用程序位置
            try
            {
                foreach (FileInfo file in folder.GetFiles("*.mp4"))//在MP4文件夹下寻找并过滤视频文件
                {
                    MediaElement.Source = new Uri(file.FullName);
                    break;
                }
            }
            catch(ArgumentNullException)
            {
                MessageBox.Show("MP4文件夹下无MP4媒体文件");
            }
            catch(DirectoryNotFoundException)
            {
                MessageBox.Show("请在目录下添加MP4文件夹");
            }
            // 初始化桌面窗口
            Init();

            // 窗口置父,设置背景窗口的父窗口为 Program Manager 窗口
            IntPtr hwnd2 = new WindowInteropHelper(window).Handle;
            Win32.SetParent(hwnd2, programIntPtr);
        }

        private void MediaElement_Loaded(object sender, RoutedEventArgs e)
        {
            window.WindowState = WindowState.Maximized;//窗口最大化
            (sender as MediaElement).Play();//视频播放
        }
        /// <summary>
        /// 视频循环播放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            (sender as MediaElement).Stop();
            (sender as MediaElement).Play();
        }
    }
}

MP4文件要放到可执行文件所在文件夹下/MP4文件夹中,MediaElement只会播放第一个视频文件,过多放置视频文件并没有意义。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,针对你的问题,我可以提供一个 MATLAB 编写的求第一型三次样条插值函数的通用程序。以下是程序的基本思路: 1. 根据输入的原始数据,计算出每个相邻数据点之间的差值和比值,以及一阶和二阶差商。 2. 根据差商的性质,可以列出一个三对角线方程组,其中未知数为每个插值点处的函数值和导数值。 3. 解出方程组的未知数,得到插值函数在插值点处的函数值和导数值。 4. 根据插值函数的定义,可以计算出插值函数在插值点处的函数值和导数值。 以下是 MATLAB 实现的示例代码: ```matlab function [y0, dy0] = spline_interp(x, y, x0) % 一维3次样条插值(第一型边界条件) % 输入参数: % x: 原始数据的自变量 % y: 原始数据的因变量 % x0: 插值点的自变量 % 输出参数: % y0: 插值点处的因变量 % dy0: 插值点处的一阶导数 n = length(x); h = diff(x); dy = diff(y) ./ h; d2y = diff(dy) ./ h(1:end-1); % 构造三对角线方程组 A = zeros(n, n); B = zeros(n, 1); A(1, 1) = 1; A(n, n) = 1; for i = 2:n-1 A(i, i-1:i+1) = [h(i-1), 2*(h(i-1)+h(i)), h(i)]; B(i) = 3*(dy(i)-dy(i-1))/h(i) - 3*(dy(i-1)-dy(i-2))/h(i-1); end c = A \ B; % 计算插值点处的函数值和一阶导数 i = find(x <= x0, 1, 'last'); if i == 0 i = 1; elseif i == n i = n-1; end hi = h(i-1); yi = y(i-1); dyi = dy(i-1); d2yi = d2y(i-1); a = d2yi / (6*hi); b = dyi / 2 - hi*d2yi / 3; c = yi - hi^2*d2yi/6 - b*hi; dx = x0 - x(i); y0 = a*dx^3 + b*dx^2 + c*dx + yi; dy0 = 3*a*dx^2 + 2*b*dx + dyi; end ``` 以上是一个通用的程序,可以适用于任何需要求一维3次样条插值的问题。只需要输入原始数据的自变量和因变量,以及插值点的自变量,就可以得到插值点处的因变量和一阶导数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值