动态壁纸-软件制作-教程

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

  源代码:请移至(码云

 

posted @ 2017-08-04 09:55  三月天的风雪  阅读(18911)  评论(0编辑  收藏  举报