#NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=FloatingClock.ico #AutoIt3Wrapper_Outfile=FloatingClock.scr #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Res_Fileversion=1.0.0.15 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;~ #include #include #include #include #include #include #Include #include #include #include _MySingleton('FloatingClock') Global $nTargetSpeed = 0.2, $nDriftSpeed = 100, $nDecay = 1.01, $iProxRadius = 100 Global $aTimeString[8], $iTextWidth, $iTextHeight Global Enum $tp_x, $tp_y, $tp_w, $tp_h, $tp_char, $tp_ub Global $aTimePieces[8][$tp_ub] Global Enum $tg_x, $tg_y, $tg_xVel, $tg_yVel, $tg_ub Global $aTargetFollow[$tg_ub], $aTargetRandom[2] Global $iCanvasWidth = @DesktopWidth, $iCanvasHeight = @DesktopHeight Global $aHSL[3] = [ 240, 240, 240 ] Global $sRegKey = 'HKCU\Software\therkSoft\FloatingClock' Global $iAntiAlias = RegRead($sRegKey, 'AntiAlias') If @error Then $iAntiAlias = 1 Global $iRefreshRate = RegRead($sRegKey, 'Refresh') If @error Then $iRefreshRate = 10 Global $iRainbowText = RegRead($sRegKey, 'Rainbow') If @error Then $iRainbowText = 1 Global $i24Hour = RegRead($sRegKey, '24Hour') If @error Then $i24Hour = 1 If @Compiled Then If $CmdLine[0] Then Switch StringLeft($CmdLine[1], 2) Case '/p' ;~ Not working :( ;~ If $CmdLine[0] > 1 Then ;~ _PreviewSaver($CmdLine[2]) ;~ ElseIf StringTrimLeft($CmdLine[0], 3) Then ;~ _PreviewSaver(StringTrimLeft($CmdLine[0], 3)) ;~ Else ;~ Exit ;~ EndIf Case '/s' _MainSaver() Case Else _Config() EndSwitch Else _Config() EndIf Else _Config() GUIDelete() Sleep(500) _MainSaver() EndIf Func _Config() GUICreate('Floating Clock Config', 170, 85, Default, Default, BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU)) GUICtrlCreateLabel('Refresh rate:', 5, 5, 60, 20, $SS_CENTERIMAGE) Local $in_Refresh = GUICtrlCreateInput($iRefreshRate, 70, 5, 30, 20, BitOR($GUI_SS_DEFAULT_INPUT, $ES_NUMBER)) Local $ch_AntiAlias = GUICtrlCreateCheckbox('Anti-alias text', 5, 25, 100, 20) If $iAntiAlias Then GUICtrlSetState(-1, $GUI_CHECKED) Local $ch_RainbowText = GUICtrlCreateCheckbox('Rainbow text', 5, 45, 100, 20) If $iRainbowText Then GUICtrlSetState(-1, $GUI_CHECKED) Local $ch_24Hour = GUICtrlCreateCheckbox('24 hour clock', 5, 65, 100, 20) If $i24Hour Then GUICtrlSetState(-1, $GUI_CHECKED) Local $bt_OK = GUICtrlCreateButton('OK', 105, 5, 60, 25) GUICtrlSetState(-1, $GUI_DEFBUTTON) Local $bt_Cancel = GUICtrlCreateButton('Cancel', 105, 35, 60, 25) GUISetState() While 1 Local $iGM = GUIGetMsg() Switch $iGM Case $bt_OK $iRefreshRate = Int(GUICtrlRead($in_Refresh)) If $iRefreshRate < 0 Then $iRefreshRate = 1 $iAntiAlias = 0 If BitAND(GUICtrlRead($ch_AntiAlias), $GUI_CHECKED) Then $iAntiAlias = 1 $iRainbowText = 0 If BitAND(GUICtrlRead($ch_RainbowText), $GUI_CHECKED) Then $iRainbowText = 1 $i24Hour = 0 If BitAND(GUICtrlRead($ch_24Hour), $GUI_CHECKED) Then $i24Hour = 1 RegWrite($sRegKey, 'Refresh', 'REG_DWORD', $iRefreshRate) RegWrite($sRegKey, 'AntiAlias', 'REG_DWORD', $iAntiAlias) RegWrite($sRegKey, 'Rainbow', 'REG_DWORD', $iRainbowText) RegWrite($sRegKey, '24Hour', 'REG_DWORD', $i24Hour) ExitLoop Case $bt_Cancel, $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd EndFunc Func _PreviewSaver($iHandle) Global $hWndCanvas = HWnd($iHandle) Local $aWinPos = WinGetPos($hWndCanvas) $iCanvasWidth = $aWinPos[2] $iCanvasHeight = $aWinPos[3] Local $WS_CHILD = 0x40000000 Local $hGUI = GUICreate('', Default, Default, Default, Default, $WS_CHILD, Default, $hWndCanvas) _WinAPI_SetParent($hGUI, $hWndCanvas) _Setup() AdlibRegister('_DrawingProcess', 10) While 1 Sleep(10) WEnd EndFunc Func _MainSaver() Global $hWndCanvas = GUICreate('', 1, 1, 0, 0, BitOR($WS_MAXIMIZE, $WS_POPUP), BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetCursor(16, 1) _Setup() GUISetState(@SW_SHOW) AdlibRegister('_DrawingProcess', $iRefreshRate) While 1 Sleep(10000) WEnd EndFunc Func _Setup() _GDIPlus_Startup() Global Const $hDC = _WinAPI_GetWindowDC($hWndCanvas) Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Global Const $hBitmap_backbuffer = _WinAPI_CreateCompatibleBitmap($hDC, $iCanvasWidth, $iCanvasHeight) Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hBitmap_backbuffer) Global Const $hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) ;~ If $iAntiAlias Then DllCall($ghGDIPDll, 'uint', 'GdipSetTextRenderingHint', 'handle', $hBackbuffer, 'int', 4) ; Anti-alias font? If $iAntiAlias Then _GDIPlus_GraphicsSetTextRenderingHint($hBackbuffer, 4) ; Anti-alias font? Global Const $hBrush_Clear = _GDIPlus_BrushCreateSolid(0xFF000000) Global Const $hBrush_Draw = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) Global Const $hPen_Draw = _GDIPlus_PenCreate(0xFFFFFFFF) Global Const $hFormat = _GDIPlus_StringFormatCreate(0x4004) _GDIPlus_StringFormatSetAlign($hFormat, 0) Global Const $hFamily = _GDIPlus_FontFamilyCreate('Arial') Global Const $hFont = _GDIPlus_FontCreate($hFamily, $iCanvasHeight / 8, 0) Global Const $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0) Global $hUser32 = DllOpen('user32.dll') Global $iLastActive = _LastActive($hUser32) OnAutoItExitRegister('_Exit') Local $colon = _GDIPlus_GraphicsMeasureString($hBackbuffer, ':', $hFont, $tLayout, $hFormat) $iTextHeight = DllStructGetData($colon[0], 'Height') $colon = DllStructGetData($colon[0], 'Width') Local $num = _GDIPlus_GraphicsMeasureString($hBackbuffer, '8', $hFont, $tLayout, $hFormat) $num = DllStructGetData($num[0], 'Width') $iTextWidth = ($colon * 2 + $num * 5) * 0.6 + $num $aTargetFollow[$tg_x] = Random(0, $iCanvasWidth - $iTextWidth, 1) $aTargetFollow[$tg_y] = Random(0, $iCanvasHeight - $iTextHeight, 1) $aTargetFollow[$tg_x] = ($iCanvasWidth - $iTextWidth) / 2 $aTargetFollow[$tg_y] = ($iCanvasHeight - $iTextHeight) / 2 For $i = 0 To 7 $aTimePieces[$i][$tp_x] = ($iCanvasWidth - $num) / 2 $aTimePieces[$i][$tp_y] = ($iCanvasHeight - $iTextHeight) / 2 Next _TargetRandomize() _GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $iCanvasWidth, $iCanvasHeight, $hBrush_Clear) ;~ _GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $iCanvasWidth, $iCanvasHeight, $hBrush_Draw) EndFunc Func _DrawingProcess() ; For some reason I keep getting some kind of idle change ; shortly after starting, causing it to fail immediately. ; That's why I added an allowance of 500ms. If Abs($iLastActive - _LastActive($hUser32)) > 500 Then _Exit() ;~ _GDIPlus_BrushSetSolidColor($hBrush_Draw, 0xFF202020) ;~ _GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $iCanvasWidth, $iCanvasHeight, $hBrush_Clear) _TargetFollowing() _TimePieceMove() _WinAPI_BitBlt($hDC, 0, 0, $iCanvasWidth, $iCanvasHeight, $hDC_backbuffer, 0, 0, $SRCCOPY) ; Copy buffer to main EndFunc Func _TargetRandomize() Global $aTargetRandom[2] = [ Random(0, $iCanvasWidth - $iTextWidth, 1), Random(0, $iCanvasHeight - $iTextHeight, 1) ] EndFunc Func _TargetFollowing() Local $xDiff = $aTargetRandom[$tg_x] - $aTargetFollow[$tg_x] Local $yDiff = $aTargetRandom[$tg_y] - $aTargetFollow[$tg_y] If Sqrt($xDiff ^ 2 + $yDiff ^ 2) < $iProxRadius Then _TargetRandomize() EndIf ;~ If ($aTargetFollow[$tg_x] > $iCanvasWidth - $iTextWidth And $aTargetFollow[$tg_xVel] > 0) Or _ ;~ ($aTargetFollow[$tg_x] < 0 And $aTargetFollow[$tg_xVel] < 0) Or _ ;~ ($aTargetFollow[$tg_y] > $iCanvasHeight - $iTextHeight And $aTargetFollow[$tg_yVel] > 0) Or _ ;~ ($aTargetFollow[$tg_y] < 0 And $aTargetFollow[$tg_yVel] < 0) Then ;~ $nDecay = 1.1 ;~ Else ;~ $nDecay = 1.01 ;~ EndIf $aTargetFollow[$tg_xVel] += $xDiff * $nTargetSpeed /1000 $aTargetFollow[$tg_yVel] += $yDiff * $nTargetSpeed /1000 If ($xDiff < 0 And $aTargetFollow[$tg_xVel] > 0) Or ($xDiff > 0 And $aTargetFollow[$tg_xVel] < 0) Then $aTargetFollow[$tg_xVel] /= $nDecay EndIf If ($yDiff < 0 And $aTargetFollow[$tg_yVel] > 0) Or ($yDiff > 0 And $aTargetFollow[$tg_yVel] < 0) Then $aTargetFollow[$tg_yVel] /= $nDecay EndIf ;~ $aTargetFollow[$tg_xVel] /= $nDecay ;~ $aTargetFollow[$tg_yVel] /= $nDecay $aTargetFollow[$tg_x] += $aTargetFollow[$tg_xVel] $aTargetFollow[$tg_y] += $aTargetFollow[$tg_yVel] If $aTargetFollow[$tg_x] > $iCanvasWidth - $iTextWidth And $aTargetFollow[$tg_xVel] > 0 Then $aTargetFollow[$tg_xVel] *= -1 $aTargetFollow[$tg_x] = $iCanvasWidth - $iTextWidth ElseIf $aTargetFollow[$tg_x] < 0 And $aTargetFollow[$tg_xVel] < 0 Then $aTargetFollow[$tg_xVel] *= -1 $aTargetFollow[$tg_x] = 0 EndIf If $aTargetFollow[$tg_y] > $iCanvasHeight - $iTextHeight And $aTargetFollow[$tg_yVel] > 0 Then $aTargetFollow[$tg_yVel] *= -1 $aTargetFollow[$tg_y] = $iCanvasHeight - $iTextHeight ElseIf $aTargetFollow[$tg_y] < 0 And $aTargetFollow[$tg_yVel] < 0 Then $aTargetFollow[$tg_yVel] *= -1 $aTargetFollow[$tg_y] = 0 EndIf ;~ _GDIPlus_GraphicsDrawRect($hBackbuffer, $aTargetFollow[$tg_x], $aTargetFollow[$tg_y], $iTextWidth, $iTextHeight, $hPen_Draw) ;~ _GDIPlus_BrushSetSolidColor($hBrush_Draw, 0xFF00FFFF) ;~ _GDIPlus_GraphicsFillEllipse($hBackbuffer, $aTargetRandom[$tg_x] - 10, $aTargetRandom[$tg_y] - 10, 20, 20, $hBrush_Draw) ;~ _GDIPlus_BrushSetSolidColor($hBrush_Draw, 0xFFFFFFFF) ;~ _GDIPlus_GraphicsFillEllipse($hBackbuffer, $aTargetFollow[$tg_x] - 10, $aTargetFollow[$tg_y] - 10, 20, 20, $hBrush_Draw) EndFunc Func _TimePieceMove() Local $iHour = Int(@HOUR) If Not $i24Hour Then If $iHour = 0 Then $iHour = 12 If $iHour > 12 Then $iHour -= 12 EndIf Local $sTimeString = StringFormat('%2s:%02d:%02d', $iHour, @MIN, @SEC) $aTimeString = StringSplit($sTimeString, '', 2) If UBound($aTimeString) <> 8 Then AdlibUnRegister('_DrawingProcess') MsgBox(0x42010, 'Error parsing time string.', '$sTimeString = "' & $sTimeString & '" (' & StringLen($sTimeString) & ')') Exit EndIf ; Clear previous drawing For $idx = 0 To 7 _GDIPlus_GraphicsFillRect($hBackbuffer, $aTimePieces[$idx][$tp_x], $aTimePieces[$idx][$tp_y], $aTimePieces[$idx][$tp_w], $aTimePieces[$idx][$tp_h], $hBrush_Clear) Next _StringPlace(0, $aTargetFollow[$tg_x], $aTargetFollow[$tg_y]) For $i = 1 To 7 _StringPlace($i, $aTimePieces[$i-1][$tp_x] + $aTimePieces[$i-1][$tp_w] * 0.6, $aTimePieces[$i-1][$tp_y]) Next ;~ _StringPlace(3, $iTextWidth/2 + $aTargetFollow[$tg_x] - $aTimePieces[3][$tp_w], $aTargetFollow[$tg_y]) ;~ _StringPlace(4, $iTextWidth/2 + $aTargetFollow[$tg_x], $aTargetFollow[$tg_y]) ;~ For $i = 2 To 0 Step -1 ;~ _StringPlace($i, $aTimePieces[$i+1][$tp_x] - $aTimePieces[$i][$tp_w], $aTimePieces[$i+1][$tp_y]) ;~ Next ;~ For $i = 5 To 7 ;~ _StringPlace($i, $aTimePieces[$i-1][$tp_x] + $aTimePieces[$i-1][$tp_w], $aTimePieces[$i-1][$tp_y]) ;~ Next EndFunc Func _StringPlace($idx, $x, $y) If $aTimeString[$idx] = ' ' Then $aTimeString[$idx] = '' $aTimePieces[$idx][$tp_char] = $aTimeString[$idx] Local $aMeasure = _GDIPlus_GraphicsMeasureString($hBackbuffer, $aTimePieces[$idx][$tp_char], $hFont, $tLayout, $hFormat) $aTimePieces[$idx][$tp_w] = DllStructGetData($aMeasure[0], 'Width') $aTimePieces[$idx][$tp_h] = DllStructGetData($aMeasure[0], 'Height') $aTimePieces[$idx][$tp_x] += ($x - $aTimePieces[$idx][$tp_x]) * $nDriftSpeed /1000 $aTimePieces[$idx][$tp_y] += ($y - $aTimePieces[$idx][$tp_y]) * $nDriftSpeed /1000 DllStructSetData($aMeasure[0], 'x', $aTimePieces[$idx][$tp_x]) DllStructSetData($aMeasure[0], 'y', $aTimePieces[$idx][$tp_y]) If $iRainbowText Then $aHSL[0] = $aTimePieces[$idx][$tp_x] / @DesktopWidth * 480 $aHSL[2] = 200 - ($aTimePieces[$idx][$tp_y] / @DesktopHeight * 160) ; Range: 200-40 top-bottom Local $iBrushColor = _ColorSetRGB(_ColorConvertHSLtoRGB($aHSL)) _GDIPlus_BrushSetSolidColor($hBrush_Draw, 0xFF000000 + $iBrushColor) EndIf ;~ _GDIPlus_GraphicsDrawRect($hBackbuffer, $aTimePieces[$idx][$tp_x], $aTimePieces[$idx][$tp_y], $aTimePieces[$idx][$tp_w], $aTimePieces[$idx][$tp_h], $hPen_Draw) _GDIPlus_GraphicsDrawStringEx($hBackbuffer, $aTimePieces[$idx][$tp_char], $hFont, $aMeasure[0], $hFormat, $hBrush_Draw) Return $aMeasure[0] EndFunc Func _LastActive($vUser32Dll = 'user32.dll') Local $tLastInput = DllStructCreate('uint;dword') DllStructSetData($tLastInput, 1, DllStructGetSize($tLastInput)) DllCall($vUser32Dll, 'int', 'GetLastInputInfo', 'ptr', DllStructGetPtr($tLastInput)) Return DllStructGetData($tLastInput, 2) EndFunc Func _Exit() _GDIPlus_GraphicsFillRect($hBackbuffer, 0, 0, $iCanvasWidth, $iCanvasHeight, $hBrush_Clear) _WinAPI_BitBlt($hDC, 0, 0, $iCanvasWidth, $iCanvasHeight, $hDC_backbuffer, 0, 0, $SRCCOPY) ; Copy buffer to main AdlibUnRegister('_DrawingProcess') DllClose($hUser32) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush_Draw) _GDIPlus_GraphicsDispose($hBackbuffer) _WinAPI_SelectObject($hDC, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hBitmap_backbuffer) _WinAPI_ReleaseDC($hWndCanvas, $hDC) _GDIPlus_Shutdown() Exit EndFunc