【聚杰网VC】用Visual C++编写完整的屏幕保护程序
ParseCommandLine( ) 返回后,程序根据不同的返回值进行响应:
返回值=sm_preview或者sm_test 或者sm_full:
程序根据返回的运行模式和Window句柄使用CreateWindow函数创建窗口(Window)并返回指向该窗口的句柄。这部分功能包含在自定义的CreateSaverWindow()函数中。在sm_preview情况下,程序用消息循环的方式等待500ms使操作系统的控制面板有足够的时间初始化。然后,读注册表检查屏保是否设定了密码,如果是,在Win9x情况下,用LoadLibrary()和GetProcessAdress()函数从动态链接库(DLL)中获得密码验证函数指针供程序退出时使用,密码验证函数类型为BOOL PASCAL (HWND)。这部分功能包含在自定义函数InitSaver()中。
以上窗口创建使用同一个窗口类(Window Class(WNDCLASS)),当然也是同一个消息响应函数(Window’s Procedure)。最后显示窗口,开始消息循环。
返回值=sm_passwordchange:
用LoadLibrary()和 GetProcessAdress()API获得密码设置函数指针,密码设置函数类型为:DOWORD PASCAL ( LPCSTR, HWND, DWORD, LPVOID ),然后调用该函数进行密码更改。
返回值=sm_config
显示一个对话框(Dialog),获取用户信息,在程序中进行相应的更改。
屏幕保护程序的退出机制反映在程序的消息响应函数(Window’s Procedure)中,当按下键盘上任何一个健或者鼠标移动计数超过5次(防止桌面振动等因素导致的鼠标移动),程序进入退出机制,在sm_test或者sm--_full情况下查看屏幕保护程序是否设置密码,如果是,验证密码,正确,程序退出,错误,程序继续。当程序验证密码时,通过全局变量g_bCheckingSaverPassword告诉消息响应函数对屏幕刷新,以保证密码的输入。其他情况(sm_config, sm_preview)不用验证密码直接退出。这些功能包括在自定义的函数InterruptSaver( )和ShutdownSaver( )中。
上述各个函数的详细代码如下:
1、 CreateSaverWindow 函数:
| 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 ) { // 开始预览时,进入一个短暂的循环以使系统显示控制面板有足够的时间初始化 g_bWaitForInputIdle = TRUE; // 开始循环 PostMessage( g_hWnd, WM_USER, 0, 0 ); MSG msg; while( g_bWaitForInputIdle ) { // 如果If 返回 FALSE, 结束循环 if( !GetMessage( &msg, g_hWnd, 0, 0 ) ) { // 结束循环 PostQuitMessage(0); break; } TranslateMessage( &msg); DispatchMessage( &msg); } } return hWnd; } |
2、 Window消息响应函数:
| LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_USER: //预览开始循环,500ms空闲时间用于控制面板的初始化。 SetTimer( hWnd, 1, 500, NULL ); break; case WM_TIMER: // 500ms时间到,预览循环结束。 g_bWaitForInputIdle = FALSE; KillTimer( hWnd, 1 ); break; case WM_DESTROY: ShutdownSaver(); break; case WM_SETCURSOR: if ( g_SaverMode == sm_full && !g_bCheckingSaverPassword ) { //隐藏鼠标指针 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: // 输入密码时对屏幕刷新 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()函数
| VOID ChangePassword() { // 载入密码更改函数动态链接库(Dynamic Linked Library) HINSTANCE mpr = LoadLibrary( TEXT("MPR.DLL") ); if ( mpr != NULL ) { // 从动态链接数据库中提取密码设置函数 typedef DWORD (PASCAL *PWCHGPROC)( LPCSTR, HWND, DWORD, LPVOID ); PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, "PwdChangePasswordA" ); //运行密码设置函数 if ( pwd != NULL ) pwd( "SCRSAVE", g_hWndParent, 0, NULL ); //释放动态链接库 FreeLibrary( mpr ); } } |




