深入淺出屏幕保護程序編程

 深入淺出屏幕保護程序編程  作者:董曉 發佈時間:2001/03/28
 
 
 
文章摘要:
  現在V程序畫面越來越精美,功能越來越強大,可以提供圖象,動畫,音頻,視頻等所有的多媒體功能。儘管我們可以很容易獲得漂亮的屏幕保護程序,但自己製作屏幕保護程序對用戶也許更有吸引力,下文便對如何製作屏幕保護程序做了詳細介紹。 
        

--------------------------------------------------------------------------------
 
正文:   


深入淺出屏幕保護程序編程   


  讀者對屏幕保護程序已經相當熟悉了。去年泰坦尼克號的屏幕保護程序風行了全世界,足見其魅力。有的屏幕保護程序功能十分強大,可以提供圖象,動畫,音頻,視頻等所有的多媒體功能。儘管可以很容易獲得漂亮的屏幕保護程序,但擁有自己的屏幕保護程序對用戶也許更有吸引力。
  VC5.0/6.0是開發屏幕保護程序的好工具。靜態鏈接庫SCRNSAVE.LIB對屏幕保護程序提供了支持。SCRNSAVE.LIB包含了建立屏幕保護程序的主程序和缺省功能,用戶可以方便地使用SDK進行編程並與之連接。儘管SDK編程相對MFC麻煩,但編寫相對簡單的屏幕保護程序卻相當容易甚至比用MFC編程更簡單。
  也可以使用MFC編寫屏幕保護程序。但遺憾的是MFC不支持SCRNSAVE.LIB,必須手工完成原來由SCRNSAVE.LIB提供的功能,比較麻煩和不好理解。不過,編寫複雜的屏幕保護程序時,MFC對於顯示模塊和對話框處理可以提供比SDK方便得多的功能。爲簡單起見先介紹如何使用SDK編寫屏幕保護程序。


一. 屏幕保護程序和SCRNSAVE.LIB

  先從開發者的角度對屏幕保護程序說明如下:
  首先,屏幕保護程序是Win32 API 支持一種特殊的應用程序並由系統自動激活。其機制是當條件滿足時,系統向當前活動窗口發出字參數 wParam 值爲SC_SCREENSAVE 的WM_SYSCOMMAND消息,然後由當前活動窗口執行SYSTEM.INI文件中[boot]區指定的屏幕保護程序。

  屏幕保護程序激活的條件是
  1. 在規定時間內沒有鼠標或鍵盤輸入.
  2. 當前的活動窗口是標準的WINDOWS應用程序。因爲非WINDOWS應用,不會理睬WM_SYSCOMMAND消息。
  3. 顯然,如果當前活動的程序接管了字參數 wParam 值爲SC_SCREENSAVE 的WM_SYSCOMMAND 消息並且不傳遞到 DefWindowProc函數就可以禁止屏幕保護程序。這對某些運行中不願意被打斷的程序如視頻播放,光盤刻錄程序特別有用。

  其次,可以在控制面板的顯示器中選擇需要的屏幕保護程序,並可以配置屏幕保護程序的參數。屏幕保護程序應該提供配置屏幕保護程序的對話框。

  再次,屏幕保護程序有特別的輸出函數,資源定義和變量聲明。SCRNSAVE.LIB包含了建立屏幕保護程序的主程序。屏幕保護程序啓動時SCRNSAVE.LIB自動創建一全屏窗口,並描述窗口類爲無光標的滿黑屏。
  用戶編寫的屏幕保護程序必須包含三個基本函數ScreenSaverProc,ScreenSaverConfigureDialog 和RegisterDialogClasses 並與SCRNSAVE.LIB連接。
  1.ScreenSaverProc 窗口函數處理特定的消息並把未處理的消息傳遞給SCRNSAVE.LIB 。ScreenSaverProc 一般處理以下消息:
  WM_CREATE 讀取.INI或註冊表的初始化數據,設置定時器以及其他初始化操作。
  WM_ERASEBKGND 擦除背景爲下一步繪圖作準備。
  WM_TIMER 進行繪圖輸出。用戶可以實現自己的動畫功能以及其他操作。
  WM_DESTROY 刪除定時器以及其他對象
  ScreenSaverProc 把未處理的消息傳遞到SCRNSAVE.LIB中的 DefScreenSaverProc函數 處理。由它完成許多複雜和關鍵的操作比如何時激活,何時關閉等,大大方便了屏幕保護程序的編寫。
  2.ScreenSaverConfigureDialog函數處理屏幕保護程序配置對話框。該對話框由控制面板的顯示器設置程序調用。用戶輸入的配置數據輸出到.INI或註冊表中。
  3. RegisterDialogClasses函數登記屏幕保護程序配置對話框的窗口類。如果不使用特殊的窗口或控件,可以簡單地返回TRUE。

  另外,編寫屏幕保護程序還有一些原則。
  1. 爲使控制面板能夠識別,屏幕保護程序的擴展名必須改爲.SCR並存放在WINDOWS目錄下。
  2. 屏幕保護程序的圖標(ICON)在資源文件中必須定義爲ID_APP。ID_APP由系統的SCRNSAVE.H.定義。
  3. 資源文件中必須包含一描述字符串。該字符串用於控制面板顯示屏幕保護程序的名字。它必須位於字符串表的首位。SCRNSAVE.H.定義其ID爲1。
  4. 資源文件中屏幕保護程序配置對話框的ID必須爲DLG_SCRNSAVECONFIGURE。它由系統的SCRNSAVE.H.定義。


