|
讀者對屏幕保護程序已經(jīng)相當熟悉了。去年泰坦尼克號的屏幕保護程序風行了全世界,足見其魅力。有的屏幕保護程序功能十分強大,可以提供圖象,動畫,音頻,視頻等所有的多媒體功能。盡管可以很容易獲得漂亮的屏幕保護程序,但擁有自己的屏幕保護程序?qū)τ脩粢苍S更有吸引力。 VC5.0/6.0是開發(fā)屏幕保護程序的好工具。靜態(tài)鏈接庫SCRNSAVE.LIB對屏幕保護程序提供了支持。RNSAVE.LIB包含了建立屏幕保護程序的主程序和缺省功能,用戶可以方便地使用SDK進行編程并與之連接。盡管SDK編程相對MFC麻煩,但編寫相對簡單的屏幕保護程序卻相當容易甚至比用MFC編程更簡單。 也可以使用MFC編寫屏幕保護程序。但遺憾的是MFC不支持SCRNSAVE.LIB,必須手工完成原來由SCRNSAVE.LIB提供的功能,比較麻煩和不好理解。不過,編寫復雜的屏幕保護程序時,MFC對于顯示模塊和對話框處理可以提供比SDK方便得多的功能。為簡單起見先介紹如何使用SDK編寫屏幕保護程序。 一. 屏幕保護程序和SCRNSAVE.LIB 先從開發(fā)者的角度對屏幕保護程序說明如下: 首先,屏幕保護程序是Win32 API 支持一種特殊的應(yīng)用程序并由系統(tǒng)自動激活。其機制是當條件滿足時,系統(tǒng)向當前活動窗口發(fā)出字參數(shù) wParam 值為SC_SCREENSAVE的WM_SYSCOMMAND消息,然后由當前活動窗口執(zhí)行SYSTEM.INI文件中[boot]區(qū)指定的屏幕保護程序。 屏幕保護程序激活的條件是在規(guī)定時間內(nèi)沒有鼠標或鍵盤輸入.當前的活動窗口是標準的WINDOWS應(yīng)用程序。因為非WINDOWS應(yīng)用,不會理睬WM_SYSCOMMAND消息。 顯然,如果當前活動的程序接管了字參數(shù) wParam 值為SC_SCREENSAVE 的WM_SYSCOMMAND 消息并且不傳遞到 DefWindowProc函數(shù)就可以禁止屏幕保護程序。這對某些運行中不愿意被打斷的程序如視頻播放,光盤刻錄程序特別有用。 其次,可以在控制面板的顯示器中選擇需要的屏幕保護程序,并可以配置屏幕保護程序的參數(shù)。屏幕保護程序應(yīng)該提供配置屏幕保護程序的對話框。 再次,屏幕保護程序有特別的輸出函數(shù),資源定義和變量聲明。SCRNSAVE.LIB包含了建立屏幕保護程序的主程序。屏幕保護程序啟動時SCRNSAVE.LIB自動創(chuàng)建一全屏窗口,并描述窗口類為無光標的滿黑屏。 用戶編寫的屏幕保護程序必須包含三個基本函數(shù)ScreenSaverProc,ScreenSaverConfigureDialog 和RegisterDialogClasses 并與SCRNSAVE.LIB連接。 1.ScreenSaverProc 窗口函數(shù)處理特定的消息并把未處理的消息傳遞給SCRNSAVE.LIB 。ScreenSaverProc 一般處理以下消息: WM_CREATE 讀取.INI或注冊表的初始化數(shù)據(jù),設(shè)置定時器以及其他初始化操作。 WM_ERASEBKGND 擦除背景為下一步繪圖作準備。 WM_TIMER 進行繪圖輸出。用戶可以實現(xiàn)自己的動畫功能以及其他操作。 WM_DESTROY 刪除定時器以及其他對象 ScreenSaverProc 把未處理的消息傳遞到SCRNSAVE.LIB中的 DefScreenSaverProc函數(shù) 處理。由它完成許多復雜和關(guān)鍵的操作比如何時激活,何時關(guān)閉等,大大方便了屏幕保護程序的編寫。 2.ScreenSaverConfigureDialog函數(shù)處理屏幕保護程序配置對話框。該對話框由控制面板的顯示器設(shè)置程序調(diào)用。用戶輸入的配置數(shù)據(jù)輸出到.INI或注冊表中。 3. RegisterDialogClasses函數(shù)登記屏幕保護程序配置對話框的窗口類。如果不使用特殊的窗口或控件,可以簡單地返回TRUE。 另外,編寫屏幕保護程序還有一些原則。 為使控制面板能夠識別,屏幕保護程序的擴展名必須改為.SCR并存放在WINDOWS目錄下。 屏幕保護程序的圖標(ICON)在資源文件中必須定義為ID_APP。ID_APP由系統(tǒng)的SCRNSAVE.H.定義。 資源文件中必須包含一描述字符串。該字符串用于控制面板顯示屏幕保護程序的名字。 它必須位于字符串表的首位。SCRNSAVE.H.定義其ID為1。 資源文件中屏幕保護程序配置對話框的ID必須為DLG_SCRNSAVECONFIGURE。它由系統(tǒng)的 SCRNSAVE.H.定義。 二.編程實例 1.最小的屏幕保護程序MiniSaver。這是一個僅包含最基本模塊的屏幕保護程序, 運行時在屏幕上顯示一行活動的文字。步驟如下: 第一步,在VC5.0/6.0中建立32位應(yīng)用工程(不選MFC WIZARD EXE).建立如下的 MiniSaver.CPP文件: #include < windows.h > #include < scrnsave.h >// SCRNSAVE.LIB的頭文件 #include "resource.h" file://聲明三個基本的函數(shù) LRESULT WINAPI ScreenSaveProc (HWND,UINT,WPARAM,LPARAM); BOOL WINAPI ScreenSaveConfigureDialog (HWND,UINT,WPARAM,LPARAM); BOOL WINAPI RegisterDialogClasses(HINSTANCE); file://定義三個基本的函數(shù) LRESULT WINAPI ScreenSaverProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {HDC hDC; RECT rc; static int xpos;//文本的橫坐標 static char SlideText[]="歡迎使用屏幕保護程序!"; static UINT timerID;//定時器 switch (message) { case WM_CREATE: xpos=0; timerID=SetTimer(hWnd,1,250,NULL);//設(shè)置定時器 break; case WM_ERASEBKGND: file://空操作,交由DefScreenSaverProc處理 break; case WM_TIMER: hDC=GetDC(hWnd); file://清屏 SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)) FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH)); file://輸出文本 SetTextColor(hDC,RGB(255*rand(), 255*rand(),255*rand())); SetBkColor(hDC,RGB(0,0,0)); TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)/2, SlideText,strlen(SlideText)); file://移動文本的橫坐標 xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN); ReleaseDC(hWnd,hDC); break; case WM_DESTROY: KillTimer(hWnd,timerID);//刪除定時器 PostQuitMessage (0); return 0; } return DefScreenSaverProc (hWnd,message,wParam,lParam); } BOOL WINAPI ScreenSaverConfigureDialog (HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam) {//暫時不需要配置對話框,僅返回FALSE return FALSE; } BOOL WINAPI RegisterDialogClasses (HINSTANCE hInstance) {//一般不需要,僅返回TRUE return TRUE; } 第二步,定義資源文件MiniSaver.rc。在VC環(huán)境下生成一圖標,其ID為ID_APP。向字符串表加入ID為IDS_DESCRIPTION字符串“MiniSaver”,并作為字符串表第一項 第三步,編譯連接并將生成的MiniSaver.EXE更名為MiniSaver.SCR拷入WINDOWS目錄。注意, 編譯前一定要在Project菜單的Setting中的Link選項中加上SCRNSAVE.LIB庫。 第四步,控制面板的顯示器設(shè)置中選擇屏幕保護程序MiniSaver就可以使用了。注意不要急于配置屏幕保護程序,因為MiniSaver還有沒提供配置對話框。 2.較完整的屏幕保護程序MySaver。該屏幕保護程序提供了配置對話框和關(guān)于對話框,并且使用了圖象顯示。讀者可以將自己喜愛的圖象加到資源中。 第一步,在VC5.0/6.0中建立32位應(yīng)用工程(不選MFC WIZARD EXE)并定義資源文件MiniSaver.rc。 在VC環(huán)境下生成一圖標,其ID為ID_APP。 向字符串表加入ID為IDS_DESCRIPTION字符串“MiniSaver”,并作為字符串表第一項。加入ID為idsAPPName字符串“Screen Saver.MySaver”,說明見后面程序。 加入ID為IDB_BITMAP1的位圖 加入ID為DLG_ABOUT對話框。僅有一ID為IDOK的按鈕 加入ID為ID_APP。此對話的ID由SCRNSAVE.H定義且只能為DLG_SCRNSAVECONFIGURE。其中有ID為IDC_EDIT的EDIT控件,ID為IDOK,IDCANCEL和IDABOUT的按鈕。 值得注意的是RESOURCE.H定義的ID_APP和DLG_SCRNSAVECONFIGURE可能與SCRNSAVE.H預定義的值沖突,可手動地將RESOURCE.H中的ID_APP設(shè)為100,DLG_SCRNSAVECONFIGURE設(shè)為2003即可。 第二步,建立如下的MySaver.CPP文件: #include < windows.h > #include < scrnsave.h > #include "resource.h" file://聲明三個基本的函數(shù) LRESULT WINAPI ScreenSaveProc (HWND,UINT,WPARAM,LPARAM); BOOL WINAPI ScreenSaveConfigureDialog (HWND,UINT,WPARAM,LPARAM); BOOL WINAPI RegisterDialogClasses(HINSTANCE); BOOL WINAPI AboutDialog(HWND,UINT,WPARAM,LPARAM); file://定義全局變量 char szIniFileName[]="control.ini"; file://屏幕保護程序配置數(shù)據(jù)存放在control.ini文件 char szSection[32]; file://屏幕保護程序配置數(shù)據(jù)在control.ini文件位置區(qū)名稱 char szEntry[]="Slide Text:"; file://屏幕保護程序配置數(shù)據(jù)項名稱 char SlideText[256]; file://屏幕保護程序配置數(shù)據(jù),這里是文本內(nèi)容 file://定義三個基本的函數(shù) LRESULT WINAPI ScreenSaverProc (HWND hWnd,UINT message, WPARAM wParam, LPARAM lParam) { static HBITMAP hBmp;//位圖句柄 HDC hDC,hMemDC;//hMemDC是內(nèi)存設(shè)備,緩存位圖。 RECT rc; static int xpos=0; static UINT timerID; switch (message) { case WM_CREATE: file://文件位置區(qū)名稱szSection賦值為資源 idsAPPName。其中hMainInstance為//SCRNSAVE.LIB 定義的屏幕保護程序?qū)嵗浔?/p> LoadString(hMainInstance,idsAPPName, szSection,sizeof(szSection)); strcpy(SlideText,"歡迎使用屏幕保護程序!"); file://讀control.ini文件中[Screen Saver.MySaver] 區(qū)的配置數(shù)據(jù)到SlideText GetPrivateProfileString(szSection,szEntry, SlideText,SlideText, sizeof(SlideText),szIniFileName); file://取位圖 hBmp=LoadBitmap(hMainInstance, MAKEINTRESOURCE(IDB_BITMAP1)); timerID=SetTimer(hWnd,1,250,NULL); break; case WM_ERASEBKGND: hDC=GetDC(hWnd); file://顯示位圖 hMemDC=CreateCompatibleDC(hDC); SelectObject(hMemDC,hBmp); SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)-25); BitBlt(hDC,rc.top,rc.left,rc.right,rc.bottom, hMemDC,rc.top,rc.left,SRCCOPY); file://清除底行,為文本顯示作準備。 SetRect(&rc,0,GetSystemMetrics(SM_CYSCREEN)-25 GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH)); ReleaseDC(hWnd,hDC); DeleteDC(hMemDC); return 1; case WM_TIMER: hDC=GetDC(hWnd); file://清除底行 SetRect(&rc,0,GetSystemMetrics(SM_CYSCREEN)-25, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH)); file://輸出文本 SetTextColor(hDC,RGB(255*rand(), 255*rand(),255*rand())); SetBkColor(hDC,RGB(0,0,0)); TextOut(hDC,xpos,GetSystemMetrics(SM_CYSCREEN)-25, SlideText,strlen(SlideText)); xpos=(xpos+10)%GetSystemMetrics(SM_CXSCREEN); ReleaseDC(hWnd,hDC); break; case WM_DESTROY: DeleteObject(hBmp); KillTimer(hWnd,timerID); PostQuitMessage (0); return 0; } return DefScreenSaverProc (hWnd,message,wParam,lParam); } BOOL WINAPI ScreenSaverConfigureDialog (HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: LoadString(hMainInstance,idsAPPName, szSection,sizeof(szSection)); strcpy(SlideText,"歡迎使用屏幕保護程序!"); GetPrivateProfileString(szSection, szEntry,SlideText, SlideText,sizeof(SlideText),szIniFileName); SetDlgItemText(hWnd,IDC_EDIT,SlideText); SetFocus(GetDlgItem(hWnd,IDC_EDIT)); return FALSE; case WM_COMMAND: switch(wParam) { case IDOK: file://取EDIT控件文本數(shù)據(jù)并寫入control.ini文件 GetDlgItemText(hWnd,IDC_EDIT, SlideText,sizeof(SlideText)); WritePrivateProfileString(szSection, szEntry,SlideText,szIniFileName); EndDialog(hWnd,TRUE); return TRUE; case IDCANCEL: EndDialog(hWnd,FALSE); return TRUE; case IDABOUT: file://調(diào)用ABOUT對話框 DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_ABOUT), hWnd,(FARPROC)AboutDialog); return TRUE; } break; } return FALSE; } BOOL WINAPI RegisterDialogClasses (HINSTANCE hInstance) { return TRUE; } BOOL WINAPI AboutDialog (HWND hWnd,UINT message,WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(wParam) { case IDOK: EndDialog(hWnd,TRUE); return TRUE; } break; } return FALSE; } 最后,編譯連接并將生成的MiniSaver.EXE更名為MiniSaver.SCR拷入WINDOWS目錄。此時可以使用配置對話框了。 |
|
|