程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 阻止系統自動睡眠的小軟件,附C#制作過程

阻止系統自動睡眠的小軟件,附C#制作過程

編輯:C#入門知識

因為有時下載東西的時候,不想讓電腦自動深入睡眠,所以就開啟了離開模式。這樣不但不節能環保,而且到真正想要睡眠的時候就是一翻蛋疼。

改過自新,關閉了離開模式,同時無操作30分鐘後也會進入睡眠模式。但是在下載的時候怎麼辦呢?反正也是閒著,就寫了這東西:

增加了合上蓋子時保持喚醒功能,截圖懶得換了。

程序在最後面。

 


下面是實現(其實寫這個程序的目的之一就是為了學習C#……):

(所謂的)是調用這個API ( MSDN的介紹) :

EXECUTION_STATE WINAPI SetThreadExecutionState(
  _In_  EXECUTION_STATE esFlags
);

這個API作用是允許程序通知系統在使用某些資源,以阻止系統進入睡眠或關閉顯示器。

參數esFlags是以下選項的組合:ES_AWAYMODE_REQUIREDES_CONTINUOUSES_DISPLAY_REQUIREDES_SYSTEM_REQUIRED

按字面意思理解選項即可。其中ES_CONTINUOUS表示在下一次調用該API前,本次設置會一直生效。所以在大部分情況下,加上這個選項的話,只需調用一次API即可。(這個API是針對每個線程而言的,只要這個線程不退出,和CONTINUOUS一起設置的選項就會一直生效)。

若是單獨使用ES_CONTINUOUS選項,則會恢復睡眠策略。

 

using System.Runtime.InteropServices;
// 按照API原型,將類型轉換C#的類型聲明即可
[DllImport("kernel32.dll")]
static extern uint SetThreadExecutionState(uint esFlags);
// 選項所用到的常數
const uint ES_AWAYMODE_REQUIRED = 0x00000040;
const uint ES_CONTINUOUS = 0x80000000;
const uint ES_DISPLAY_REQUIRED = 0x00000002;
const uint ES_SYSTEM_REQUIRED = 0x00000001;

C#所有的方法變量都必須聲明在一個類裡。我把這些東西聲明到一個叫Public的類。聲明後,就可以直接調用該方法了。

 

該程序可以通過主界面以及托盤彈出的菜單進行選擇的設置,所以需要同步這兩個地方的狀態,Checkbox該自動打鉤時打鉤,該取消時取消等等。為了寫代碼時,不需要考慮這些東西,就抽象出了一個Option類(每次起名的時候就痛恨自己英文太差)。通過該類可以設置選項,同時也可以在裡面注冊一個委托,當選項有變時,會調用這些委托。同時,該類也會負責在設置選項時自動通知系統。注:在析構函數中,以參數ES_CONTINUOUS調用一次該API恢復原來的休眠配置。

 

    主界面就是拉拉控件,處理下事件。注意,Checkbox的選項值可能會因為鼠標點擊以外的原因改變,所以選擇監聽鼠標點擊事件。為了處理事件時少粘貼點代碼,我用一個Dictionary將每個CheckBox和一個選項值綁定在一起。然後使用同一個事件處理函數,在函數裡,根據sender確定是哪個Checkbox發送的,再根據那個Dictionary確定需要設置什麼樣的值。 然後向Option類注冊一個委托,在選項有變時改變Checkbox到正確的狀態。

    最小化時直接隱藏窗口,而不是縮小的任務欄:可以選擇監聽Resize事件,在事件中判斷窗體是不是處於最小化的狀態,是的話就隱藏窗體。更徹底的是重載窗體類的消息處理函數,並自己處理最小化消息。

protected override void WndProc(ref Message m)
{
	const int WM_SYSCOMMAND = 0x112;
	const int SC_CLOSE = 0xF060;
	const int SC_MINIMIZE = 0xF020;
	const int SC_MAXIMIZE = 0xF030;
	if (m.Msg == WM_SYSCOMMAND)
	{
		if (m.WParam.ToInt32() == SC_MINIMIZE)
		{
			this.Hide();
			return;
		}
	}
	base.WndProc(ref m);
}

 

    托盤:使用NotifyIcon控件。注意,這個控件必須設置ICON才能顯示。添加一個ContextMenuStrip對象作為右鍵點擊時的彈出菜單。為了讓點擊托盤時能彈出這個菜單,可以將托盤控件的ContextMenuStrip屬性設置為該菜單即可。在這裡因為我需要監聽鼠標事件,讓左鍵點擊時顯示主窗口,我就在事件處理函數中順便處理右鍵點擊了。如果是右鍵點擊,則調用該菜單的Show方法就可以了。

    然後是菜單的內容。新建若干ToolStripMenuItem對象,並用ContextMenuStrip.Items.Add(…)方法將這些Item添加進菜單即可。每個Item可以監聽鼠標點擊事件,同時也可以通過設置它的Checked屬性來顯示item文本前的小鉤鉤。需要分割線的話添加ToolStripSeparator對象就可以了。

    動態的托盤圖標:為了少寫點什麼讀取文件之類的代碼,就直接把托盤圖標添加進程序的資源文件裡了。方法是在項目的屬性裡選擇資源,然後就可以添加想要的資源了。需要訪問這些資源時,在myProject.Properties.Resources裡就可以訪問了。如:System.Drawing.Bitmap bitmap1 = myProject.Properties.Resources.Image01(參考MSDN)。最後再根據選項的狀態選擇相應的圖標即可。

    托盤消失:直接執行Application.Exit()的話,托盤不會自動消失,得鼠標從托盤上面滑過才可以。為了讓托盤顯示,執行NotifyIcon對象的Dispose( )方法就好了。

 

讓程序開始運行時只顯示托盤,而不顯示主窗體。放狗搜索的時候發現這個問題讓很多新手喝了一壺。我的解決方法是:讓程序開始是不運行主窗體的代碼,只運行托盤控件的代碼。轉到Main函數,發現Main函數最後執行的是 Application.Run(…) 這個方法。最開始嘗試在這個方法的參數裡填入一個NotifyIcon對象,但是不行。然後試著直接用new新建一個NotifyIcon對象,這個時候托盤是會顯示出來,但是程序馬上就會退出了。最後發現這個方法有個無參重載版本,執行後程序就不會退出了……

 

:在項目的屬性裡,選擇應用程序選項卡,就可以設置圖標了。


睡眠終結者: http://files.cnblogs.com/h46incon/SleepPreventer.zip

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved