实现ppt幻灯片播放倒计时
需求:为控制会议时间,采取ppt幻灯片播放倒计时的办法,倒计时5分钟。
分析:用EnumWindows枚举窗口,发现PPT窗口类名有三种:PP12FrameClass、MS-SDIb、screenClass。其中screenClass代表全屏播放窗口。
设计思路:在timer控件中用FindWindow检查有无screenClass的窗口,用TimeSpan倒计时。
设计成一个托盘程序,用一个notifyIcon和contextMenuStrip关联。
代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using System.Text.RegularExpressions; using System.IO; namespace pptClock { //使用说明:用于PPT倒计时的winform。将播放的PPT文件名最后加上数字,表示播放限时的分钟数。若数字为0或无数字表示不限时。 public partial class Form1 : Form { //相关的win32 api [DllImport("user32.dll")] private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); [DllImport("user32.dll")] private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", EntryPoint = "FindWindow")] private extern static IntPtr FindWindow(string lpClassName, string lpWindowName); public const int WM_CLOSE = 0x10; [DllImport("user32.dll", EntryPoint = "SendMessageA")] public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam); //全屏播放PPT窗口信息 public struct WindowInfo { public IntPtr hWnd; //ppt窗口句柄 public string szWindowName;//窗口标题 public string szClassName;//类名:screenClass ,实际没有用。 public int timeL; //播放限时,从文件名中获取 } public bool hasscreenClass() //是否有全屏播放PPT { bool yn = false; IntPtr hwnd = FindWindow("screenClass", null); if (hwnd != IntPtr.Zero)//有全屏的PPT { yn = true; //则将窗口信息保存到wndfullscreen中 StringBuilder sb = new StringBuilder(256); //get hwnd wndfullscreen.hWnd = hwnd; //get window name GetWindowTextW(hwnd, sb, sb.Capacity); wndfullscreen.szWindowName = sb.ToString(); //get window class GetClassNameW(hwnd, sb, sb.Capacity); wndfullscreen.szClassName = sb.ToString(); Match result = Regex.Match(wndfullscreen.szWindowName.ToLower(), @"\d{1,2}(?=.ppt)", RegexOptions.RightToLeft); string r = result.Value; int timeL; if (r != "") { timeL = int.Parse(r); }else { timeL = 0; } wndfullscreen.timeL = timeL; } return yn; } WindowInfo wndfullscreen = new WindowInfo();//用于保存正在全屏播放的窗口信息 TimeSpan ts = new TimeSpan(0); //保存播放倒计时 bool playflag = false; //播放flag; bool rtimeflag = false; //是否对播放的ppt限时的flag; public Form1() { InitializeComponent(); } private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } private void Form1_Load(object sender, EventArgs e) { //this.Hide = true; this.ShowInTaskbar = false; timer1.Interval = 1000; this.Top = 0; Rectangle ScreenArea = System.Windows.Forms.Screen.GetBounds(this); int width1 = ScreenArea.Width; //屏幕宽度 int width2 = this.Width; this.Left = width1 - width2-100;//定位到屏幕右上角 timer1.Enabled = true; //开始计时 this.TopMost = true;//显示在最前 } private void timer1_Tick(object sender, EventArgs e) { if (playflag == false && hasscreenClass())//说明是刚开始播放 { playflag = true; int timeL = wndfullscreen.timeL; if(timeL >0 ) { rtimeflag = true; //表明要对本ppt进行倒计时 ts = new TimeSpan(0, wndfullscreen.timeL,0); //设定倒计时时间 } } if (playflag == true && rtimeflag == true) //正在播放且需要进行限时 { ts = ts.Subtract(new TimeSpan(0, 0, 1));//倒计时,每隔一秒减去一秒 String str = ts.Minutes.ToString() + ":" + ts.Seconds.ToString(); this.label1.Text = str; }else //不限时,则显示时钟 { String str = DateTime.Now.Hour.ToString() + ":"+ DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString(); this.label1.Text = str; } //用户提前退出ppt if (playflag == true && !hasscreenClass()) { playflag = false; rtimeflag = false; } //倒计时结束 if (ts.TotalSeconds < 0.0 && hasscreenClass())//当倒计时完毕 { IntPtr hwnd_win = wndfullscreen.hWnd; SendMessage(hwnd_win, WM_CLOSE, 0, 0);//发送退出消息 playflag = false; rtimeflag = false; } } private void 设置ToolStripMenuItem_Click(object sender, EventArgs e) { //选择播放目录 string fullfname, extension; string path = string.Empty; System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog(); if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { path = fbd.SelectedPath; } if (path != string.Empty) { DirectoryInfo di = new DirectoryInfo(path); foreach (var fi in di.GetFiles()) { extension =fi.Extension.ToLower(); if(extension == ".ppt" || extension == ".pptx") { try { fullfname = fi.FullName; //修改文件名加上“限时” if (fullfname.Contains("安全环保部")) { fi.MoveTo(fullfname + "_限时8" + extension); } else { fi.MoveTo(fullfname + "_限时5" + extension); } //打开目录 System.Diagnostics.Process.Start(fi.DirectoryName); } catch { } } } } } } }
补充:增加了可拖动窗口的代码如下:
//处理拖动 protected override void WndProc(ref Message m) { if(m.Msg == 0x0201){//鼠标左键按下 m.Msg = 0x00A1; //更改消息为非客户区按下鼠标 m.LParam = IntPtr.Zero; //默认值 m.WParam = new IntPtr(2); //鼠标放在标题栏内 } base.WndProc(ref m); }