国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

VC實現系統熱鍵激活后臺服務程序

2019-11-17 05:01:24
字體:
來源:轉載
供稿:網友
  摘要: 本文給出了一種通過設置系統熱鍵來呼出在系統后臺隱藏運行的服務程序的一種方法,通過這種方法,可以實現后臺服務程序在必要的時候同用戶的交互設置。  引言  通常情況下,用于后臺監控的服務程序(Service)是沒有界面的,甚至也沒有提供任務欄圖標,因此絕大多數情況下服務程序是無法同用戶進行交互的。但是在實際應用中,這些服務程序雖然絕大多數時間是在后臺運行,但是在某些必要的情況下還是需要用戶的干預并同用戶進行一些必要的交互操作。但是由于服務程序沒有提供任何可供交互操作之用的界面,因此如何將其從后臺激活(即呼出)成為解決此問題的一個要害。本文下面就給出一種通過設置系統熱鍵的方法來激活運行于后臺的服務程序。  設計思路  盡管從理論上可以有許多方法來激活后臺運行的服務程序,比如可以通過尋找服務程序的窗口標題名而得到其窗口指針,然后再向此窗口發送消息使其出現到前臺;也可以通過系統快照對當前系統進程進行枚舉,然后再將其激活到前臺。但是以上這些方法都需要另外編寫應用程序,對后臺服務程序的激活實際是再這些應用程序中進行的,這樣的處理方式顯然十分不便,最好的方法是對程序的激活和隱藏處理均在服務程序內部完成。因此可以考慮接收系統發出的消息,假如通過設置全局鉤子對設置事件進行攔截捕捉,顯然是相當煩瑣的。在此考慮使用系統熱鍵來激活后臺服務程序,其實現過程非常簡單,只需先向操作系統添加一個全局原子(Atom),然后再向操作系統登記一個熱鍵,當程序在后臺運行期間一旦有此熱鍵按下,操作系統將會拋出系統消息WM_HOTKEY,所以服務程序只需在 WM_HOTKEY消息響應函數中添加相應代碼即可實現服務程序的后臺激活。  系統熱鍵的注冊  根據前面的介紹,不難寫出為后臺服務程序添加對系統熱鍵響應的功能代碼。首先通過函數GlobalFindAtom()查詢本服務程序所對應的全局原子是否已存在于全局原子表中,假如發現,則說明系統中已經存在有此服務,程序退出。假如沒有發現,則通過GlobalAddAtom()函數向全局原子表添加一個字串,并獲取得到一個唯一標識此字串的原子。以上兩函數原型分別為:
以下是引用片段:
ATOM GlobalFindAtom(LPCTSTR lpString);
  ATOM GlobalAddAtom(LPCTSTR lpString);
  其中,輸入參數為一個描述原子的字符串,假如GlobalFindAtom()從全局原子表中找到了指定的字串,那么將返回此字串對應的原子,否則返回0。GlobalAddAtom()假如創建成功,將返回一個新創建的原子。
  接下來,為了能在程序運行期間捕捉到系統熱鍵,需要通過RegisterHotKey()定義一個系統范圍的熱鍵。該函數原形如下:
以下是引用片段:
 BOOL RegisterHotKey(HWND hWnd, // 接收熱鍵響應的窗口句柄
  int id, // 熱鍵的標識
  UINT fsModifiers, // 控制鍵標志
  UINT vk // 虛擬鍵值
  );
  其中,熱鍵標識id必須是一個范圍在0xC000到0xFFFF之間的全局唯一的值,為了避免可能引起的熱鍵沖突,通常把GlobalAddAtom ()返回的原子作為參數傳入,而且GlobalAddAtom()返回值的范圍同id參數的答應范圍是完全一致的。參數fsModifiers定義了同虛擬鍵值vk同時按下而產生出系統熱鍵消息WM_HOTKEY的控制鍵組合,如MOD_ALT、MOD_CONTROL、MOD_SHIFT和 MOD_WIN等。在本例中將要設定的系統熱鍵為Alt+Ctrl+R,因此,參數fsModifiers和vk分別設置為MOD_ALT MOD_CONTROL和VK_R。有關系統熱鍵的注冊實現方法可以整理如下:
