最近發現日常的工作中,經常因為敲代碼而忘記了休息,晚上眼睛特别的累。
并且經常長時間看着顯示器,對眼睛一定是不好的,是以今天開發了一個小程式,用于提醒休息。
下面先看看運作效果:
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的簡潔了許多。
最後,把程式添加到系統的啟動檔案夾内,以後開機就能自動運作了。
當看到倒計時的時候,應該要停下工作,起來活動活動了。