动态壁纸-软件制作-教程
0、开始:
演示视频:请移至(bilibili)
源代码:请移至(github)
下面是关键实现,具体请看仓库源码。
1、创建工程
打开vs2017,选择 文件 > 新建 > 项目 > Windows 窗体应用。
2、声明用到的Win32API
添加一个 Win32.cs 静态类,里面的API我们用到时,再说。
public static class Win32 { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string className,string winName); [DllImport("user32.dll")] public static extern IntPtr SendMessageTimeout(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam, uint fuFlage, uint timeout, IntPtr result); [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc proc,IntPtr lParam); public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam); [DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string winName); [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hwnd,int nCmdShow); [DllImport("user32.dll")] public static extern IntPtr SetParent(IntPtr hwnd,IntPtr parentHwnd); }
3、代码
Form1.cs
1 public partial class Form1 : Form 2 { 3 // 指向 Program Manager 窗口句柄 4 private IntPtr programIntPtr = IntPtr.Zero; 5 6 // 桌面背景窗口 7 private BgForm bgForm = null; 8 9 public Form1() 10 { 11 InitializeComponent(); 12 13 // 设置循环播放 14 axWindowsMediaPlayer1.settings.setMode("loop", true); 15 } 16 17 private void Form1_Load(object sender, EventArgs e) 18 { 19 20 } 21 22 public void Init() 23 { 24 // 通过类名查找一个窗口,返回窗口句柄。 25 programIntPtr = Win32.FindWindow("Progman", null); 26 27 // 窗口句柄有效 28 if(programIntPtr != IntPtr.Zero) 29 { 30 31 IntPtr result = IntPtr.Zero; 32 33 // 向 Program Manager 窗口发送 0x52c 的一个消息,超时设置为0x3e8(1秒)。 34 Win32.SendMessageTimeout(programIntPtr, 0x52c, IntPtr.Zero, IntPtr.Zero, 0, 0x3e8, result); 35 36 // 遍历顶级窗口 37 Win32.EnumWindows((hwnd, lParam) => 38 { 39 // 找到包含 SHELLDLL_DefView 这个窗口句柄的 WorkerW 40 if (Win32.FindWindowEx(hwnd,IntPtr.Zero, "SHELLDLL_DefView", null) != IntPtr.Zero) 41 { 42 // 找到当前 WorkerW 窗口的,后一个 WorkerW 窗口。 43 IntPtr tempHwnd = Win32.FindWindowEx(IntPtr.Zero, hwnd, "WorkerW", null); 44 45 // 隐藏这个窗口 46 Win32.ShowWindow(tempHwnd, 0); 47 } 48 return true; 49 }, IntPtr.Zero); 50 } 51 } 52 53 // 打开视频按钮 的事件 54 private void button2_Click(object sender, EventArgs e) 55 { 56 // 创建对话框 57 OpenFileDialog dialog = new OpenFileDialog(); 58 // 设置过滤器,只允许 .wmv 和 mp4 格式的视频。 59 dialog.Filter = "视频(*.wmv;*.mp4)|*.wmv;*.mp4"; 60 61 DialogResult result = dialog.ShowDialog(); 62 63 if(result == DialogResult.OK) 64 { 65 // 把打开的视频路径,给播放器。 66 axWindowsMediaPlayer1.URL = dialog.FileName; 67 68 // 播放视频。 69 axWindowsMediaPlayer1.Ctlcontrols.play(); 70 } 71 } 72 73 // 设置壁纸 按钮事件 74 private void button1_Click(object sender, EventArgs e) 75 { 76 if(bgForm == null) 77 { 78 // 创建背景窗口 79 bgForm = new BgForm(); 80 81 // 初始化桌面窗口 82 Init(); 83 84 // 窗口置父,设置背景窗口的父窗口为 Program Manager 窗口 85 Win32.SetParent(bgForm.Handle, programIntPtr); 86 87 // 显示背景窗口 88 bgForm.Show(); 89 } 90 91 // 预览窗口视频暂停播放 92 axWindowsMediaPlayer1.Ctlcontrols.pause(); 93 94 // 背景窗口视频播放 95 bgForm.Play(axWindowsMediaPlayer1); 96 } 97 98 // 播放器的状态发生改变,为了解决无缝视频循环。 99 private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e) 100 { 101 // 播放结束 102 if(axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsMediaEnded) 103 { 104 // 无黑屏循环播放视频 105 axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 0; 106 } 107 } 108 }
BgForm.cs
1 public partial class BgForm : Form 2 { 3 public BgForm() 4 { 5 InitializeComponent(); 6 7 // 隐藏播放器的ui 8 axWindowsMediaPlayer1.uiMode = "none"; 9 10 // 最大化窗口(全屏) 11 WindowState = FormWindowState.Maximized; 12 13 // 如果最大化窗口,屏幕边缘出现缝隙。改用如下代码进行全屏: 14 // this.Bounds = Screen.PrimaryScreen.Bounds; 15 16 // 设置循环播放 17 axWindowsMediaPlayer1.settings.setMode("loop", true); 18 } 19 20 // 播放方法,在Form1中有调用。 21 public void Play(AxWMPLib.AxWindowsMediaPlayer mediaPlayer) 22 { 23 // 使用Form1预览窗口中 url、音量。 24 axWindowsMediaPlayer1.URL = mediaPlayer.URL; 25 axWindowsMediaPlayer1.settings.volume = mediaPlayer.settings.volume; 26 27 // 背景窗口播放器,播放视频。 28 axWindowsMediaPlayer1.Ctlcontrols.play(); 29 } 30 31 // 跟Form1预览窗口,中一样,解决无缝视频播放。 32 private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e) 33 { 34 if(axWindowsMediaPlayer1.playState == WMPLib.WMPPlayState.wmppsMediaEnded) 35 { 36 axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 0; 37 } 38 39 } 40 }
5、完成
演示视频:请移至(bilibili)
源代码:请移至(码云)