以下是引用片段:
// 獲取當前窗口句柄
  HWND handle = GetSafeHwnd();
  // 尋找HotKey對應的原子是否存在于原子列表
  if(GlobalFindAtom("Hotkey") == 0)
  {
  // 假如沒有存在于原子列表,則創建一個原子
  id = GlobalAddAtom("Hotkey");
  //注冊全局熱鍵Ctrl + Alt + R
  RegisterHotKey(handle, id, CONTROL + ALT, R);
  }
  else // 假如HotKey已經存在于原子列表,則終止程序運行
  PostQuitMessage(0);
  服務程序的隱藏與激活  服務程序除了被激活后同用戶的交互,絕大部分時間都是在后臺隱藏運行的,不僅界面是不可視的,而且在任務列表中也不應當出現。關于界面的隱藏比較簡單,可以通過向ShowWindow()函數設置SW_HIDE參數來實現,而在任務列表中的隱身則一般的做法是通過調用系統內核Kernel32.DLL的RegisterServicePRocess()函數將其設置成為一個服務進程,這樣,在任務列表中也實現了隱身。但是RegisterServiceProcess()函數并非一個標準的API函數,使用起來有點煩瑣。首先要通過 GetModuleHandle()函數得到Kernel32.DLL模塊的句柄,并由此通過GetProcAddress()函數進一步得出 RegisterServiceProcess()函數在Kernel32.DLL中的入口地址,最后才能使用 RegisterServiceProcess()函數。該函數原型聲明如下:
以下是引用片段:
DWord RegisterServiceProcess(DWORD dwProcessId,DWORD dwType);
  其第一個參數指定了將要注冊為服務進程的進程標識,參數dwType指定是去注冊一個服務進程(為1時)還是去卸載一個服務進程(為0時)。其具體服務注冊過程如下:
  typedef DWORD (WINAPI *RSP)(DWORD dwProcessId,DWORD dwType);
  // 獲取Kernel32.DLL模塊句柄
  HMODULE m_hKernel = ::GetModuleHandle("Kernel32.DLL");
  // 得到RegisterServiceProcess()函數入口地址
  RSP m_rsp = (RSP)::GetProcAddress(m_hKernel, "RegisterServiceProcess");
  // 注冊當前進程為服務進程
  m_rsp(::GetCurrentProcessId(),1);
  在服務程序后臺運行期間,一旦有系統熱鍵Alt+Ctrl+R按下,將發出系統熱鍵消息WM_HOTKEY,該消息的消息響應函數不能通過 ClassWizard來添加,而只能手工完成消息映射。在消息響應函數中,通過對消息參數 wParam的判定可以確定出是否是本服務程序所設定的系統熱鍵,假如是,通過ShowWindow(SW_SHOW)將程序界面顯示出來,以進行同用戶的交互操作:
以下是引用片段:
void CServiceDlg::OnHotKey(WPARAM wParam, LPARAM lParam)
  {
  // 判定是否是本服務程序設置的系統熱鍵
  if (wParam == id)
  {
  ……
  // 在此發送WM_PAINT消息,在OnPain()中通過
  // ShowWindow(SW_SHOW)將界面設置為可視
  PostMessage(WM_PAINT, 0, 0);
  }
  }
  系統熱鍵的卸載  由于前面將系統熱鍵、全局原子等都注冊到系統,因此必須在服務程序退出之前將其卸載,否則將導致下次注冊時的失敗。函數UnregisterHotKey()負責完成對系統熱鍵的釋放,GlobalDeleteAtom()將全局原子從全局原子列表刪除。  小結  通過本文所述方法為后臺運行的系統服務程序添加此熱鍵呼出功能可以真正實現程序的后臺隱蔽運行、熱鍵激活,非常有利于治理員和用戶的治理與使用。本文所述程序在windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 德安县| 尚义县| 怀安县| 塔城市| 砀山县| 罗源县| 邢台县| 丰顺县| 乌什县| 扎兰屯市| 刚察县| 凉山| 浮山县| 鄂尔多斯市| 庆城县| 济源市| 壶关县| 色达县| 微山县| 黄大仙区| 南丹县| 外汇| 米林县| 铁岭县| 桐乡市| 无为县| 信丰县| 万荣县| 盘山县| 团风县| 保靖县| 华容县| 枣阳市| 临澧县| 微博| 克什克腾旗| 鹤峰县| 大荔县| 且末县| 龙岩市| 淄博市|