2008年11月20日 星期四

[C++] 捕捉螢幕保護模式事件的方法

我們都知道當系統進入螢幕保護模式之前, Windows 會送出 WM_SYSCOMMAND message (wParam == SC_SCREENSAVE). 給目前 Active 的視窗. 可是這個方法有侷限性. 請看下文.

 

本文內容包含

     1. 系統進入螢幕保護模式前, 讓程式接收 ScreenSaver 事件的方法 

     2. 如何關閉螢幕保護模式

     3. 系統從螢幕保護模式恢復後的事件接收 (網路事件, 電源管理事件)

 

我們開始吧.

系統進入螢幕保護模式前, 讓程式接收 ScreenSaver 事件的方法

下面是一個最簡單的 code.  (參考axterix code )

CWindowContextMS::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_SYSCOMMAND)
{
if (wParam == SC_SCREENSAVE)
{
LOG("GOT THE SCREEN SAVER EVENT");
}
}
}

可是, 這只限制在當你的程式正在 Active 時, 才會收到. 如果當你的程式在背景執行時, 將收不到系統送來的 SC_CREENSAVE 的訊息.


所以, 如果想要讓背景程式也要能夠收到螢幕保護模式的事件, 那只有使用 Hook 了.
對於 Hook 如何做?

       1. Yan-Fei Wei 列出了幾項作法
       2. Bite Qiu 提出了很漂亮的作法



如何關閉螢幕保護模式
對於一些特殊需求的程式, 我們不希望系統進入螢幕保護模式. 好的.那麼我們該怎麼做呢? 下面是標準答案:

How to force a screen saver to close once started in Windows NT, Windows 2000, and Windows Server 2003



系統從螢幕保護模式恢復後的事件接收
SC_SCREENSAVE 訊息只有在螢幕保護模式啟動前會發出, 可是當系統從螢幕保護模式恢復時, 卻無法提供相關事件. 這時候, 我們就必須依靠 System Event Notification Service (SENS), 來幫我們的忙.

SENS 提供了 ISenLogon 介面, 能夠通知我們, 當
      1. 系統進入螢幕保護模式之後
      2. 系統已經從螢幕保護模式回來 (Resume)
      3. 當使用者把網路線拔掉
      4. 當使用者把網路線插回去
      5. 系統電源資訊: 電源是電池電源還是 AC 電源, 你的電池是否快沒電了.  等等



怎麼做?
你可以在這裡找到標準答案:
http://support.microsoft.com/kb/321381 (使用 VC6)


下面是用 Visual Studio .Net 2008, 建立最簡單的 ATL 專案, 應該對你有幫助.



建立專案

Step 1: 建立 ATL 專案, 選擇 Executable(EXE), 然後按 Finish.



01_ChooseExecutable



Step 2:  增加一個 ATL Simple Object 到你的類別中



       a. 到右邊的 Class View 你的類別, 按滑鼠右鍵, 選擇新增 Class



2_addclass



        b. 選擇 ATL Simple Object, 然後按 Next



03_chooseATLsimpleobject



        c.  輸入簡單的名稱: MySenes, 然後按 Finish.



04_shortname



 



現在我們已經有一個簡單得 ATL 外殼了, 現在要實做 senes 的那些接收介面



Step 1:  到右邊的 Class View 中, 選擇你剛剛建立的 MySens 類別.



                a. 滑鼠按右鍵 -> [Add] -> [Implement Interface ...]



05_implement_interface



       



                b. 選擇 Interface: SENES Events Type Library <2.0>



06_typelibrary



 



                 c. 選擇你要實做的介面, 然後按 Finish.



07_choose_interface



 



然後就可以按照  http://support.microsoft.com/kb/321381 教你的方法實做與建立整個 scenes 介面功能.

另外, 你還需要的 library: sensapi.lib

Enjoy.
by Jing





參考資料
[1] Yan-Fei Wei 列出了幾項作法
[2] Bite Qiu 提出了很漂亮的作法
[3] How to force a screen saver to close once started in Windows NT, Windows 2000, and Windows Server 2003
[4] System Event Notification Service
[5] http://support.microsoft.com/kb/321381



 



 



 





沒有留言:

張貼留言