開發環境
作業系統:Windows Server 2008 R2
整合式開發環境(IDE):Microsoft Visual Studio 2010
開發語言:c#
建立項目
檔案》建立》項目
.NET Framework可以選擇2.0版本,也可以選擇4.0版本;
項目類型選擇:Windows表單應用程式
輸入項目名稱,確定
項目建立成功,如:
修改主表單屬性
修改表單的“FormBorderStyle”屬性為“none”,實現一個沒有邊框的表單
修改後視窗設計器中顯示如下:
依次按修改其它屬性,屬性值黑體加粗的是修改過的
屬性說明:
ShowIcon=False,不顯示表單的表徵圖;
ShowInTaskbar=False,使表單不在Windows工作列中出現;
SizeGripStyle=Hide,禁用拖動表單右下角可以改變大小的功能;
WindowsState=Minimized,視窗啟動後最小化;
設定完這些屬性後,編譯,運行,程式是在運行狀態,但是卻看不到程式的視窗;
實現熱鍵功能
這裡需要使用WindowsAPI
註冊熱鍵:RegisterHotKey
該函數定義一個系統範圍的熱鍵。函數原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk);
取消熱鍵註冊:UnregisterHotKey
該函數釋放調用線程先前登記的熱鍵。
擷取熱鍵ID:GlobalAddAtom
只適用於傳統型應用程式。
向全域原子表添加一個字串,並返回這個字串的唯一識別碼(原子ATOM)。
API及局部變數定義:
/// <summary> /// 向全域原子表添加一個字串,並返回這個字串的唯一識別碼(原子ATOM)。 /// </summary> /// <param name="lpString">自己設定的一個字串</param> /// <returns></returns> [System.Runtime.InteropServices.DllImport("Kernel32.dll")] public static extern Int32 GlobalAddAtom(string lpString); /// <summary> /// 註冊熱鍵 /// </summary> /// <param name="hWnd"></param> /// <param name="id"></param> /// <param name="fsModifiers"></param> /// <param name="vk"></param> /// <returns></returns> [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk); /// <summary> /// 取消熱鍵註冊 /// </summary> /// <param name="hWnd"></param> /// <param name="id"></param> /// <returns></returns> [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); /// <summary> /// 熱鍵ID /// </summary> public int hotKeyId = 100; /// <summary> /// 熱鍵模式:0=Ctrl + Alt + A, 1=Ctrl + Shift + A /// </summary> public int HotKeyMode = 1; /// <summary> /// 修飾鍵的類型 /// </summary> public enum KeyModifiers : uint { None = 0, Alt = 1, Control = 2, Shift = 4, Windows = 8 } /// <summary> /// 用於儲存截取的整個螢幕的圖片 /// </summary> protected Bitmap screenImage;
註冊熱鍵:
private void Form1_Load(object sender, EventArgs e) { //隱藏視窗 this.Hide(); //註冊快速鍵 //註:HotKeyId的合法取之範圍是0x0000到0xBFFF之間,GlobalAddAtom函數得到的值在0xC000到0xFFFF之間,所以減掉0xC000來滿足調用要求。 this.hotKeyId = GlobalAddAtom("Screenshot") - 0xC000; if (this.hotKeyId == 0) { //如果擷取失敗,設定一個預設值; this.hotKeyId = 0xBFFE; } if (this.HotKeyMode == 0) { RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Alt, Keys.A); } else { RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Shift, Keys.A); } }
熱鍵響應函數:
/// <summary> /// 處理快速鍵事件 /// </summary> /// <param name="m"></param> protected override void WndProc(ref Message m) { //if (m.Msg == 0x0014) //{ // return; // 禁掉清除背景訊息 //} const int WM_HOTKEY = 0x0312; switch (m.Msg) { case WM_HOTKEY: ShowForm(); break; default: break; } base.WndProc(ref m); }
視窗實現原理
視窗實際是一個沒有邊框,沒有菜單,沒有工具列的一個全屏頂層視窗。
當按下熱鍵時,程式首先擷取整個螢幕的圖片,儲存到“screenImage”變數中;然後添加遮罩層,將其設定為表單的背景圖,將視窗大小設定為主畫面的大小,顯示視窗;讓人感覺是在案頭上加一個半透明的遮罩層一樣。
代碼如下:
/// <summary> /// 如果視窗為可見狀態,則隱藏視窗; /// 否則則顯示視窗 /// </summary> protected void ShowForm() { if (this.Visible) { this.Hide(); } else { Bitmap bkImage = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height); Graphics g = Graphics.FromImage(bkImage); g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size, CopyPixelOperation.SourceCopy); screenImage = (Bitmap)bkImage.Clone(); g.FillRectangle(new SolidBrush(Color.FromArgb(64, Color.Gray)), Screen.PrimaryScreen.Bounds); this.BackgroundImage = bkImage; this.ShowInTaskbar = false; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Width = Screen.PrimaryScreen.Bounds.Width; this.Height = Screen.PrimaryScreen.Bounds.Height; this.Location = Screen.PrimaryScreen.Bounds.Location; this.WindowState = FormWindowState.Maximized; this.Show(); } }
取消熱鍵註冊
關閉視窗時,要取消熱鍵註冊,代碼如下:
/// <summary> /// 當視窗正在關閉時進行驗證 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (e.CloseReason == CloseReason.ApplicationExitCall) { e.Cancel = false; UnregisterHotKey(this.Handle, hotKeyId); } else { this.Hide(); e.Cancel = true; } }
到這裡,熱鍵註冊,視窗的顯示等功能已經基本完成。
注意:測試本代碼時最好在表單上添加一個按鈕,用於關閉或隱藏視窗;因為視窗是全屏的,不能響應ESC鍵,所以只能通過工作管理員來結束進程退出。調試時最好是在表單上添加一個Label控制項來顯示需要的變數資訊,因為視窗是頂層的全屏視窗,斷點被命中時根本沒辦法操作VS。