一款DYI動态桌面桌面程式
自己制作的動态桌面桌面才能真正滿足自己的需求。
通過視窗句柄周遊頂級視窗并在上加一層視窗用以播放視訊檔案實作動态桌面桌面效果說起來也不繁瑣。
以前有用過winFram設計動态桌面桌面程式,發現運作時,将顯示設定下的縮放與布局由100%改成更大時,全屏化視窗無法做到真正全屏,即視窗無法設定進行等比縮放。
而現在Windows10系統上WPF比winForm視窗程式內建好的多。是以我們用WPF來制作動态桌面桌面程式。
程式所用CPU是與視訊大小及清晰度相關,1分半100MB視訊所占用的CPU幾乎可以忽略不記,記憶體需要0.4GB左右。
但需要5%的GPU加速。
源代碼
在Gird中加入一個MediaElement控件用于播放視訊檔案
Xaml
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隻會播放第一個視訊檔案,過多放置視訊檔案并沒有意義。