我們都知道當系統進入螢幕保護模式之前, 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.
Step 2: 增加一個 ATL Simple Object 到你的類別中
a. 到右邊的 Class View 你的類別, 按滑鼠右鍵, 選擇新增 Class
b. 選擇 ATL Simple Object, 然後按 Next
c. 輸入簡單的名稱: MySenes, 然後按 Finish.
現在我們已經有一個簡單得 ATL 外殼了, 現在要實做 senes 的那些接收介面
Step 1: 到右邊的 Class View 中, 選擇你剛剛建立的 MySens 類別.
a. 滑鼠按右鍵 -> [Add] -> [Implement Interface ...]
b. 選擇 Interface: SENES Events Type Library <2.0>
c. 選擇你要實做的介面, 然後按 Finish.
然後就可以按照 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
沒有留言:
張貼留言