最近發現日常的工作中,經常因為敲代碼而忘記了休息,晚上眼睛特別的累。
並且經常長時間看着顯示器,對眼睛一定是不好的,所以今天開發了一個小程序,用於提醒休息。
下面先看看運行效果:
1、程序啟動后,后台運行,不顯示界面,也沒有制作顯示托盤圖標
2、當時間到達后,屏幕居中顯示以下界面,並且開始倒計時
3、倒計時為0時,屏幕熄滅,但其實隨便碰一下鼠標或鍵盤就會點亮顯示器了。
4、人手點亮顯示器后,顯示以下界面,也可以不亮屏的狀態下直接輸入密碼。
5、輸入密碼並且正確,界面隱藏至后台,並且重新計時。
上代碼:
首先,要有一個控制顯示器的幫助類,MonitorHelper
1 using System; 2 using System.Runtime.InteropServices; 3
4 namespace MonitorTool 5 { 6 /// <summary>
7 /// 顯示器開關控制 8 /// </summary>
9 public class MonitorHelper 10 { 11 [DllImport("user32.dll")] 12 public static extern IntPtr SendMessage( 13 IntPtr hWnd, 14 uint msg, 15 uint wParam, 16 int lParam); 17
18 //系統消息
19 private const uint WM_SYSCOMMAND = 0x112; 20
21 //關閉顯示器的系統命令
22 private const int SC_MONITORPOWER = 0xF170; 23
24 //2為PowerOff, 1為省電狀態,-1為開機
25 private const int MonitorPowerOff = 2; 26
27 /// <summary>
28 /// 關閉顯示器 29 /// </summary>
30 public static void PowerOff(IntPtr hWnd) 31 { 32 SendMessage( 33 hWnd, 34 WM_SYSCOMMAND, 35 SC_MONITORPOWER, 36 2
37 ); 38 } 39
40 /// <summary>
41 /// 打開顯示器 42 /// </summary>
43 public static void PowerOn(IntPtr hWnd) 44 { 45 SendMessage( 46 hWnd, 47 WM_SYSCOMMAND, 48 SC_MONITORPOWER, 49 -1
50 ); 51 } 52 } 53 }
程序界面:
只有2個控件,分別是Label控件,ID是"lblTips",TextBox控件,ID是"txtPwd"
窗體的TopMost設置為True,StartPosition設置為CenterScreen
窗體的后台代碼:
1 using System; 2 using System.Threading; 3 using System.Windows.Forms; 4
5 namespace MonitorTool 6 { 7 public partial class FrmMain : Form 8 { 9 //工作總時間
10 public int WorkTime { get; set; } 11 //顯示器關閉前的倒計時時間
12 public int TipsTime { get; set; } 13
14 public string Password { get; set; } 15 //線程變量
16 public Thread tTotal { get; set; } 17
18 public FrmMain() 19 { 20 InitializeComponent(); 21 //初始化變量值,也是方便以后修改
22 this.WorkTime = 50 * 60 * 1000; //ms(分鍾*60秒*1000毫秒)
23 this.TipsTime = 5; //s(倒計時的總秒數)
24 this.Password = "cong"; //重新計時的密碼
25 } 26
27 private void FrmMain_Load(object sender, EventArgs e) 28 { 29 TimerTotal(); 30
31 //隱藏窗口
32 this.ShowInTaskbar = false; 33 this.Hide(); 34 } 35
36 //開始計時,至屏幕熄滅的方法
37 public void TimerTotal() 38 { 39 //打開新的線程
40 tTotal = new Thread(() =>
41 { 42 //掛起線程,直到到達工作總時間
43 Thread.Sleep(this.WorkTime); 44
45 //聲明系統的委托
46 Action<string> actionDelegate = null; 47
48 //第一次使用委托,顯示窗口
49 actionDelegate = (x) =>
50 { 51 lblTips.Text = ""; 52 this.Show(); 53 }; 54 this.Invoke(actionDelegate, "show"); 55
56 //第二次使用委托,for循環,顯示倒計時提示信息,每個循環掛起線程1秒
57 for (int i = this.TipsTime; i >= 0; i--) 58 { 59 actionDelegate = (x) =>
60 { 61 lblTips.Text = string.Format("Monitor will turn off after {0} secords ...", x); 62 }; 63 this.lblTips.Invoke(actionDelegate, i.ToString()); 64 Thread.Sleep(1000); 65 } 66
67 //第三次使用委托,顯示器熄滅,掛起線程3秒,用於緩沖,並且使密碼框獲得焦點,以便快速輸入密碼
68 actionDelegate = (x) =>
69 { 70 MonitorHelper.PowerOff(this.Handle); 71 Thread.Sleep(3000); 72 lblTips.Text = "please type your password."; 73 txtPwd.Focus(); 74 }; 75 this.Invoke(actionDelegate, "hide"); 76 }); 77
78 //運行線程前,必須定義為后台運行,並開啟線程
79 tTotal.IsBackground = true; 80 tTotal.Start(); 81 } 82
83 //密碼框,如果密碼正確,則再次開啟線程,重新計時
84 private void txtPwd_TextChanged(object sender, EventArgs e) 85 { 86 if (txtPwd.Text.Trim().Equals(this.Password)) 87 { 88 txtPwd.Text = ""; 89
90 TimerTotal(); 91 this.Hide(); 92 } 93 } 94 } 95 }
這樣就可以完成了。
其實也可以使用Timer控件來制作,但是因為不大熟練線程的使用,所以特意使用線程。
當然,這只用到了線程中很少一部分的知識,代碼比使用Timer的簡潔了許多。
最后,把程序添加到系統的啟動文件夾內,以后開機就能自動運行了。
當看到倒計時的時候,應該要停下工作,起來活動活動了。