//用enum定义五种调用方式: enum SaverMode { sm_config, sm_preview, sm_full, sm_test, sm_passwordchange }; //命令行过滤函数,命令行获得函数是用API GetCommandLine( )。 SaverMode ParseCommandLine( TCHAR* pstrCommandLine ) { g_hWndParent = NULL; //全局变量(global varibale) 在头函数或主文件开始处定义。 // 跳过长文件名中的路径和空格。 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++; } // 跳过"/" 或 "-" while ( *pstrCommandLine != TEXT('\0') && *pstrCommandLine != TEXT('/') && *pstrCommandLine != TEXT('-') ) pstrCommandLine++; // 如果没有任何参数,为设置模式。 if ( *pstrCommandLine == TEXT('\0') ) return sm_config; // 如果有参数,查看参数内容。 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)); //该函数仅在64位编译情况下使用。 g_hWndParent = (HWND)(_atoi64(strCommandLine)); #else g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); //数字串变为 /Window句柄 #endif } else { g_hWndParent = NULL; } return sm_config; case 't': case 'T': return sm_test; case 'p': case 'P': //预览模式,后面有Window句柄,为十进制数字 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': //密码设置模式,后面有Window句柄,为十进制数字 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: //其他选项,屏保实际运行模式(通常/s) return sm_full; } } /////////////////////// |
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; } |
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 ); } |
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 ); } } |
4、 InitSaver()函数
VOID InitSaver() { //检查操作系统版本 OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx( &osvi ); g_bIs9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); // 在运行模式下,如果操作系统是win9x,需要载入密码验证动态链接库。 if ( g_SaverMode == sm_full && g_bIs9x ) { // 检查注册表查看屏保是否设定了密码 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 ); //通知操作系统屏幕保护程序开始运行。 } } |
VOID ShutdownSaver() { // 通知操作系统屏幕保护程序退出 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,则没有设屏保密码。 if ( g_VerifySaverPassword != NULL ) { g_bCheckingSaverPassword = TRUE;//告诉消息响应函数正在验证密码 bPasswordOkay = g_VerifySaverPassword( g_hWnd ); g_bCheckingSaverPassword = FALSE; //密码验证结束。 if ( !bPasswordOkay ) { //屏保程序继续运行… SetCursor( NULL ); g_dwSaverMouseMoveCount = 0; return; } } } ShutdownSaver(); } } |
#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; } |
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( ); |
欢迎访问最专业的网吧论坛,无盘论坛,网吧经营,网咖管理,网吧专业论坛
https://bbs.txwb.com
关注天下网吧微信/下载天下网吧APP/天下网吧小程序,一起来超精彩
|
本文来源:vczx 作者:佚名