二.編程實例

  1.最小的屏幕保護程序MiniSaver。這是一個僅包含最基本模塊的屏幕保護程序,運行時在屏幕上顯示一行活動的文字。步驟如下:
  第一步,在VC5.0/6.0中建立32位應用工程(不選MFC WIZARD EXE).建立如下的MiniSaver.CPP文件:
#include
#include
// SCRNSAVE.LIB的頭文件
#include "resource.h"
//聲明三個基本的函數
LRESULT WINAPI ScreenSaveProc
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI ScreenSaveConfigureDialog
(HWND,UINT,WPARAM,LPARAM);
BOOL WINAPI RegisterDialogClasses(HINSTANCE);
//定義三個基本的函數
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);//設置定時器
break;

case WM_ERASEBKGND:
//空操作,交由DefScreenSaverProc處理
break;
case WM_TIMER:
hDC=GetDC(hWnd);
//清屏
SetRect(&rc,0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN))
FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH));
//輸出文本
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));
//移動文本的橫座標
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環境下生成一圖標,其ID爲ID_APP。向字符串表加入ID爲IDS_DESCRIPTION字符串"MiniSaver",並作爲字符串表第一項
  第三步,編譯連接並將生成的MiniSaver.EXE更名爲MiniSaver.SCR拷入WINDOWS目錄。注意, 編譯前一定要在Project菜單的Setting中的Link選項中加上SCRNSAVE.LIB庫。
  第四步,控制面板的顯示器設置中選擇屏幕保護程序MiniSaver就可以使用了。注意不要急於配置屏幕保護程序,因爲MiniSaver還有沒提供配置對話框。

  2.較完整的屏幕保護程序MySaver。該屏幕保護程序提供了配置對話框和關於對話框,並且使用了圖象顯示。讀者可以將自己喜愛的圖象加到資源中。
  第一步,在VC5.0/6.0中建立32位應用工程(不選MFC WIZARD EXE)並定義資源文件MiniSaver.rc。
    在VC環境下生成一圖標,其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設爲100,DLG_SCRNSAVECONFIGURE設爲2003即可。
  第二步,建立如下的MySaver.CPP文件:
#include #include

#include "resource.h"
//聲明三個基本的函數
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);
//定義全局變量
char szIniFileName[]="control.ini";
//屏幕保護程序配置數據存放在control.ini文件
char szSection[32];
//屏幕保護程序配置數據在control.ini文件位置區名稱
char szEntry[]="Slide Text:";
//屏幕保護程序配置數據項名稱
char SlideText[256];
//屏幕保護程序配置數據,這裏是文本內容
//定義三個基本的函數
LRESULT WINAPI ScreenSaverProc
(HWND hWnd,UINT message, WPARAM wParam,
LPARAM lParam)
{ static HBITMAP hBmp;//位圖句柄
HDC hDC,hMemDC;//hMemDC是內存設備,緩存位圖。
RECT rc;
static int xpos=0;
static UINT timerID;
switch (message)
{
case WM_CREATE:
//文件位置區名稱szSection賦值爲資源
idsAPPName。其中hMainInstance爲//SCRNSAVE.LIB
定義的屏幕保護程序實例句柄
LoadString(hMainInstance,idsAPPName,
szSection,sizeof(szSection));
strcpy(SlideText,"歡迎使用屏幕保護程序!");
//讀control.ini文件中[Screen Saver.MySaver]
區的配置數據到SlideText
GetPrivateProfileString(szSection,szEntry,
SlideText,SlideText,
sizeof(SlideText),szIniFileName);
//取位圖
hBmp=LoadBitmap(hMainInstance,
MAKEINTRESOURCE(IDB_BITMAP1));
timerID=SetTimer(hWnd,1,250,NULL);
break;

case WM_ERASEBKGND:
hDC=GetDC(hWnd);
//顯示位圖
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);
//清除底行,爲文本顯示作準備。
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);
//清除底行
SetRect(&rc,0,GetSystemMetrics(SM_CYSCREEN)-25,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN));
FillRect(hDC,&rc,GetStockObject(BLACK_BRUSH));
//輸出文本
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:
//取EDIT控件文本數據並寫入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:
//調用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目錄。此時可以使用配置對話框了。

 

作者會員名:heliking

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章