當(dāng)前位置:
首頁(yè) >
用VC++6.0 编写一个完整的
發(fā)布時(shí)間:2025/3/15
26
豆豆
生活随笔
收集整理的這篇文章主要介紹了
用VC++6.0 编写一个完整的
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
屏幕保護(hù)程序是一個(gè)Win32應(yīng)用程序,與一般的Win32應(yīng)用程序不同之處在于:1、擴(kuò)展名要求為 SCR ;2、命令行要有一定的格式,以便操作系統(tǒng)向其傳遞信息,如 運(yùn)行模式,父窗口句柄(Handle to Parent Window)等 ;3、其他一些消息相應(yīng)方面的要求。本文將首先介紹屏幕保護(hù)程序的命令行格式及實(shí)現(xiàn)的方法,然后介紹各個(gè)相應(yīng)函數(shù),并通過(guò)Window主函數(shù)WinMin()勾畫出屏幕保護(hù)程序的主框架,最后介紹編譯步驟和注意事項(xiàng)
屏幕保護(hù)程序的命令行格式 :文件名 / [運(yùn)行模式] /[窗口句柄]。
其中運(yùn)行模式有五種選擇:
1.??? “運(yùn)行模式”= ‘c’ 或 ‘C ’, 句柄為一串?dāng)?shù)字, 或文件名后沒有任何參數(shù)。
屏保程序設(shè)置方式,Window 顯示屬性_屏幕保護(hù)程序_設(shè)置按鈕調(diào)用,數(shù)字為調(diào)用函數(shù)的窗口句柄(Handle to Parent Window)(十進(jìn)制),如果沒有數(shù)字,句柄為NULL。
2.??? “運(yùn)行模式”=‘t’或‘T’。
測(cè)試方式,忽略句柄數(shù)字。 3.??? “運(yùn)行模式”=‘p’或‘P’。
預(yù)覽方式,Window 顯示屬性_屏幕保護(hù)程序_預(yù)覽按鈕調(diào)用,句柄為調(diào)用函數(shù)的窗口句柄。 4.??? “運(yùn)行模式”=‘a(chǎn)’或‘A’。
密碼設(shè)置方式, Window 顯示屬性_屏幕保護(hù)程序_密碼保護(hù)_更改按鈕調(diào)用。句柄為調(diào)用函數(shù)的Window 句柄。 5.??? 其它(通常“運(yùn)行模式”=‘s’)
屏幕保護(hù)程序正常運(yùn)行模式。 因此,編寫屏幕保護(hù)程序的首要任務(wù)是過(guò)濾命令行,提取對(duì)應(yīng)的系統(tǒng)調(diào)用方式和其他信息,本文用自定義函數(shù)ParseCommandline( )實(shí)現(xiàn): //用enum定義五種調(diào)用方式: enum SaverMode { ??????????????????????????????????? sm_config, ??????????????????????????????????? sm_preview, ??????????????????????????????????? sm_full, ??????????????????????????????????? sm_test, ??????????????????????????????????? sm_passwordchange }; ? //命令行過(guò)濾函數(shù),命令行獲得函數(shù)是用API ?GetCommandLine( )。 SaverMode ParseCommandLine( TCHAR* pstrCommandLine ) { ????? g_hWndParent = NULL; //全局變量(global varibale) 在頭函數(shù)或主文件開始處定義。 ????? // 跳過(guò)長(zhǎng)文件名中的路徑和空格。 ????? if (*pstrCommandLine == TEXT('/"')) ?????? { ???????? pstrCommandLine++; ???????? while (*pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT('/"')) ??????????? pstrCommandLine++; ???????? If( *pstrCommandLine == TEXT('/"') ) ??????????? pstrCommandLine++; ?????? } ????? else ????? { ? ??????while (*pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT(' ')) ??????????? pstrCommandLine++; ???????? if( *pstrCommandLine == TEXT(' ') ) ??????????? pstrCommandLine++; ????? } ??? // 跳過(guò)"/" 或 "-" ??? while ( *pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT('/') && *pstrCommandLine != TEXT('-') ) ??????? pstrCommandLine++; ??? // 如果沒有任何參數(shù),為設(shè)置模式。 ??? if ( *pstrCommandLine == TEXT('/0') ) ??????? return sm_config; ??? // 如果有參數(shù),查看參數(shù)內(nèi)容。 ??? switch ( *(++pstrCommandLine) ) ???? { ??????? case 'c': ??????? case 'C': ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ??????????????? pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ??????????? { #ifdef _WIN64? //考慮64位編譯情況。 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb( strCommandLine, pstrCommandLine, sizeof(strCommandLine)); //該函數(shù)僅在64位編譯情況下使用。 ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); //數(shù)字串變?yōu)?/span>/Window句柄 #endif ??????????? } ??????????? else ??????????? { ??????????????? g_hWndParent = NULL; ??????????? } ??????????? return sm_config; ??????? case 't': ??????? case 'T': ??????????? return sm_test; ??????? case 'p': ??????? case 'P': ??????????? //預(yù)覽模式,后面有Window句柄,為十進(jìn)制數(shù)字 ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ???? ???????????pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ????????????? { #ifdef _WIN64 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine, sizeof(strCommandLine)); ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); #endif ????????????? } ???????????? return sm_preview; ??????? case 'a': ??????? case 'A': ??????????? //密碼設(shè)置模式,后面有Window句柄,為十進(jìn)制數(shù)字 ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ??????????????? pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ??????????? { #ifdef _WIN64 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine, sizeof(strCommandLine)); ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); #endif ??????????? } ??????????? return sm_passwordchange; ??????? default: ??????????? //其他選項(xiàng),屏保實(shí)際運(yùn)行模式(通常/s) ??????????? return sm_full; ??? } } /// ParseCommandLine( ) 返回后,程序根據(jù)不同的返回值進(jìn)行響應(yīng): 返回值=sm_preview或者sm_test 或者sm_full: 程序根據(jù)返回的運(yùn)行模式和Window句柄使用CreateWindow函數(shù)創(chuàng)建窗口(Window)并返回指向該窗口的句柄。這部分功能包含在自定義的CreateSaverWindow()函數(shù)中。在sm_preview情況下,程序用消息循環(huán)的方式等待500ms使操作系統(tǒng)的控制面板有足夠的時(shí)間初始化。然后,讀注冊(cè)表檢查屏保是否設(shè)定了密碼,如果是,在Win9x情況下,用LoadLibrary()和GetProcessAdress()函數(shù)從動(dòng)態(tài)鏈接庫(kù)(DLL)中獲得密碼驗(yàn)證函數(shù)指針供程序退出時(shí)使用,密碼驗(yàn)證函數(shù)類型為BOOL? PASCAL? (HWND)。這部分功能包含在自定義函數(shù)InitSaver()中。 以上窗口創(chuàng)建使用同一個(gè)窗口類(Window Class(WNDCLASS)),當(dāng)然也是同一個(gè)消息響應(yīng)函數(shù)(Window’s Procedure)。最后顯示窗口,開始消息循環(huán)。 返回值=sm_passwordchange: 用LoadLibrary()和 GetProcessAdress()API獲得密碼設(shè)置函數(shù)指針,密碼設(shè)置函數(shù)類型為:DOWORD? PASCAL? ( LPCSTR, HWND, DWORD, LPVOID ),然后調(diào)用該函數(shù)進(jìn)行密碼更改。 返回值=sm_config 顯示一個(gè)對(duì)話框(Dialog),獲取用戶信息,在程序中進(jìn)行相應(yīng)的更改。 屏幕保護(hù)程序的退出機(jī)制反映在程序的消息響應(yīng)函數(shù)(Window’s Procedure)中,當(dāng)按下鍵盤上任何一個(gè)健或者鼠標(biāo)移動(dòng)計(jì)數(shù)超過(guò)5次(防止桌面振動(dòng)等因素導(dǎo)致的鼠標(biāo)移動(dòng)),程序進(jìn)入退出機(jī)制,在sm_test或者sm--_full情況下查看屏幕保護(hù)程序是否設(shè)置密碼,如果是,驗(yàn)證密碼,正確,程序退出,錯(cuò)誤,程序繼續(xù)。當(dāng)程序驗(yàn)證密碼時(shí),通過(guò)全局變量g_bCheckingSaverPassword告訴消息響應(yīng)函數(shù)對(duì)屏幕刷新,以保證密碼的輸入。其他情況(sm_config, sm_preview)不用驗(yàn)證密碼直接退出。這些功能包括在自定義的函數(shù)InterruptSaver( )和ShutdownSaver( )中。 上述各個(gè)函數(shù)的詳細(xì)代碼如下: 1、?CreateSaverWindow 函數(shù): HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance) { ??? HWND hWnd; ??? RECT rc; ??? DWORD dwStyle; ?????????????????????????? hWnd=NULL; ?????????????????????????? ??? switch ( mode ) ??? { ??????? case sm_preview: ??????????? GetClientRect(hWndParent, &rc ); ??????????? dwStyle = WS_VISIBLE | WS_CHILD; ??????????? AdjustWindowRect( &rc, dwStyle, FALSE ); ??????????? hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, ??????????????????????????????????? rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, ??????????????????????????????????? hWndParent, NULL, hInstance, NULL); ??????????? break; ?????? ?case sm_test: ??????????? rc.left = rc.top = 50; ??????????? rc.right = rc.left+600; ??????????? rc.bottom = rc.top+400; ??????????? dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; ??????????? AdjustWindowRect( &rc, dwStyle, FALSE ); ??????????? hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, ?????????????????????????????????? rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, ?????????????????????????????????? NULL, NULL, hInstance, NULL); ?? ?????????break; ??????? case sm_full: ??????????? ??????????? rc.left=rc.top=0; ???????????????????????????????????? rc.bottom=GetSystemMetrics(SM_CYSCREEN); ???????????????????????????????????? rc.right=GetSystemMetrics(SM_CXSCREEN); ???????????????????????????????????? dwStyle = WS_VISIBLE | WS_POPUP; ??????????? hWnd = CreateWindowEx( WS_EX_TOPMOST, TEXT("SaverWndClass"), ??????????????????? TEXT("SaverWindow"), dwStyle, rc.left, rc.top, rc.right - rc.left, ??????????????????? rc.bottom - rc.top, NULL, NULL, hInstance, NULL); ??????????????? ??? } ?????????????????????????? ??? if(mode == sm_preview ) ??? { ??????? // 開始預(yù)覽時(shí),進(jìn)入一個(gè)短暫的循環(huán)以使系統(tǒng)顯示控制面板有足夠的時(shí)間初始化 ??????? g_bWaitForInputIdle = TRUE; ??????? // 開始循環(huán) ??????? PostMessage( g_hWnd, WM_USER, 0, 0 ); ??????? MSG msg; ??????? while( g_bWaitForInputIdle ) ??????? { ??????????? // 如果If 返回 FALSE, 結(jié)束循環(huán) ??????????? if( !GetMessage( &msg, g_hWnd, 0, 0 ) ) ??????????? { ??????????????? // 結(jié)束循環(huán) ??????????????? PostQuitMessage(0); ??????????????? break; ??????????? } ??????????? TranslateMessage( &msg); ??????????? DispatchMessage( &msg); ??????? } ??? } ??? ??? return hWnd; } 2、?Window消息響應(yīng)函數(shù): LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { ??? switch ( uMsg ) ??????? { ??????? case WM_USER: ??????????? //預(yù)覽開始循環(huán),500ms空閑時(shí)間用于控制面板的初始化。 ??????????? SetTimer( hWnd, 1, 500, NULL ); ??????????? break; ??????? case WM_TIMER: ??????????? // 500ms時(shí)間到,預(yù)覽循環(huán)結(jié)束。 ??????????? g_bWaitForInputIdle = FALSE; ??????????? KillTimer( hWnd, 1 ); ??????????? break; ??????? case WM_DESTROY: ??????????? ShutdownSaver(); ??????????? break; ??????? case WM_SETCURSOR: ??? ????????if ( g_SaverMode == sm_full && !g_bCheckingSaverPassword ) ??????????? { ??????????????? //隱藏鼠標(biāo)指針 ??????????????? SetCursor( NULL ); ??????????????? return TRUE; ??????????? } ??????????? break; ??????? case WM_PAINT: ??????? { ??????????? ????? ??????PAINTSTRUCT ps; ??????????? BeginPaint( hWnd, &ps ); ??????????????? RECT rc; ??????????????? GetClientRect(hWnd,&rc); ??????????????? FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH) ); //黑屏 ??????????? EndPaint( hWnd, &ps ); ??????? ????return 0; ??????? } ??????? case WM_ERASEBKGND: ??????????? // 輸入密碼時(shí)對(duì)屏幕刷新 ???????????? if( !g_bCheckingSaverPassword ) ??????????????? return TRUE;?? ?????????? ??????????? break; ??????? case WM_MOUSEMOVE: ??????????? if( g_SaverMode != sm_test ) ??????????? { ??????????????? static INT xPrev = -1; ??????????????? static INT yPrev = -1; ??????????????? INT xCur = GET_X_LPARAM(lParam); ??????????????? INT yCur = GET_Y_LPARAM(lParam); ??????????????? if( xCur != xPrev || yCur != yPrev ) ???????????? ???{ ??????????????????? xPrev = xCur; ??????????????????? yPrev = yCur; ??????????????????? g_dwSaverMouseMoveCount++; ??????????????????? if ( g_dwSaverMouseMoveCount > 5 ) ??????????????????????? InterruptSaver(); ??????????????? } ??????????? } ?????? ?????break; ??????? case WM_KEYDOWN: ??????? case WM_LBUTTONDOWN: ??????? case WM_RBUTTONDOWN: ??????? case WM_MBUTTONDOWN: ??????????? if( g_SaverMode != sm_test ) ??????????????? InterruptSaver(); ??????????? break; ??????? case WM_ACTIVATEAPP: ?????? ?????if( wParam == FALSE && g_SaverMode != sm_test ) ??????????????? InterruptSaver(); ??????????? break; ??????? case WM_POWERBROADCAST: ??????????? if( wParam == PBT_APMSUSPEND && g_VerifySaverPassword == NULL ) ??????????????? InterruptSaver(); ?????? ?????break; ??????? case WM_SYSCOMMAND: ??????????? if ( g_SaverMode == sm_full ) ??????????? { ??????????????? switch ( wParam ) ??????????????? { ??????????????????? case SC_NEXTWINDOW: ??????????????????? case SC_PREVWINDOW: ??????????????????? case SC_SCREENSAVE: ??????????????????? case SC_CLOSE: ??????????????????????? return FALSE; ??????????????? }; ??????????? } ??????????? break; ??? } ??? return DefWindowProc( hWnd, uMsg, wParam, lParam ); } 3、?ChangePassword()函數(shù) VOID ChangePassword() { ??? // 載入密碼更改函數(shù)動(dòng)態(tài)鏈接庫(kù)(Dynamic Linked Library) ??? HINSTANCE mpr = LoadLibrary( TEXT("MPR.DLL") ); ??? if ( mpr != NULL ) ??? { ??????? // 從動(dòng)態(tài)鏈接數(shù)據(jù)庫(kù)中提取密碼設(shè)置函數(shù) ??????? typedef DWORD (PASCAL *PWCHGPROC)( LPCSTR, HWND, DWORD, LPVOID ); ??????? PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, "PwdChangePasswordA" ); ??????? //運(yùn)行密碼設(shè)置函數(shù) ??????? if ( pwd != NULL ) ??????????? pwd( "SCRSAVE", g_hWndParent, 0, NULL ); ??????? //釋放動(dòng)態(tài)鏈接庫(kù) ??????? FreeLibrary( mpr ); ??? } } 4、?InitSaver()函數(shù) ??? VOID InitSaver() { //檢查操作系統(tǒng)版本 ??? OSVERSIONINFO osvi; ??????? osvi.dwOSVersionInfoSize = sizeof(osvi); ??????? GetVersionEx( &osvi ); ??????? g_bIs9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); ?????? // 在運(yùn)行模式下,如果操作系統(tǒng)是win9x,需要載入密碼驗(yàn)證動(dòng)態(tài)鏈接庫(kù)。 ???? ?if ( g_SaverMode == sm_full && g_bIs9x ) ?????? { ??????? // 檢查注冊(cè)表查看屏保是否設(shè)定了密碼 ??????? HKEY hKey; ??????? if ( RegCreateKeyEx( HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, 0, NULL, 0, KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS ) ?????????? { ???????? ???DWORD dwVal; ??????????? DWORD dwSize = sizeof(dwVal); ??????????? if ( (RegQueryValueEx( hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL, ?????????????????????????????????? (BYTE *)&dwVal, &dwSize ) == ERROR_SUCCESS) && dwVal ) ??????????? { ?????? ?????????g_hPasswordDLL = LoadLibrary( TEXT("PASSWORD.CPL") ); ??????????????? if ( g_hPasswordDLL ) ???????????????? g_VerifySaverPassword= (VERIFYPWDPROC)GetProcAddress( g_hPasswordDLL, "VerifyScreenSavePwd" ); ??????????????? RegCloseKey( hKey ); ????? ??????} ???????? } ????? } ?? ????? if ( g_SaverMode == sm_full ) ?????? { ???????? BOOL bUnused; ???????? SystemParametersInfo( SPI_SCREENSAVERRUNNING, TRUE, &bUnused, 0 ); //通知操作系統(tǒng)屏幕保護(hù)程序開始運(yùn)行。 ?????? } } 5、屏保退出函數(shù)ShutdownSaver( )和InteruptSaver( ): VOID ShutdownSaver() { ??? // 通知操作系統(tǒng)屏幕保護(hù)程序退出 ??? if ( g_SaverMode == sm_full ) ???? { ??????? BOOL bUnused; ??????? SystemParametersInfo( SPI_SCREENSAVERRUNNING, FALSE, &bUnused, 0 ); ???? } ??? ??? if ( g_hPasswordDLL != NULL ) ???? { ??????? FreeLibrary( g_hPasswordDLL ); ??????? g_hPasswordDLL = NULL; ???? } ?? ???? PostQuitMessage( 0 ); } / VOID InterruptSaver() { ??? BOOL bPasswordOkay = FALSE; ??? if( g_SaverMode == sm_test || ??????? g_SaverMode == sm_full&&!g_bCheckingSaverPassword ) ??? { ??????? if( g_bIs9x && g_SaverMode == sm_full ) ??????? { ??????????? // Win9x下如果g_VerifySaverPassword==NULL,則沒有設(shè)屏保密碼。 ??????????? if ( g_VerifySaverPassword != NULL ) ??????????? { ??????????????? ????????????????????? g_bCheckingSaverPassword = TRUE;//告訴消息響應(yīng)函數(shù)正在驗(yàn)證密碼 ??????????????? bPasswordOkay = g_VerifySaverPassword( g_hWnd ); ???????????????????????????????????????????????????? g_bCheckingSaverPassword = FALSE; //密碼驗(yàn)證結(jié)束。 ??????????????? if ( !bPasswordOkay ) ??????????????? { ?????????????????? //屏保程序繼續(xù)運(yùn)行… ??????????????????? SetCursor( NULL ); ??????????????????? g_dwSaverMouseMoveCount = 0; ??????????????????? return; ??????????????? } ??????????? } ??????? } ??????? ShutdownSaver(); ??? } } 屏保設(shè)置方式下的響應(yīng)程序?yàn)樽远xDoconfig( ),因篇幅的關(guān)系不再詳細(xì)介紹,讀者應(yīng)當(dāng)很容易自己加上,也可以定義為空函數(shù):VOID Doconfig ( ) { return;}。 黑屏屏幕保護(hù)程序主入口函數(shù)如下: #include <windows.h> #include <windowsx.h> #include <tchar.h> #include <stdio.h> #include <stdlib.h> #include <regstr.h> #include "Saver.h" #include "resource.h" HINSTANCE g_hinstance; HWND g_hWndParent; BOOL? g_bWaitForInputIdle; HWND g_hWnd; LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); int APIENTRY WinMain(HINSTANCE hInstance, ???????????????????? HINSTANCE hPrevInstance, ???????????????????? LPSTR???? lpCmdLine, ???????????????????? int?????? nCmdShow) { ????????????????????????? // TODO: Place code here. ??? ?????????????????????????? MSG msg; ?????????????????????????? g_bCheckingSaverPassword = FALSE; ??????????????? g_bIs9x = FALSE; ??????????????? g_dwSaverMouseMoveCount = 0; ??????????????? g_hWndParent = NULL; ??????????????? g_hPasswordDLL = NULL; ??????????????? g_hWnd = NULL; ??????????????? g_VerifySaverPassword = NULL; ??????????????? g_hinstance=hInstance; ??? ?????????????????????????? WNDCLASS??? cls; ??????????????? cls.hCursor = LoadCursor( NULL, IDC_ARROW ); ??????????????? cls.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ); ??????????????? cls.lpszMenuName = NULL; ??????????????? cls.lpszClassName = TEXT("SaverWndClass"); ??????????????? cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); ??????????????? cls.hInstance = hInstance; ??????????????? cls.style = CS_VREDRAW|CS_HREDRAW; ??????????????? cls.lpfnWndProc = SaverProc; ???????????? ???cls.cbWndExtra = 0; ??????????????? cls.cbClsExtra = 0; ???????????? if(!RegisterClass( &cls )) ??????????????????????????????????? MessageBox(NULL,TEXT("Cant register window class"),TEXT("SaverWndClass"),MB_ICONERROR); ??? ?????????????????????????? SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_IDLE ); ??????????????? TCHAR* pstrCmdLine = GetCommandLine(); g_SaverMode = ParseCommandLine(pstrCmdLine); ?????????????????????????? switch(g_SaverMode) ?????????????????????????? { ?????? ?????????????????????????? case sm_preview: ?????????????????????????? case sm_full: ?????????????????????????? case sm_test: ?????????????????????????? ??? g_hWnd=CreateSaverWindow(g_SaverMode,g_hWndParent,hInstance); ?????????????????????????? ?????????????????????????? ??? if ( g_hWnd == NULL ) ?????????????????????????? ?? ???????? { ?????????????????????????????????????????????????????? MessageBox(NULL,TEXT("Can't Create Window"), TEXT("Create Window Terminated"),MB_ICONERROR); ?????????????????????????? ???????? return 0; ??????????????????????????????????? ??? }else ?????????????????????????? ??????????????????????????????????? ??? { ??????????????????????????????????? ????? ShowWindow(g_hWnd,nCmdShow); ??????????????????????????????????? ????? UpdateWindow(g_hWnd); ?????????????????????????? ?? ???????? } ?????????????????????????? ???????????????????? InitSaver(); ??? ?????????????????????????? ???? while(GetMessage(&msg,NULL,0,0)) ?????????????????????????? ?????? { ??????????????????????????????????? ??????? TranslateMessage(&msg); ??????????????????????????????????? ??????? DispatchMessage(&msg); ?????????????????????????? ??????? } ?????????????????????????? ?????? break; case sm_config: ? Doconfig(); ??????????????????????????????????? ?? break; ?????????????????????????? case sm_passwordchange: ??????????????????????????????????? ?? ChangePassword(); ?????????????????????????? ?? break; ??????????? } ?????????????????????????? ?????????????????????????? return 0; } 至此,黑屏屏幕保護(hù)程序代碼編寫完成,下一步是輸入VC++6.0 并進(jìn)行編譯,具體步驟如下: 1、?打開VC++ 6.0, 從文件菜單中選擇 New, 選中工程(Project)窗口,從窗口中選中Win32 Application項(xiàng),在右側(cè)的Locatioon(工程文件保存位置)填入位置信息(如填D/ScreenSaver),在其上邊的Project name(工程名)欄中填入適當(dāng)?shù)拿Q(如Saver),按OK按鈕,這時(shí)出現(xiàn)新的窗口,有三個(gè)選項(xiàng),選擇 A Simple Apllication, 按Finish(完成)健,接下來(lái)出現(xiàn)確認(rèn)窗口,按OK,完成初步Win32 Application工程的創(chuàng)建。 2、?在ClassView窗口的Globles項(xiàng)下找到WinMain函數(shù),雙擊鼠標(biāo)打開C++文件(本文為Saver.cpp),按照前面的各條程序輸入相應(yīng)內(nèi)容。 3、?選擇FileView窗口選項(xiàng),從主窗口文件菜單中選擇New,選擇File(文件),從文件類型中選擇C/C++ Header File,輸入文件名(最好與工程名同名,如Saver),確認(rèn)后,新的頭文件出現(xiàn)在FileView窗口Header Files項(xiàng)下(本文文件名為Saver.h)。 雙擊新創(chuàng)建的頭文件(Saver.h),在頭文件中輸入以上函數(shù)和全局變量的說(shuō)明(Declaration):
enum SaverMode { ??????? sm_config, ??????? sm_preview, ??????? sm_full, ??????? sm_test, ??????? sm_passwordchange }; typedef BOOL (PASCAL * VERIFYPWDPROC) (HWND); DWORD?????????? g_dwSaverMouseMoveCount; BOOL??????????? g_bIs9x; HINSTANCE?????? g_hPasswordDLL; VERIFYPWDPROC?? g_VerifySaverPassword; BOOL??????????? g_bCheckingSaverPassword; SaverMode?????? g_SaverMode; SaverMode ParseCommandLine( TCHAR* pstrCommandLine ); HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance); VOID InitSaver(); VOID ChangePassword(); VOID Doconfig( ); 4、?確保在C++主文件中包含頭文件,即在主文件(Saver.cpp)中,包含#include <Saver.h>語(yǔ)句。 5、?在插入(Insert)菜單中選擇資源(Resource),在隨后出現(xiàn)的菜單中選擇資源類型為圖標(biāo)(Icon),按新建按鈕,這時(shí),空白圖標(biāo)出現(xiàn)在右邊窗口,對(duì)其進(jìn)行編輯后,用鼠標(biāo)選定該圖標(biāo),從查看菜單中打開屬性窗口(Properties),將該圖標(biāo)的ID 改為IDI_MAIN_ICON,按保存按鈕,這時(shí)出現(xiàn)窗口,要求選擇Resource Script文件名,填入適當(dāng)?shù)奈募?#xff08;本文填Saver),按OK健,這時(shí),工程目錄中應(yīng)當(dāng)出現(xiàn)以rc為擴(kuò)展名的文件。選擇FileView窗口,選擇Resource Files項(xiàng),按鼠標(biāo)右健,選擇Add Files to Folder…項(xiàng),將Resource.h和新建立的Saver.rc文件加入Resource項(xiàng)下。這時(shí),出現(xiàn)ResourceView窗口選項(xiàng),從該窗口中可以查看本工程的資源(Resource)情況。 6、?在工程菜單中,選擇設(shè)置(Settings…), 在Setting for欄目中分別選擇Win32 Release和Win32 Debug項(xiàng),在右邊的Link窗口中,將Output File Name中的文件名從exe擴(kuò)展名改為scr擴(kuò)展名。 這時(shí),完成編譯環(huán)境的設(shè)置和輸入工作,從編譯菜單中選Build,如果沒有輸入錯(cuò)誤,即可順利編譯成功。
測(cè)試方式,忽略句柄數(shù)字。 3.??? “運(yùn)行模式”=‘p’或‘P’。
預(yù)覽方式,Window 顯示屬性_屏幕保護(hù)程序_預(yù)覽按鈕調(diào)用,句柄為調(diào)用函數(shù)的窗口句柄。 4.??? “運(yùn)行模式”=‘a(chǎn)’或‘A’。
密碼設(shè)置方式, Window 顯示屬性_屏幕保護(hù)程序_密碼保護(hù)_更改按鈕調(diào)用。句柄為調(diào)用函數(shù)的Window 句柄。 5.??? 其它(通常“運(yùn)行模式”=‘s’)
屏幕保護(hù)程序正常運(yùn)行模式。 因此,編寫屏幕保護(hù)程序的首要任務(wù)是過(guò)濾命令行,提取對(duì)應(yīng)的系統(tǒng)調(diào)用方式和其他信息,本文用自定義函數(shù)ParseCommandline( )實(shí)現(xiàn): //用enum定義五種調(diào)用方式: enum SaverMode { ??????????????????????????????????? sm_config, ??????????????????????????????????? sm_preview, ??????????????????????????????????? sm_full, ??????????????????????????????????? sm_test, ??????????????????????????????????? sm_passwordchange }; ? //命令行過(guò)濾函數(shù),命令行獲得函數(shù)是用API ?GetCommandLine( )。 SaverMode ParseCommandLine( TCHAR* pstrCommandLine ) { ????? g_hWndParent = NULL; //全局變量(global varibale) 在頭函數(shù)或主文件開始處定義。 ????? // 跳過(guò)長(zhǎng)文件名中的路徑和空格。 ????? if (*pstrCommandLine == TEXT('/"')) ?????? { ???????? pstrCommandLine++; ???????? while (*pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT('/"')) ??????????? pstrCommandLine++; ???????? If( *pstrCommandLine == TEXT('/"') ) ??????????? pstrCommandLine++; ?????? } ????? else ????? { ? ??????while (*pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT(' ')) ??????????? pstrCommandLine++; ???????? if( *pstrCommandLine == TEXT(' ') ) ??????????? pstrCommandLine++; ????? } ??? // 跳過(guò)"/" 或 "-" ??? while ( *pstrCommandLine != TEXT('/0') && *pstrCommandLine != TEXT('/') && *pstrCommandLine != TEXT('-') ) ??????? pstrCommandLine++; ??? // 如果沒有任何參數(shù),為設(shè)置模式。 ??? if ( *pstrCommandLine == TEXT('/0') ) ??????? return sm_config; ??? // 如果有參數(shù),查看參數(shù)內(nèi)容。 ??? switch ( *(++pstrCommandLine) ) ???? { ??????? case 'c': ??????? case 'C': ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ??????????????? pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ??????????? { #ifdef _WIN64? //考慮64位編譯情況。 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb( strCommandLine, pstrCommandLine, sizeof(strCommandLine)); //該函數(shù)僅在64位編譯情況下使用。 ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); //數(shù)字串變?yōu)?/span>/Window句柄 #endif ??????????? } ??????????? else ??????????? { ??????????????? g_hWndParent = NULL; ??????????? } ??????????? return sm_config; ??????? case 't': ??????? case 'T': ??????????? return sm_test; ??????? case 'p': ??????? case 'P': ??????????? //預(yù)覽模式,后面有Window句柄,為十進(jìn)制數(shù)字 ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ???? ???????????pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ????????????? { #ifdef _WIN64 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine, sizeof(strCommandLine)); ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); #endif ????????????? } ???????????? return sm_preview; ??????? case 'a': ??????? case 'A': ??????????? //密碼設(shè)置模式,后面有Window句柄,為十進(jìn)制數(shù)字 ??????????? pstrCommandLine++; ??????????? while ( *pstrCommandLine && !isdigit(*pstrCommandLine) ) ??????????????? pstrCommandLine++; ??????????? if ( isdigit(*pstrCommandLine) ) ??????????? { #ifdef _WIN64 ??????????????? CHAR strCommandLine[2048]; ??????????????? DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine, sizeof(strCommandLine)); ??????????????? g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else ??????????????? g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); #endif ??????????? } ??????????? return sm_passwordchange; ??????? default: ??????????? //其他選項(xiàng),屏保實(shí)際運(yùn)行模式(通常/s) ??????????? return sm_full; ??? } } /// ParseCommandLine( ) 返回后,程序根據(jù)不同的返回值進(jìn)行響應(yīng): 返回值=sm_preview或者sm_test 或者sm_full: 程序根據(jù)返回的運(yùn)行模式和Window句柄使用CreateWindow函數(shù)創(chuàng)建窗口(Window)并返回指向該窗口的句柄。這部分功能包含在自定義的CreateSaverWindow()函數(shù)中。在sm_preview情況下,程序用消息循環(huán)的方式等待500ms使操作系統(tǒng)的控制面板有足夠的時(shí)間初始化。然后,讀注冊(cè)表檢查屏保是否設(shè)定了密碼,如果是,在Win9x情況下,用LoadLibrary()和GetProcessAdress()函數(shù)從動(dòng)態(tài)鏈接庫(kù)(DLL)中獲得密碼驗(yàn)證函數(shù)指針供程序退出時(shí)使用,密碼驗(yàn)證函數(shù)類型為BOOL? PASCAL? (HWND)。這部分功能包含在自定義函數(shù)InitSaver()中。 以上窗口創(chuàng)建使用同一個(gè)窗口類(Window Class(WNDCLASS)),當(dāng)然也是同一個(gè)消息響應(yīng)函數(shù)(Window’s Procedure)。最后顯示窗口,開始消息循環(huán)。 返回值=sm_passwordchange: 用LoadLibrary()和 GetProcessAdress()API獲得密碼設(shè)置函數(shù)指針,密碼設(shè)置函數(shù)類型為:DOWORD? PASCAL? ( LPCSTR, HWND, DWORD, LPVOID ),然后調(diào)用該函數(shù)進(jìn)行密碼更改。 返回值=sm_config 顯示一個(gè)對(duì)話框(Dialog),獲取用戶信息,在程序中進(jìn)行相應(yīng)的更改。 屏幕保護(hù)程序的退出機(jī)制反映在程序的消息響應(yīng)函數(shù)(Window’s Procedure)中,當(dāng)按下鍵盤上任何一個(gè)健或者鼠標(biāo)移動(dòng)計(jì)數(shù)超過(guò)5次(防止桌面振動(dòng)等因素導(dǎo)致的鼠標(biāo)移動(dòng)),程序進(jìn)入退出機(jī)制,在sm_test或者sm--_full情況下查看屏幕保護(hù)程序是否設(shè)置密碼,如果是,驗(yàn)證密碼,正確,程序退出,錯(cuò)誤,程序繼續(xù)。當(dāng)程序驗(yàn)證密碼時(shí),通過(guò)全局變量g_bCheckingSaverPassword告訴消息響應(yīng)函數(shù)對(duì)屏幕刷新,以保證密碼的輸入。其他情況(sm_config, sm_preview)不用驗(yàn)證密碼直接退出。這些功能包括在自定義的函數(shù)InterruptSaver( )和ShutdownSaver( )中。 上述各個(gè)函數(shù)的詳細(xì)代碼如下: 1、?CreateSaverWindow 函數(shù): HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance) { ??? HWND hWnd; ??? RECT rc; ??? DWORD dwStyle; ?????????????????????????? hWnd=NULL; ?????????????????????????? ??? switch ( mode ) ??? { ??????? case sm_preview: ??????????? GetClientRect(hWndParent, &rc ); ??????????? dwStyle = WS_VISIBLE | WS_CHILD; ??????????? AdjustWindowRect( &rc, dwStyle, FALSE ); ??????????? hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, ??????????????????????????????????? rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, ??????????????????????????????????? hWndParent, NULL, hInstance, NULL); ??????????? break; ?????? ?case sm_test: ??????????? rc.left = rc.top = 50; ??????????? rc.right = rc.left+600; ??????????? rc.bottom = rc.top+400; ??????????? dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU; ??????????? AdjustWindowRect( &rc, dwStyle, FALSE ); ??????????? hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, ?????????????????????????????????? rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, ?????????????????????????????????? NULL, NULL, hInstance, NULL); ?? ?????????break; ??????? case sm_full: ??????????? ??????????? rc.left=rc.top=0; ???????????????????????????????????? rc.bottom=GetSystemMetrics(SM_CYSCREEN); ???????????????????????????????????? rc.right=GetSystemMetrics(SM_CXSCREEN); ???????????????????????????????????? dwStyle = WS_VISIBLE | WS_POPUP; ??????????? hWnd = CreateWindowEx( WS_EX_TOPMOST, TEXT("SaverWndClass"), ??????????????????? TEXT("SaverWindow"), dwStyle, rc.left, rc.top, rc.right - rc.left, ??????????????????? rc.bottom - rc.top, NULL, NULL, hInstance, NULL); ??????????????? ??? } ?????????????????????????? ??? if(mode == sm_preview ) ??? { ??????? // 開始預(yù)覽時(shí),進(jìn)入一個(gè)短暫的循環(huán)以使系統(tǒng)顯示控制面板有足夠的時(shí)間初始化 ??????? g_bWaitForInputIdle = TRUE; ??????? // 開始循環(huán) ??????? PostMessage( g_hWnd, WM_USER, 0, 0 ); ??????? MSG msg; ??????? while( g_bWaitForInputIdle ) ??????? { ??????????? // 如果If 返回 FALSE, 結(jié)束循環(huán) ??????????? if( !GetMessage( &msg, g_hWnd, 0, 0 ) ) ??????????? { ??????????????? // 結(jié)束循環(huán) ??????????????? PostQuitMessage(0); ??????????????? break; ??????????? } ??????????? TranslateMessage( &msg); ??????????? DispatchMessage( &msg); ??????? } ??? } ??? ??? return hWnd; } 2、?Window消息響應(yīng)函數(shù): LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { ??? switch ( uMsg ) ??????? { ??????? case WM_USER: ??????????? //預(yù)覽開始循環(huán),500ms空閑時(shí)間用于控制面板的初始化。 ??????????? SetTimer( hWnd, 1, 500, NULL ); ??????????? break; ??????? case WM_TIMER: ??????????? // 500ms時(shí)間到,預(yù)覽循環(huán)結(jié)束。 ??????????? g_bWaitForInputIdle = FALSE; ??????????? KillTimer( hWnd, 1 ); ??????????? break; ??????? case WM_DESTROY: ??????????? ShutdownSaver(); ??????????? break; ??????? case WM_SETCURSOR: ??? ????????if ( g_SaverMode == sm_full && !g_bCheckingSaverPassword ) ??????????? { ??????????????? //隱藏鼠標(biāo)指針 ??????????????? SetCursor( NULL ); ??????????????? return TRUE; ??????????? } ??????????? break; ??????? case WM_PAINT: ??????? { ??????????? ????? ??????PAINTSTRUCT ps; ??????????? BeginPaint( hWnd, &ps ); ??????????????? RECT rc; ??????????????? GetClientRect(hWnd,&rc); ??????????????? FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH) ); //黑屏 ??????????? EndPaint( hWnd, &ps ); ??????? ????return 0; ??????? } ??????? case WM_ERASEBKGND: ??????????? // 輸入密碼時(shí)對(duì)屏幕刷新 ???????????? if( !g_bCheckingSaverPassword ) ??????????????? return TRUE;?? ?????????? ??????????? break; ??????? case WM_MOUSEMOVE: ??????????? if( g_SaverMode != sm_test ) ??????????? { ??????????????? static INT xPrev = -1; ??????????????? static INT yPrev = -1; ??????????????? INT xCur = GET_X_LPARAM(lParam); ??????????????? INT yCur = GET_Y_LPARAM(lParam); ??????????????? if( xCur != xPrev || yCur != yPrev ) ???????????? ???{ ??????????????????? xPrev = xCur; ??????????????????? yPrev = yCur; ??????????????????? g_dwSaverMouseMoveCount++; ??????????????????? if ( g_dwSaverMouseMoveCount > 5 ) ??????????????????????? InterruptSaver(); ??????????????? } ??????????? } ?????? ?????break; ??????? case WM_KEYDOWN: ??????? case WM_LBUTTONDOWN: ??????? case WM_RBUTTONDOWN: ??????? case WM_MBUTTONDOWN: ??????????? if( g_SaverMode != sm_test ) ??????????????? InterruptSaver(); ??????????? break; ??????? case WM_ACTIVATEAPP: ?????? ?????if( wParam == FALSE && g_SaverMode != sm_test ) ??????????????? InterruptSaver(); ??????????? break; ??????? case WM_POWERBROADCAST: ??????????? if( wParam == PBT_APMSUSPEND && g_VerifySaverPassword == NULL ) ??????????????? InterruptSaver(); ?????? ?????break; ??????? case WM_SYSCOMMAND: ??????????? if ( g_SaverMode == sm_full ) ??????????? { ??????????????? switch ( wParam ) ??????????????? { ??????????????????? case SC_NEXTWINDOW: ??????????????????? case SC_PREVWINDOW: ??????????????????? case SC_SCREENSAVE: ??????????????????? case SC_CLOSE: ??????????????????????? return FALSE; ??????????????? }; ??????????? } ??????????? break; ??? } ??? return DefWindowProc( hWnd, uMsg, wParam, lParam ); } 3、?ChangePassword()函數(shù) VOID ChangePassword() { ??? // 載入密碼更改函數(shù)動(dòng)態(tài)鏈接庫(kù)(Dynamic Linked Library) ??? HINSTANCE mpr = LoadLibrary( TEXT("MPR.DLL") ); ??? if ( mpr != NULL ) ??? { ??????? // 從動(dòng)態(tài)鏈接數(shù)據(jù)庫(kù)中提取密碼設(shè)置函數(shù) ??????? typedef DWORD (PASCAL *PWCHGPROC)( LPCSTR, HWND, DWORD, LPVOID ); ??????? PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, "PwdChangePasswordA" ); ??????? //運(yùn)行密碼設(shè)置函數(shù) ??????? if ( pwd != NULL ) ??????????? pwd( "SCRSAVE", g_hWndParent, 0, NULL ); ??????? //釋放動(dòng)態(tài)鏈接庫(kù) ??????? FreeLibrary( mpr ); ??? } } 4、?InitSaver()函數(shù) ??? VOID InitSaver() { //檢查操作系統(tǒng)版本 ??? OSVERSIONINFO osvi; ??????? osvi.dwOSVersionInfoSize = sizeof(osvi); ??????? GetVersionEx( &osvi ); ??????? g_bIs9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); ?????? // 在運(yùn)行模式下,如果操作系統(tǒng)是win9x,需要載入密碼驗(yàn)證動(dòng)態(tài)鏈接庫(kù)。 ???? ?if ( g_SaverMode == sm_full && g_bIs9x ) ?????? { ??????? // 檢查注冊(cè)表查看屏保是否設(shè)定了密碼 ??????? HKEY hKey; ??????? if ( RegCreateKeyEx( HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, 0, NULL, 0, KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS ) ?????????? { ???????? ???DWORD dwVal; ??????????? DWORD dwSize = sizeof(dwVal); ??????????? if ( (RegQueryValueEx( hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL, ?????????????????????????????????? (BYTE *)&dwVal, &dwSize ) == ERROR_SUCCESS) && dwVal ) ??????????? { ?????? ?????????g_hPasswordDLL = LoadLibrary( TEXT("PASSWORD.CPL") ); ??????????????? if ( g_hPasswordDLL ) ???????????????? g_VerifySaverPassword= (VERIFYPWDPROC)GetProcAddress( g_hPasswordDLL, "VerifyScreenSavePwd" ); ??????????????? RegCloseKey( hKey ); ????? ??????} ???????? } ????? } ?? ????? if ( g_SaverMode == sm_full ) ?????? { ???????? BOOL bUnused; ???????? SystemParametersInfo( SPI_SCREENSAVERRUNNING, TRUE, &bUnused, 0 ); //通知操作系統(tǒng)屏幕保護(hù)程序開始運(yùn)行。 ?????? } } 5、屏保退出函數(shù)ShutdownSaver( )和InteruptSaver( ): VOID ShutdownSaver() { ??? // 通知操作系統(tǒng)屏幕保護(hù)程序退出 ??? if ( g_SaverMode == sm_full ) ???? { ??????? BOOL bUnused; ??????? SystemParametersInfo( SPI_SCREENSAVERRUNNING, FALSE, &bUnused, 0 ); ???? } ??? ??? if ( g_hPasswordDLL != NULL ) ???? { ??????? FreeLibrary( g_hPasswordDLL ); ??????? g_hPasswordDLL = NULL; ???? } ?? ???? PostQuitMessage( 0 ); } / VOID InterruptSaver() { ??? BOOL bPasswordOkay = FALSE; ??? if( g_SaverMode == sm_test || ??????? g_SaverMode == sm_full&&!g_bCheckingSaverPassword ) ??? { ??????? if( g_bIs9x && g_SaverMode == sm_full ) ??????? { ??????????? // Win9x下如果g_VerifySaverPassword==NULL,則沒有設(shè)屏保密碼。 ??????????? if ( g_VerifySaverPassword != NULL ) ??????????? { ??????????????? ????????????????????? g_bCheckingSaverPassword = TRUE;//告訴消息響應(yīng)函數(shù)正在驗(yàn)證密碼 ??????????????? bPasswordOkay = g_VerifySaverPassword( g_hWnd ); ???????????????????????????????????????????????????? g_bCheckingSaverPassword = FALSE; //密碼驗(yàn)證結(jié)束。 ??????????????? if ( !bPasswordOkay ) ??????????????? { ?????????????????? //屏保程序繼續(xù)運(yùn)行… ??????????????????? SetCursor( NULL ); ??????????????????? g_dwSaverMouseMoveCount = 0; ??????????????????? return; ??????????????? } ??????????? } ??????? } ??????? ShutdownSaver(); ??? } } 屏保設(shè)置方式下的響應(yīng)程序?yàn)樽远xDoconfig( ),因篇幅的關(guān)系不再詳細(xì)介紹,讀者應(yīng)當(dāng)很容易自己加上,也可以定義為空函數(shù):VOID Doconfig ( ) { return;}。 黑屏屏幕保護(hù)程序主入口函數(shù)如下: #include <windows.h> #include <windowsx.h> #include <tchar.h> #include <stdio.h> #include <stdlib.h> #include <regstr.h> #include "Saver.h" #include "resource.h" HINSTANCE g_hinstance; HWND g_hWndParent; BOOL? g_bWaitForInputIdle; HWND g_hWnd; LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); int APIENTRY WinMain(HINSTANCE hInstance, ???????????????????? HINSTANCE hPrevInstance, ???????????????????? LPSTR???? lpCmdLine, ???????????????????? int?????? nCmdShow) { ????????????????????????? // TODO: Place code here. ??? ?????????????????????????? MSG msg; ?????????????????????????? g_bCheckingSaverPassword = FALSE; ??????????????? g_bIs9x = FALSE; ??????????????? g_dwSaverMouseMoveCount = 0; ??????????????? g_hWndParent = NULL; ??????????????? g_hPasswordDLL = NULL; ??????????????? g_hWnd = NULL; ??????????????? g_VerifySaverPassword = NULL; ??????????????? g_hinstance=hInstance; ??? ?????????????????????????? WNDCLASS??? cls; ??????????????? cls.hCursor = LoadCursor( NULL, IDC_ARROW ); ??????????????? cls.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ); ??????????????? cls.lpszMenuName = NULL; ??????????????? cls.lpszClassName = TEXT("SaverWndClass"); ??????????????? cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); ??????????????? cls.hInstance = hInstance; ??????????????? cls.style = CS_VREDRAW|CS_HREDRAW; ??????????????? cls.lpfnWndProc = SaverProc; ???????????? ???cls.cbWndExtra = 0; ??????????????? cls.cbClsExtra = 0; ???????????? if(!RegisterClass( &cls )) ??????????????????????????????????? MessageBox(NULL,TEXT("Cant register window class"),TEXT("SaverWndClass"),MB_ICONERROR); ??? ?????????????????????????? SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_IDLE ); ??????????????? TCHAR* pstrCmdLine = GetCommandLine(); g_SaverMode = ParseCommandLine(pstrCmdLine); ?????????????????????????? switch(g_SaverMode) ?????????????????????????? { ?????? ?????????????????????????? case sm_preview: ?????????????????????????? case sm_full: ?????????????????????????? case sm_test: ?????????????????????????? ??? g_hWnd=CreateSaverWindow(g_SaverMode,g_hWndParent,hInstance); ?????????????????????????? ?????????????????????????? ??? if ( g_hWnd == NULL ) ?????????????????????????? ?? ???????? { ?????????????????????????????????????????????????????? MessageBox(NULL,TEXT("Can't Create Window"), TEXT("Create Window Terminated"),MB_ICONERROR); ?????????????????????????? ???????? return 0; ??????????????????????????????????? ??? }else ?????????????????????????? ??????????????????????????????????? ??? { ??????????????????????????????????? ????? ShowWindow(g_hWnd,nCmdShow); ??????????????????????????????????? ????? UpdateWindow(g_hWnd); ?????????????????????????? ?? ???????? } ?????????????????????????? ???????????????????? InitSaver(); ??? ?????????????????????????? ???? while(GetMessage(&msg,NULL,0,0)) ?????????????????????????? ?????? { ??????????????????????????????????? ??????? TranslateMessage(&msg); ??????????????????????????????????? ??????? DispatchMessage(&msg); ?????????????????????????? ??????? } ?????????????????????????? ?????? break; case sm_config: ? Doconfig(); ??????????????????????????????????? ?? break; ?????????????????????????? case sm_passwordchange: ??????????????????????????????????? ?? ChangePassword(); ?????????????????????????? ?? break; ??????????? } ?????????????????????????? ?????????????????????????? return 0; } 至此,黑屏屏幕保護(hù)程序代碼編寫完成,下一步是輸入VC++6.0 并進(jìn)行編譯,具體步驟如下: 1、?打開VC++ 6.0, 從文件菜單中選擇 New, 選中工程(Project)窗口,從窗口中選中Win32 Application項(xiàng),在右側(cè)的Locatioon(工程文件保存位置)填入位置信息(如填D/ScreenSaver),在其上邊的Project name(工程名)欄中填入適當(dāng)?shù)拿Q(如Saver),按OK按鈕,這時(shí)出現(xiàn)新的窗口,有三個(gè)選項(xiàng),選擇 A Simple Apllication, 按Finish(完成)健,接下來(lái)出現(xiàn)確認(rèn)窗口,按OK,完成初步Win32 Application工程的創(chuàng)建。 2、?在ClassView窗口的Globles項(xiàng)下找到WinMain函數(shù),雙擊鼠標(biāo)打開C++文件(本文為Saver.cpp),按照前面的各條程序輸入相應(yīng)內(nèi)容。 3、?選擇FileView窗口選項(xiàng),從主窗口文件菜單中選擇New,選擇File(文件),從文件類型中選擇C/C++ Header File,輸入文件名(最好與工程名同名,如Saver),確認(rèn)后,新的頭文件出現(xiàn)在FileView窗口Header Files項(xiàng)下(本文文件名為Saver.h)。 雙擊新創(chuàng)建的頭文件(Saver.h),在頭文件中輸入以上函數(shù)和全局變量的說(shuō)明(Declaration):
enum SaverMode { ??????? sm_config, ??????? sm_preview, ??????? sm_full, ??????? sm_test, ??????? sm_passwordchange }; typedef BOOL (PASCAL * VERIFYPWDPROC) (HWND); DWORD?????????? g_dwSaverMouseMoveCount; BOOL??????????? g_bIs9x; HINSTANCE?????? g_hPasswordDLL; VERIFYPWDPROC?? g_VerifySaverPassword; BOOL??????????? g_bCheckingSaverPassword; SaverMode?????? g_SaverMode; SaverMode ParseCommandLine( TCHAR* pstrCommandLine ); HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance); VOID InitSaver(); VOID ChangePassword(); VOID Doconfig( ); 4、?確保在C++主文件中包含頭文件,即在主文件(Saver.cpp)中,包含#include <Saver.h>語(yǔ)句。 5、?在插入(Insert)菜單中選擇資源(Resource),在隨后出現(xiàn)的菜單中選擇資源類型為圖標(biāo)(Icon),按新建按鈕,這時(shí),空白圖標(biāo)出現(xiàn)在右邊窗口,對(duì)其進(jìn)行編輯后,用鼠標(biāo)選定該圖標(biāo),從查看菜單中打開屬性窗口(Properties),將該圖標(biāo)的ID 改為IDI_MAIN_ICON,按保存按鈕,這時(shí)出現(xiàn)窗口,要求選擇Resource Script文件名,填入適當(dāng)?shù)奈募?#xff08;本文填Saver),按OK健,這時(shí),工程目錄中應(yīng)當(dāng)出現(xiàn)以rc為擴(kuò)展名的文件。選擇FileView窗口,選擇Resource Files項(xiàng),按鼠標(biāo)右健,選擇Add Files to Folder…項(xiàng),將Resource.h和新建立的Saver.rc文件加入Resource項(xiàng)下。這時(shí),出現(xiàn)ResourceView窗口選項(xiàng),從該窗口中可以查看本工程的資源(Resource)情況。 6、?在工程菜單中,選擇設(shè)置(Settings…), 在Setting for欄目中分別選擇Win32 Release和Win32 Debug項(xiàng),在右邊的Link窗口中,將Output File Name中的文件名從exe擴(kuò)展名改為scr擴(kuò)展名。 這時(shí),完成編譯環(huán)境的設(shè)置和輸入工作,從編譯菜單中選Build,如果沒有輸入錯(cuò)誤,即可順利編譯成功。
總結(jié)
以上是生活随笔為你收集整理的用VC++6.0 编写一个完整的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 最新研究前线-深度推荐系统真的有效吗?
- 下一篇: C++中建立对象间消息连接的系统方法