需求:为控制会议时间,采取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 hwndwndfullscreen.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;}//用户提前退出pptif (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); }