Thudo Posted September 10, 2010 Share Posted September 10, 2010 Mega thanks to forum user MELBA for drastically spring boarding this project. With this help, I'm almost at the finishing line. Just have some lingering issues to resolve. The script in question: expandcollapse popup#include <Crypt.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> #include <Misc.au3> #include <WinAPI.au3> #include <Timers.au3> TraySetState(2) ; Disable the tray icon ; Clear screensaver backup files when possible. Local $Userprofile = envget("USERPROFILE") Local $Usertemp = ($Userprofile&"\Local Settings\Temp\") FileDelete($Usertemp&"\~DF*.tmp") Global $sav, $sPath, $lticks, $GUI, $CGUI, $PGUI, $PIC, $bl_ScreenSaver = False, $w = @DesktopWidth, $h = @DesktopHeight Global $parent_PID = "", $hWnd = "" Global $bmp = False, $jpg = False, $gif = False Global $s_path, $n_disp ; Determine cfg paths Global $TempDir = ("") ; network path to cfg Global $TempDir2 = ("C:\DATA\") ; local path to cfg (used as backup) ; Ensure network path is always backed-up to local path. If FileExists($TempDir) Then FileCopy($TempDir, $TempDir2, 1) EndIf ; Choose alternate path if primary does not exist If FileExists($TempDir) Then $sav = $TempDir & '\ScreenSaver.cfg' Else $sav = $TempDir2 & '\ScreenSaver.cfg' EndIf $sPath = FileReadLine($sav, 1) #Region Check cfg If Not FileExists($sav) Then FileWrite($sav, "C:\DATA\SCREENSAVER\") ; where the images are stored FileWrite($sav, @CRLF & '15000') ; Time in ms between image transitions (standard is 15 seconds) FileWrite($sav, @CRLF & '.bmp|.jpg|.gif') ; Image formats supported FileWrite($sav, @CRLF & '420000') ; Time in ms between idle timeouts (standard is 7 minutes) FileWrite($sav, @CRLF & "0x098F6BCD4621D373CADE4E832627B4F6") ; 'test' default Hash password to unlock screensaver (in MD5 Encyption) FileWrite($sav, @CRLF & "0x6D662F965D1E85BB367EFAA03594C5A1") ; 'sdm' master unchanging Hash password to unlock screensaver for support teams (in MD5 Encyption) EndIf #EndRegion Check cfg ; Set Hotkey to invoke password HotKeySet("^!{l}", "_ScreenSaverHotKey") ; Ctrl+Alt+L #Region Pref Create $PGUI = GUICreate('Picture Screen Saver', 350, 150, -1, -1, BitOR(0x00040000, 0x00000080)) GUICtrlCreateGroup('Pictures folder', 5, 5, 335, 42) $p_pic = GUICtrlCreateEdit(FileReadLine($sav, 1), 10, 20, 270, 20, 2048 + 128) $hPGUI_Browse = GUICtrlCreateButton('Browse', 285, 20, 50, 20) GUICtrlCreateGroup('Display picture extension...', 5, 50, 155, 40) $bmp = GUICtrlCreateCheckbox('.bmp', 15, 65) $jpg = GUICtrlCreateCheckbox('.jpg', 70, 65) $gif = GUICtrlCreateCheckbox('.gif', 120, 65) GUICtrlCreateGroup('Display time', 170, 50, 80, 40) $tdisp = GUICtrlCreateEdit(FileReadLine($sav, 2), 180, 67, 60, 17, 8192 + 128) GUICtrlCreateGroup('Idle timeout', 260, 50, 80, 40) $tidle = GUICtrlCreateEdit(FileReadLine($sav, 4), 270, 67, 60, 17, 8192 + 128) $hPGUI_Apply = GUICtrlCreateButton('Apply', 140, 95, 80, 20) GUISetState(@SW_HIDE, $PGUI) #EndRegion Pref Create If Not FileExists($sav) Then ; Check for command line If Not $CmdLine[0] Then ConsoleWrite('!> $CmdLine[0]' & @CRLF) ; Exit if no CmdLine Exit ElseIf StringInStr($CmdLine[1], '/p') Then If $CmdLine[0] < 2 Then MsgBox(48, 'Picture scr', 'Invalid preview window information supplied.') Exit Else $parent_PID = _ProcessGetParent(@AutoItPID) $w = 152 $h = 112 $hWnd = HWnd($CmdLine[2]) EndIf ElseIf Not StringInStr($CmdLine[1], '/s') Then _PrefOpen() EndIf EndIf $s_path = FileReadLine($sav, 1) $n_disp = FileReadLine($sav, 2) $Poss_Ext = FileReadLine($sav, 3) $i_WaitIdleTime = FileReadLine($sav, 4) $check = FileFindFirstFile($s_path & '*.*') If $check = -1 Then ConsoleWrite('!> FileFindFirstFile' & Chr(13)) Exit EndIf While 1 $sNext = FileFindNextFile($check) If @error Then ; No valid files $sNext = "" ExitLoop EndIf If StringInStr($sNext, ".") Then $s_Ext = StringRegExpReplace($sNext, "^.*\.", ".$1") If StringRegExp($s_Ext, "(?i)" & $Poss_Ext) Then ExitLoop EndIf WEnd ; On first run, don't start screensaver immediately, wait for idle time to expire. ;~ If _Timer_GetIdleTime() > $i_WaitIdleTime Then ;_WinAPI_ShowCursor(0) _ScreenSaverPicture($w, $h, $hWnd) ;~ EndIf If ($s_Ext = '.bmp') And $bmp = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) ElseIf ($s_Ext = '.jpg') And $jpg = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) ElseIf ($s_Ext = '.gif') And $gif = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) EndIf $iBegin = TimerInit() Sleep(500) ; Allow settle time from start click While 1 Sleep(10) Switch $bl_ScreenSaver Case True ; Has user actioned something in the last 500 ms If _Timer_GetIdleTime() < 500 Then _TurnOnSplash() Switch _AskPassword() ; Password good Case 1 ; Stop screensaver $bl_ScreenSaver = False _TurnOffSplash() ; Cancel pressed Case 0 ; Restart screensaver ;_WinAPI_ShowCursor(0) _ScreenSaverPicture($w, $h, $hWnd) _TurnOffSplash() ; Password fail x 5 Case -1 ; Restart screensaver ;_WinAPI_ShowCursor(0) _ScreenSaverPicture($w, $h, $hWnd) _TurnOffSplash() EndSwitch EndIf Case False If _Timer_GetIdleTime() > $i_WaitIdleTime Then ;_WinAPI_ShowCursor(0) _ScreenSaverPicture($w, $h, $hWnd) _TurnOffSplash() EndIf EndSwitch If TimerDiff($iBegin) > $n_disp Then While 1 $sNext = FileFindNextFile($check) If @error Then ; No valid files FileClose($check) $check = FileFindFirstFile($s_path & '*.*') ; Go back to the first file $sNext = FileFindNextFile($check) EndIf If StringInStr($sNext, ".") Then $s_Ext = StringRegExpReplace($sNext, "^.*\.", ".$1") If StringRegExp($s_Ext, "(?i)" & $Poss_Ext) Then ExitLoop EndIf WEnd If $parent_PID <> "" Then $child_PID = _ProcessGetChildren($parent_PID) If $child_PID[0] > 1 Then Exit ;Another ss selected If Not WinExists($CmdLine[2]) Then Exit EndIf If ($s_Ext = '.bmp') And $bmp = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) ElseIf ($s_Ext = '.jpg') And $jpg = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) ElseIf ($s_Ext = '.gif') And $gif = True Then __SetPicture($CGUI, $PIC, $s_path & $sNext) EndIf $iBegin = TimerInit() EndIf WEnd #Region Pref Create Func _PrefOpen() GUICtrlSetData($p_pic, FileReadLine($sav, 1)) GUICtrlSetData($tdisp, FileReadLine($sav, 2)) $sExt = StringSplit(FileReadLine($sav, 3), '|') #Region Reset checkbox GUICtrlSetState($bmp, 4) GUICtrlSetState($jpg, 4) GUICtrlSetState($gif, 4) #EndRegion Reset checkbox For $i = 1 To UBound($sExt) - 1 If ($sExt[$i] = '.bmp') Then GUICtrlSetState($bmp, 1) ElseIf ($sExt[$i] = '.jpg') Then GUICtrlSetState($jpg, 1) ElseIf ($sExt[$i] = '.gif') Then GUICtrlSetState($gif, 1) EndIf Next GUISetState(@SW_SHOW, $PGUI) While 1 Switch GUIGetMsg() Case $hPGUI_Browse $path = FileSelectFolder('Select picture folder', @MyDocumentsDir, 1 + 2) If @error Then ConsoleWrite('!> FileSelectFolder' & @CRLF) Exit EndIf GUICtrlSetData($p_pic, $path & '\') Case $hPGUI_Apply FileDelete($sav) FileWrite($sav, GUICtrlRead($p_pic)) If (GUICtrlRead($tdisp) <> '') Then FileWrite($sav, @CRLF & GUICtrlRead($tdisp) & @CRLF) Else FileWrite($sav, @CRLF & '2000' & @CRLF) EndIf If (GUICtrlRead($tidle) <> '') Then FileWrite($sav, @CRLF & GUICtrlRead($tidle) & @CRLF) Else FileWrite($sav, @CRLF & '2000' & @CRLF) EndIf If (GUICtrlRead($bmp) = 1) Then FileWrite($sav, '.bmp|') If (GUICtrlRead($jpg) = 1) Then FileWrite($sav, '.jpg|') If (GUICtrlRead($gif) = 1) Then FileWrite($sav, '.gif|') GUISetState(@SW_HIDE, $PGUI) $bl_ScreenSaver = True EndSwitch WEnd EndFunc ;==>_PrefOpen #EndRegion Pref Create #Region ScreensaverPic ; _ScreenSaverPicture Func _ScreenSaverPicture($width, $height, $hWnd = 'Screen Saver') $bl_ScreenSaver = True Local $s_path = FileReadLine($sav, 1) Local $n_disp = FileReadLine($sav, 2) If ($hWnd = 'Screen Saver') Then Global $GUI = GUICreate('Screen Saver', @DesktopWidth, @DesktopHeight, 0, 0, 0x80000000) GUISetBkColor(0x000000, $GUI) GUISetState(@SW_SHOW, $GUI) WinSetOnTop($GUI, "", 1) EndIf Global $CGUI = GUICreate('Screen Saver', $width, $height, 0, 0, 0x80000000, 0x00000008, $hWnd) _WinAPI_SetParent($CGUI, $hWnd) $PIC = GUICtrlCreatePic('', 0, 0, $width, $height) GUISetBkColor(0x000000, $CGUI) GUISetState(@SW_SHOW, $CGUI) $sExt = StringSplit(FileReadLine($sav, 3), '|') For $i = 1 To UBound($sExt) - 1 If ($sExt[$i] = '.bmp') Then $bmp = True ElseIf ($sExt[$i] = '.jpg') Then $jpg = True ElseIf ($sExt[$i] = '.gif') Then $gif = True EndIf Next Sleep(500) EndFunc ;==>_ScreenSaverPicture ; Randomize image transitions Func __SetPicture($hGUI, $ID, $p_path) _WinAnimate($hGUI, Random(1, 10, 1), 2, 700) GUICtrlSetImage($ID, $p_path) _WinAnimate($hGUI, Random(1, 10, 1), 1, 700) EndFunc ;==>__SetPicture #EndRegion ScreensaverPic Func _ScreenSaverHotKey() _WinAPI_ShowCursor(1) _TurnOnSplash() _AskPassword() _TurnOffSplash() EndFunc #Region Password Func _AskPassword() ; Stop screensaver $bl_ScreenSaver = False GUIDelete($CGUI) GUIDelete($GUI) _WinAPI_ShowCursor(1) Local $bPasswordHash = (FileReadLine($sav, 5)) Local $bMasterPasswordHash = (FileReadLine($sav, 6)) Local $iXTimes = 5, $iCount = 0 Local $sPassword = "" $hPasswordGetter = GUICreate('Login', 330, 85, -1, -1, BitOR($WS_SYSMENU, $WS_CAPTION), $WS_EX_TOPMOST) GUIRegisterMsg($WM_NCLBUTTONDOWN, 'WM_NCLBUTTONDOWN') ; Prevent Login box from being moved $hPG_Label = GUICtrlCreateGroup('Enter Password ' & (FileReadLine($sav, 5)), 4, 10, 323, 40) $hPG_Input = GUICtrlCreateInput("", 10, 25, 310, 20, $ES_PASSWORD) GUICtrlSetState($hPG_Input, $GUI_FOCUS) $hPG_OK = GUICtrlCreateButton('OK', 100, 55, 50, 20) $hPG_Cancel = GUICtrlCreateButton('Cancel', 185, 55, 50, 20) GUISetState() While 1 Switch GUIGetMsg() Case $hPG_OK GUISetState(@SW_HIDE, $hPasswordGetter) $iCount += 1 If $iCount = $iXTimes Then ;BlockInput(1) ; Freeze user's mouse/keyboard -- likely will omit this but here for testing the lock down. MsgBox(16, "Failed Password Login attempt limit reached", "Please contact your local Support team for Assistance..") GUIDelete(GUISetState(@SW_HIDE, $hPasswordGetter)) Return -1 EndIf $sAttempt = GUICtrlRead($hPG_Input) If _Crypt_HashData($sAttempt, $CALG_MD5) = $bPasswordHash Or _Crypt_HashData($sAttempt, $CALG_MD5) = $bMasterPasswordHash Then Return 1 MsgBox(16, "Access Denied", "Password Incorrect!" & @CR & "You have " & $iXTimes - $iCount & " trys left") GUICtrlSetData($hPG_Input, "") GUICtrlSetState($hPG_Input, $GUI_FOCUS) GUISetState(@SW_SHOW, $hPasswordGetter) Case $hPG_Cancel GUIDelete(GUISetState(@SW_HIDE, $hPasswordGetter)) _MouseTrap() Return 0 EndSwitch WEnd EndFunc ;==>_AskPassword #EndRegion Password Func WM_NCLBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) Switch $wParam Case 0x02 Return 0 EndSwitch Return 'GUI_RUNDEFMSG' EndFunc ;==>WM_NCLBUTTONDOWN Func _TurnOnSplash() $findpic = ("") ; add custom background image if desired. SplashTextOn("", "", @DesktopWidth, @DesktopHeight, -1, -1, 3) EndFunc Func _TurnOffSplash() SplashOff() EndFunc #Region Process functions ; _ProcessGetParent Func _ProcessGetParent($i_pid) Local $TH32CS_SNAPPROCESS = 0x00000002 Local $a_tool_help = DllCall('Kernel32.dll', 'long', 'CreateToolhelp32Snapshot', 'int', $TH32CS_SNAPPROCESS, 'int', 0) If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, $i_pid) Local $tagPROCESSENTRY32 = _ DllStructCreate( _ 'dword dwsize;' & _ 'dword cntUsage;' & _ 'dword th32ProcessID;' & _ 'uint th32DefaultHeapID;' & _ 'dword th32ModuleID;' & _ 'dword cntThreads;' & _ 'dword th32ParentProcessID;' & _ 'long pcPriClassBase;' & _ 'dword dwFlags;' & _ 'char szExeFile[260]' _ ) DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32)) Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32) Local $a_pfirst = DllCall('Kernel32.dll', 'int', 'Process32First', 'long', $a_tool_help[0], 'ptr', $p_PROCESSENTRY32) If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, $i_pid) Local $a_pnext, $i_return = 0 If DllStructGetData($tagPROCESSENTRY32, 'th32ProcessID') = $i_pid Then $i_return = DllStructGetData($tagPROCESSENTRY32, 'th32ParentProcessID') DllCall('Kernel32.dll', 'int', 'CloseHandle', 'long', $a_tool_help[0]) If $i_return Then Return $i_return Return $i_pid EndIf While @error = 0 $a_pnext = DllCall('Kernel32.dll', 'int', 'Process32Next', 'long', $a_tool_help[0], 'ptr', $p_PROCESSENTRY32) If DllStructGetData($tagPROCESSENTRY32, 'th32ProcessID') = $i_pid Then $i_return = DllStructGetData($tagPROCESSENTRY32, 'th32ParentProcessID') If $i_return Then ExitLoop $i_return = $i_pid ExitLoop EndIf WEnd DllCall('Kernel32.dll', 'int', 'CloseHandle', 'long', $a_tool_help[0]) Return $i_return EndFunc ;==>_ProcessGetParent ; _ProcessGetChildren Func _ProcessGetChildren($i_pid) Local Const $TH32CS_SNAPPROCESS = 0x00000002 Local $a_tool_help = DllCall('Kernel32.dll', 'long', 'CreateToolhelp32Snapshot', 'int', $TH32CS_SNAPPROCESS, 'int', 0) If IsArray($a_tool_help) = 0 Or $a_tool_help[0] = -1 Then Return SetError(1, 0, $i_pid) Local $tagPROCESSENTRY32 = _ DllStructCreate _ ( _ 'dword dwsize;' & _ 'dword cntUsage;' & _ 'dword th32ProcessID;' & _ 'uint th32DefaultHeapID;' & _ 'dword th32ModuleID;' & _ 'dword cntThreads;' & _ 'dword th32ParentProcessID;' & _ 'long pcPriClassBase;' & _ 'dword dwFlags;' & _ 'char szExeFile[260]' _ ) DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32)) Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32) Local $a_pfirst = DllCall('Kernel32.dll', 'int', 'Process32First', 'long', $a_tool_help[0], 'ptr', $p_PROCESSENTRY32) If IsArray($a_pfirst) = 0 Then Return SetError(2, 0, $i_pid) Local $a_pnext, $a_children[11] = [10], $i_child_pid, $i_parent_pid, $i_add = 0 $i_child_pid = DllStructGetData($tagPROCESSENTRY32, 'th32ProcessID') If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, 'th32ParentProcessID') If $i_parent_pid = $i_pid Then $i_add += 1 $a_children[$i_add] = $i_child_pid EndIf EndIf While 1 $a_pnext = DllCall('Kernel32.dll', 'int', 'Process32Next', 'long', $a_tool_help[0], 'ptr', $p_PROCESSENTRY32) If IsArray($a_pnext) And $a_pnext[0] = 0 Then ExitLoop $i_child_pid = DllStructGetData($tagPROCESSENTRY32, 'th32ProcessID') If $i_child_pid <> $i_pid Then $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, 'th32ParentProcessID') If $i_parent_pid = $i_pid Then If $i_add = $a_children[0] Then ReDim $a_children[$a_children[0] + 10] $a_children[0] = $a_children[0] + 10 EndIf $i_add += 1 $a_children[$i_add] = $i_child_pid EndIf EndIf WEnd If $i_add <> 0 Then ReDim $a_children[$i_add + 1] $a_children[0] = $i_add EndIf DllCall('Kernel32.dll', 'int', 'CloseHandle', 'long', $a_tool_help[0]) If $i_add Then Return $a_children Return SetError(3, 0, 0) EndFunc ;==>_ProcessGetChildren #EndRegion Process functions #Region WinAnimate Func _WinAnimate($hGUI, $Style = 1, $Ani = 1, $n_speed = 250) Local $sIN = StringSplit('80000,40001,40002,40004,40008,40005,40006,40009,4000A,40010', ',') Local $sOUT = StringSplit('90000,50002,50001,50008,50004,5000A,50009,50006,50005,50010', ',') If $Ani = 1 Then DllCall('user32.dll', 'int', 'AnimateWindow', 'hwnd', $hGUI, 'int', $n_speed, 'long', '0x000' & $sIN[$Style]) ElseIf $Ani = 2 Then DllCall('user32.dll', 'int', 'AnimateWindow', 'hwnd', $hGUI, 'int', $n_speed, 'long', '0x000' & $sOUT[$Style]) EndIf EndFunc ;==>_WinAnimate #EndRegion WinAnimate Yep this is a screensaver and yes it won't ever be secure but its a project I need to complete for the environment I work in. MELBA helped clean up my code so now I'm 90% there now. With the above code in mind I am stuck with the following issues to fix. I looked around everywhere and found no resolution as of yet to these.. 1) How to create a HotKey that integrates more appropriately with the running code? Current I use: ; Set Hotkey to invoke password HotKeySet("^!{l}", "_ScreenSaverHotKey") ; Ctrl+Alt+L..but the problem is this is a static solution as you see it calls the function.. Func _ScreenSaverHotKey() _WinAPI_ShowCursor(1) _TurnOnSplash() _AskPassword() _TurnOffSplash() EndFuncbut this becomes a dead-end and doesn't work if you hit the CANCEL button in the Login Prompt (which should default back to the screensaver). How can I build in a better HotKey functionality here? 2) During the Login Box, hitting ESC, RETURN, or the Top-Right Red-X are disabled. I used to use InputBox and these were enabled. ESC and the Red-X should default back to the screensaver like clicking CANCEL. RETURN would be basically clicking OK. Anyway to enable these? 3) Quick Bonus question: Can _MouseTrap lock a mouse in a MsgBox? I've only see it work with a GUI. When the "Access Denied" message box comes up the _MouseTrap code is broken as its a MsgBox (just like InputBox too). So #1 and #2 are most important right now. If I can get those nailed down I'm good. Thanks so very much Autoit community.. guys have been a lifesaver! Link to comment Share on other sites More sharing options...
Thudo Posted September 10, 2010 Author Share Posted September 10, 2010 Ok figured out the ESC, ENTER, and Red-X issues.. Use the GUISetAccelerators() and now have this working well. $hPasswordGetter = GUICreate('Login', 330, 85, -1, -1, BitOR($WS_DLGFRAME, $WS_CAPTION, $WS_EX_TOPMOST)) GUIRegisterMsg($WM_NCLBUTTONDOWN, 'WM_NCLBUTTONDOWN') ; Prevent Login box from being moved $hPG_Label = GUICtrlCreateGroup('Enter Password ' & (FileReadLine($sav, 5)), 4, 10, 323, 40) $hPG_Input = GUICtrlCreateInput("", 10, 25, 310, 20, $ES_PASSWORD) GUICtrlSetState($hPG_Input, $GUI_FOCUS) $hPG_OK = GUICtrlCreateButton('OK', 100, 55, 50, 20) $hPG_Cancel = GUICtrlCreateButton('Cancel', 185, 55, 50, 20) Dim $GUIKeys[2][2]=[["{ENTER}", $hPG_OK], ["{ESC}", $hPG_Cancel]] GUISetAccelerators($GUIKeys)Note the changes in BitOR (which removes the top-right Red-X) and the addition of the Hotkeys using GUISetAccelerators. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now