Moin,
Habe eine kleine Uhr gebastelt. Sie wird auf dem Hauptbildschirm angezeigt, sobald der Mauszeiger eine y Koordinate von 0 hat (als ganz oben). Konnte leider nicht testen ob sie korrekt von 23:59:59 auf 00:00:00 umschaltet (hab immer den Zeitpunkt verpennt). Die CPU Last ist im Leerlauf extrem gering (weil nicht gezeichnet wird) und beim Anzeigen auch human (bei mir ca. 2%). 100% GDI+, keine GDI/ASM Zauberei
Kritik und Verbesserungsvorschläge sind gerne gesehen
Edit (02.04.2015):
- Es wird WS_ES_TOOLWINDOW benutzt (wollte ich ursürünglich tun, habe es aber vergessen. Danke für die Erinnerung)
- Farbeinstellungen erweitert und insgesamt besser kommentiert.
- Kleine Zusammenfassungen sodass der Code kürzer ist.
Spoiler anzeigen
AutoIt: Uhr.au3
; Kleine Uhr von Mars@AutoIt.de
#include <GDIPlus.au3>
; ####################### Einstellungen #######################
; Größe der Uhr. Die Uhr skaliert automatisch mit der gewählten Schriftgröße
Global Const $iFontSize = 100
; Mögliche Ziffernfarben (bei nur einer Farbe wird die Uhr immer diese Farbe behalten)
Global Const $aFontColor[] = [0xFF20CC20, 0xFFCC2020, 0xFF2020CC, 0xFFFF8000, 0xFF00FF80, 0xFF8000FF, 0xFFFF0080, 0xFF0080FF, 0xFF80FF00]
; Soll die Uhr bei jedem Aufruf eine neue Farbe erhalten ? (Die neue Farbe wird zufällig gewählt und kann der alten Farbe entsprechen)
Global Const $bNewColors = True
; Fenstertransparenz (255 = völlständig sichtbar, 0 = vollständig transparent)
Global Const $iTrans = 225
; #############################################################
; Starten
Opt('GUIOnEventMode', 1)
_GDIPlus_Startup()
; Globale Konstanten & Variablen
Global Const $iW = Round($iFontSize * 5.9, 0)
Global Const $iH = Round($iFontSize * 1.5, 0)
Global Const $iXOffset = @DesktopWidth / 2 - $iW / 2
Global Const $iDCircle = $iFontSize / 10
Global $iOffset = $iH
Global $hGUI = GUICreate('Uhr', $iW, $iH, $iXOffset, -$iH, 0x80000000, 0x80) ; WS_POPUP und WP_EX_TOOLWINDOW
Global $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Global $hBMP = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGFX)
Global $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
Global $hFAM = _GDIPlus_FontFamilyCreate('Arial')
Global $hFON = _GDIPlus_FontCreate($hFAM, $iFontSize)
Global $hBRU = _GDIPlus_BrushCreateSolid($aFontColor[Random(0, UBound($aFontColor) - 1, 1)])
Global $hFOR = _GDIPlus_StringFormatCreate()
Global $hBRU_B = _GDIPlus_BrushCreateSolid(0xFF000000)
Global $hBRU_T = _GDIPlus_BrushCreateSolid(0xFF000000)
Global $hBRU_W = _GDIPlus_BrushCreateSolid(0x25FFFFFF)
_GDIPlus_StringFormatSetAlign($hFOR, 1)
_GDIPlus_GraphicsSetTextRenderingHint($hBUF, 4)
; Unmengen Unfug für das GUI
GUISetBkColor(0, $hGUI)
WinSetOnTop($hGUI, '', 1)
WinSetTrans($hGUI, '', $iTrans)
GUISetOnEvent(-3, '_Exit', $hGUI)
OnAutoItExitRegister('Release')
GUIRegisterMsg(0xF, 'WM_PAINT')
GUISetState(@SW_SHOW, $hGUI)
While Sleep(10) ; Uberragend komplexer Main-Loop
Pos()
WEnd
Func Pos() ; Checkt die Position der Maus und zeigt ggf die Uhr an
Local $aPos = MouseGetPos()
Local Static $bMove, $iOffsetOld
$iOffsetOld = $iOffset
$iOffset = $aPos[1] = 0 ? $iOffset / 1.5 : ($iOffset + 1) * 1.5 > $iH ? $iH : ($iOffset + 1) * 1.5
If $iOffset < 1 Then $iOffset = 0
If $iOffsetOld <> $iOffset Then WinMove($hGUI, '', $iXOffset, -$iOffset)
If $iOffsetOld <> $iOffset Or $iOffset = 0 Then Uhr($iOffset = $iH / 1.5) ; Neuzeichnen beim ersten Frame den die Uhr innerhalb des Bildschirms ist.
EndFunc
Func Uhr($bNeuZeichnen = False)
Local Static $hDraw = False, $mDraw = False, $bFirstRun = True
Local $h = @HOUR, $m = @MIN, $s = @SEC, $ms = @MSEC, $iTime
If $bNewColors And $bNeuZeichnen Then ; Neue Farbe
$bFirstRun = True
DllCall($__g_hGDIPDll, 'int', 'GdipDeleteBrush', 'handle', $hBRU)
$hBRU = DllCall($__g_hGDIPDll, 'int', 'GdipCreateSolidFill', 'int', $aFontColor[Random(0, UBound($aFontColor) - 1, 1)], 'handle*', 0)[2]
EndIf
If $bFirstRun Then ; Zu Beginn die 4 Kreise zeichnen (mit smoothing).
DllCall($__g_hGDIPDll, 'int', 'GdipGraphicsClear', 'handle', $hBUF, 'dword', 0xFF000000)
DllCall($__g_hGDIPDll, 'int', 'GdipSetSmoothingMode', 'handle', $hBUF, 'int', $GDIP_SMOOTHINGMODE_ANTIALIAS8X8)
DllCall($__g_hGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hBUF, 'handle', $hBRU, 'float', $iW / 3 - $iDCircle / 2, 'float', $iH / 3 - $iDCircle / 2, 'float', $iDCircle, 'float', $iDCircle)
DllCall($__g_hGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hBUF, 'handle', $hBRU, 'float', $iW / 3 - $iDCircle / 2, 'float', $iH / 3 * 2 - $iDCircle / 2, 'float', $iDCircle, 'float', $iDCircle)
DllCall($__g_hGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hBUF, 'handle', $hBRU, 'float', $iW / 3 * 2 - $iDCircle / 2, 'float', $iH / 3 - $iDCircle / 2, 'float', $iDCircle, 'float', $iDCircle)
DllCall($__g_hGDIPDll, 'int', 'GdipFillEllipse', 'handle', $hBUF, 'handle', $hBRU, 'float', $iW / 3 * 2 - $iDCircle / 2, 'float', $iH / 3 * 2 - $iDCircle / 2, 'float', $iDCircle, 'float', $iDCircle)
DllCall($__g_hGDIPDll, 'int', 'GdipSetSmoothingMode', 'handle', $hBUF, 'int', $GDIP_SMOOTHINGMODE_DEFAULT)
$hDraw = True
$mDraw = True
$bFirstRun = False
EndIf
$hDraw = Feld($hDraw, $bNeuZeichnen, ($m = 59 And $s = 59) ? $h + $ms / 1000 : Int($h), 0.95, 0.05) ; Zeichnet das Stundenfeld
$mDraw = Feld($mDraw, $bNeuZeichnen, $s = 59 ? $m + $ms / 1000 : Int($m), 2.95, 2.075, 1.75) ; Zeichnet das Minutenfeld
Feld(0, 1, $s + $ms / 1000, 4.97, 4.05) ; Zeichnet das Sekundenfeld
DllCall($__g_hGDIPDll, 'int', 'GdipDrawImageI', 'handle', $hGFX, 'handle', $hBMP, 'int', 0, 'int', 0)
EndFunc
Func Feld($xDraw, $bNeuZeichnen, $iTime, $iMulti1, $iMulti2, $iMulti3 = 1.8) ; Zeichnet ein Feld mit einer Ziffer darin
If Not IsInt($iTime) Then $xDraw = True
If $xDraw Or $bNeuZeichnen Then
DllCall($__g_hGDIPDll, 'int', 'GdipFillRectangleI', 'handle', $hBUF, 'handle', $hBRU_B, 'int', $iFontSize * $iMulti2, 'int', 0, 'int', $iFontSize * $iMulti3, 'int', $iH) ; Nur die betreffende Stelle clearen
Ziffer($iTime, $iFontSize * $iMulti1, 0)
Ziffer($iTime + 1, $iFontSize * $iMulti1, -$iFontSize * 1.5)
DllCall($__g_hGDIPDll, 'int', 'GdipFillRectangleI', 'handle', $hBUF, 'handle', $hBRU_T, 'int', $iFontSize * $iMulti2, 'int', 0, 'int', $iFontSize * $iMulti3, 'int', $iH * 0.05) ; Oben und unten Schwarzer Balken.
DllCall($__g_hGDIPDll, 'int', 'GdipFillRectangleI', 'handle', $hBUF, 'handle', $hBRU_T, 'int', $iFontSize * $iMulti2, 'int', $iH * 0.95, 'int', $iFontSize * $iMulti3, 'int', $iH * 0.05 + 1)
DllCall($__g_hGDIPDll, 'int', 'GdipFillRectangleI', 'handle', $hBUF, 'handle', $hBRU_W, 'int', $iFontSize * $iMulti2, 'int', 0, 'int', $iFontSize * $iMulti3, 'int', $iH * 0.5) ; Oben Hell
Return IsInt($iTime) ? False : True
EndIf
EndFunc
Func Ziffer($n, $x, $y, $l = 1) ; Zeichnet eine Zimmer im Puffer an x, y. ($l = 1 -> Ziffer geht bis 60, sonst bis 24)
$n = $l ? $n < 60 ? $n : $n - 60 : $n < 24 ? $n : $n - 24
DllCall($__g_hGDIPDll, 'int', 'GdipDrawString', 'handle', $hBUF, 'wstr', StringFormat('%02i', Int($n)), 'int', -1, 'handle', $hFON, 'struct*', _GDIPlus_RectFCreate($x, $y + $iFontSize * 1.5 * ($n - Int($n)) ^ 5 - 0.5), 'handle', $hFOR, 'handle', $hBRU)
EndFunc
Func WM_PAINT()
DllCall($__g_hGDIPDll, 'int', 'GdipDrawImageI', 'handle', $hGFX, 'handle', $hBMP, 'int', 0, 'int', 0)
EndFunc
Func Release()
_GDIPlus_BrushDispose($hBRU_W)
_GDIPlus_BrushDispose($hBRU_T)
_GDIPlus_BrushDispose($hBRU_B)
_GDIPlus_StringFormatDispose($hFOR)
_GDIPlus_BrushDispose($hBRU)
_GDIPlus_FontDispose($hFON)
_GDIPlus_FontFamilyDispose($hFAM)
_GDIPlus_GraphicsDispose($hBUF)
_GDIPlus_BitmapDispose($hBMP)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
EndFunc
Func _Exit()
Exit
EndFunc
Alles anzeigen
lg
M