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)
源代碼:請移至(碼雲)