Kleine Binär Uhr

  • Hey,
    Hatte ein wenig langeweile und wollt mal versuchen auf einem transparenten Fenster mit GDI+ zu arbeiten.
    Aufgebaut ist es in 3 Spalten (Stunden, Minuten, Sekunden) wobei die Lowbits unten sind.

    Schauts euch einfach an, vllt gefällts euch ja ^^

    Code
    [autoit]

    #NoTrayIcon
    #include <GUIConstantsEx.au3>
    #include <WinApi.au3>
    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $SC_DRAGMOVE = 0xF012

    [/autoit] [autoit][/autoit] [autoit]

    Global $nWidth = 100, $nHeight = 130, $nWnd_X = 1066, $nWnd_Y = 46

    [/autoit] [autoit][/autoit] [autoit]

    Global $Kreis_size = 15

    [/autoit] [autoit][/autoit] [autoit]

    Global $Sec, $Type = 1

    [/autoit] [autoit][/autoit] [autoit]

    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", 500)
    DllStructSetData($tSize, "Y", 500)
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", 255)
    DllStructSetData($tBlend, "Format", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aHour[5]
    _FillArrayWithBinary($aHour, @HOUR)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aMin[6]
    _FillArrayWithBinary($aMin, @MIN)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aSec[6]
    _FillArrayWithBinary($aSec, @SEC)

    [/autoit] [autoit][/autoit] [autoit]

    Dim $aAll[17]

    [/autoit] [autoit][/autoit] [autoit]

    $hWnd = GUICreate("Binary-Clock", 500, 500, $nWnd_X, $nWnd_Y, -1, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_FollowMouse")
    $nMenu = GUICtrlCreateContextMenu(-1)
    GUICtrlSetOnEvent(GUICtrlCreateMenuItem("Exit", $nMenu), "_Exit")
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_LBUTTONDBLCLK, "_ChangeType")

    [/autoit] [autoit][/autoit] [autoit]

    $hDC_Window = _WinAPI_GetDC($hWnd)
    $hDC_Buffer = _WinAPI_CreateCompatibleDC($hDC_Window)
    $hBitmap_Buffer = _WinAPI_CreateCompatibleBitmap($hDC_Window, 500, 500)
    _WinAPI_SelectObject($hDC_Buffer, $hBitmap_Buffer)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC_Buffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphics, 2)
    DllCall($ghGDIPDll, "uint", "GdipSetTextRenderingHint", "handle", $hGraphics, "int", 4);; Macht durchsichtig ?!

    [/autoit] [autoit][/autoit] [autoit]

    $hPen_Hour = _GDIPlus_PenCreate(0xFF000000)
    $hBrush_Hour = _GDIPlus_BrushCreateSolid(0xAAFF0000)

    [/autoit] [autoit][/autoit] [autoit]

    $hPen_Min = _GDIPlus_PenCreate(0xFF000000)
    $hBrush_Min = _GDIPlus_BrushCreateSolid(0xAA00FF00)

    [/autoit] [autoit][/autoit] [autoit]

    $hPen_Sec = _GDIPlus_PenCreate(0xFF000000)
    $hBrush_Sec = _GDIPlus_BrushCreateSolid(0xAA0000FF)

    [/autoit] [autoit][/autoit] [autoit]

    $hBrush_BG = _GDIPlus_BrushCreateSolid(0x30000000)

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(100)
    If $Sec <> @SEC Then
    $Sec = @SEC
    _DRAW()
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _DRAW()
    _GDIPlus_GraphicsClear($hGraphics, 0x0)
    _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $nWidth, $nHeight, $hBrush_BG)

    [/autoit] [autoit][/autoit] [autoit]

    _FillArrayWithBinary($aHour, @HOUR)
    _FillArrayWithBinary($aMin, @MIN)
    _FillArrayWithBinary($aSec, @SEC)

    [/autoit] [autoit][/autoit] [autoit]

    Switch $Type
    Case 1
    _DrawDisplay1()
    Case 2
    _DrawDisplay2()
    Case 3
    _DrawDisplay3()
    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_UpdateLayeredWindow($hWnd, $hDC_Window, 0, $pSize, $hDC_Buffer, $pSource, 0, $pBlend, 2)
    EndFunc ;==>_DRAW

    [/autoit] [autoit][/autoit] [autoit]

    Func _DrawDisplay3()
    _GDIPlus_GraphicsDrawString($hGraphics, "EMPTY", 0, 0)
    EndFunc ;==>_DrawDisplay3

    [/autoit] [autoit][/autoit] [autoit]

    Func _DrawDisplay2()
    For $i = 0 To 4
    $aAll[$i] = $aHour[$i]
    Next
    For $i = 5 To 10
    $aAll[$i] = $aMin[$i - 5]
    Next
    For $i = 11 To 16
    $aAll[$i] = $aSec[$i - 11]
    Next

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 17
    If $aAll[$i - 1] = 1 Then
    If $i >= 1 And $i <= 5 Then ;; Hour
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($Kreis_size * $i), $nHeight / 2, $Kreis_size, $hBrush_Hour)
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i), $nHeight / 2, $Kreis_size, $hPen_Hour)
    ElseIf $i >= 6 And $i <= 11 Then ;; Min
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size, $nHeight / 2, $Kreis_size, $hBrush_Min)
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size, $nHeight / 2, $Kreis_size, $hPen_Min)
    ElseIf $i >= 12 And $i <= 17 Then;; Sec
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size * 2, $nHeight / 2, $Kreis_size, $hBrush_Sec)
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size * 2, $nHeight / 2, $Kreis_size, $hPen_Sec)
    EndIf
    EndIf
    If $aAll[$i - 1] = 0 Then
    If $i >= 1 And $i <= 5 Then ;; Hour
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i), $nHeight / 2, $Kreis_size, $hPen_Hour)
    ElseIf $i >= 6 And $i <= 11 Then ;; Min
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size, $nHeight / 2, $Kreis_size, $hPen_Min)
    ElseIf $i >= 12 And $i <= 17 Then;; Sec
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($Kreis_size * $i) + $Kreis_size * 2, $nHeight / 2, $Kreis_size, $hPen_Sec)
    EndIf
    EndIf
    Next
    EndFunc ;==>_DrawDisplay2

    [/autoit] [autoit][/autoit] [autoit]

    Func _DrawDisplay1()

    [/autoit] [autoit][/autoit] [autoit]

    ;; Stunden
    For $i = 0 To UBound($aHour) - 1
    If $aHour[$i] = 1 Then
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($nWidth / 4) * 1, ($i + 2) * $Kreis_size, $Kreis_size, $hBrush_Hour)
    EndIf
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($nWidth / 4) * 1, ($i + 2) * $Kreis_size, $Kreis_size, $hPen_Hour)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;; Minuten
    For $i = 0 To UBound($aMin) - 1
    If $aMin[$i] = 1 Then
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($nWidth / 4) * 2, ($i + 1) * $Kreis_size, $Kreis_size, $hBrush_Min)
    EndIf
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($nWidth / 4) * 2, ($i + 1) * $Kreis_size, $Kreis_size, $hPen_Min)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;; Sekunden
    For $i = 0 To UBound($aSec) - 1
    If $aSec[$i] = 1 Then
    _GDIPlus_GraphicsFillEllipseMid($hGraphics, ($nWidth / 4) * 3, ($i + 1) * $Kreis_size, $Kreis_size, $hBrush_Sec)
    EndIf
    _GDIPlus_GraphicsDrawEllipseMid($hGraphics, ($nWidth / 4) * 3, ($i + 1) * $Kreis_size, $Kreis_size, $hPen_Sec)
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;; Digitale Uhrzeit
    ;; Kasten
    $Time = @HOUR & ":" & @MIN & ":" & @SEC
    _GDIPlus_GraphicsDrawString($hGraphics, $Time, $nWidth / 2 - 25, $nHeight - 20, "Arial", 10)
    EndFunc ;==>_DrawDisplay1

    [/autoit] [autoit][/autoit] [autoit]

    Func _ChangeType()
    $Pos = WinGetPos("Binary-Clock")
    $Type += 1
    If $Type >= 4 Then $Type = 1
    Switch $Type
    Case 1
    $nWidth = 100
    $nHeight = 130
    Case 2
    $nWidth = $Kreis_size * 20
    $nHeight = $Kreis_size * 2
    Case 3
    $nWidth = 130
    $nHeight = 130
    EndSwitch
    _GDIPlus_GraphicsClear($hGraphics, 0xABCDEF)
    _Draw()
    EndFunc ;==>_ChangeType

    [/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsDrawEllipseMid($hGraphic, $x, $y, $Durchmesser, $hPen = 0)
    _GDIPlus_GraphicsDrawEllipse($hGraphic, $x - $Durchmesser / 2, $y - $Durchmesser / 2, $Durchmesser, $Durchmesser, $hPen)
    EndFunc ;==>_GDIPlus_GraphicsDrawEllipseMid

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _GDIPlus_GraphicsFillEllipseMid($hGraphic, $x, $y, $Durchmesser, $hBrush = 0)
    _GDIPlus_GraphicsFillEllipse($hGraphic, $x - $Durchmesser / 2, $y - $Durchmesser / 2, $Durchmesser, $Durchmesser, $hBrush)
    EndFunc ;==>_GDIPlus_GraphicsFillEllipseMid

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _FillArrayWithBinary(ByRef $aArray, $nDec)
    $aBits = StringSplit(_TranslateBase($nDec), "", 2)
    For $i = 0 To UBound($aArray) - 1 - UBound($aBits)
    $aArray[$i] = 0
    Next

    [/autoit] [autoit][/autoit] [autoit]

    For $i = UBound($aArray) - UBound($aBits) To UBound($aArray) - 1
    $aArray[$i] = $aBits[$i - (UBound($aArray) - UBound($aBits))]
    Next
    EndFunc ;==>_FillArrayWithBinary

    [/autoit] [autoit][/autoit] [autoit]

    Func _FollowMouse()
    _SendMessage($hWnd, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
    EndFunc ;==>_FollowMouse

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_PenDispose($hPen_Hour)
    _GDIPlus_PenDispose($hPen_Min)
    _GDIPlus_PenDispose($hPen_Sec)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_ReleaseDC($hWnd, $hDC_Window)
    _WinAPI_DeleteDC($hDC_Buffer)
    _WinAPI_DeleteObject($hBitmap_Buffer)

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus_BrushDispose($hBrush_Hour)
    _GDIPlus_BrushDispose($hBrush_Min)
    _GDIPlus_BrushDispose($hBrush_Sec)
    _GDIPlus_BrushDispose($hBrush_BG)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _TranslateBase($sNumber, $iOldBase = 10, $iNewBase = 2)
    ;!!by eukalyptus!!
    If $iOldBase < 2 Or $iOldBase > 36 Or $iNewBase < 2 Or $iNewBase > 36 Then Return SetError(1, 1, False)
    Local $iNum, $aRes, $tChr = DllStructCreate("char[64];")
    If $iOldBase <> 10 Then
    $aRes = DllCall("msvcrt.dll", "uint64:cdecl", "_strtoui64", "str", $sNumber, "ptr", 0, "int", $iOldBase)
    If @error Then Return SetError(1, 2, False)
    $iNum = $aRes[0]
    Else
    $iNum = Int($sNumber)
    EndIf
    $aRes = DllCall("msvcrt.dll", "ptr:cdecl", "_i64toa", "int64", $iNum, "ptr", DllStructGetPtr($tChr), "int", $iNewBase)
    If @error Then Return SetError(1, 3, False)
    Return DllStructGetData($tChr, 1)
    EndFunc ;==>_TranslateBase

    [/autoit]

    Changelog:
    * 2. Binäransicht verschönert (Platz zwischen den Bit-Blöcken gelassen)
    _____________________________________________________________________________________
    + Binäransicht wechselbar mit Doppelklick
    + Neue Binäransicht
    * Schrift verschönert (Danke an name22 (Kann mir jmd sagen warum RenderingHint auf 3 die Bitmap in dem Fall durchsichtig macht?!)
    * Draw-Funktion ruckelt nichtmehr (Danke Marsi ;))
    * Vollständige Resourcen Freigabe

    PS: Beenden kann man es mit Rechter Maustaste->Exit
    Ich bau vllt noch ein, das die Position gespeichert wird in der das Fenster geschlossen wird, damit es immer richtig öffnet.

    mfg BB

    "IF YOU'RE GOING TO KILL IT
    OPEN SOURCE IT!"

    by Phillip Torrone

    Zitat von Shoutbox

    [Heute, 11:16] Andy: ....böseböseböseböse....da erinnere ich mich daran, dass man den Puschelschwanz eines KaRnickels auch "Blume" nennt....ob da eins zum anderen passt? :rofl: :rofl: :rofl: :rofl:

    https://autoit.de/index.php?page…leIt#post251138

    Neon Snake

    5 Mal editiert, zuletzt von BadBunny (1. April 2012 um 14:19)

  • Sehr schön geworden (wollte ich auch irgendwann mal machen...^^).

    Du Zeichnest aber alle 300ms.
    Dadurch geht die Uhr etwas "abgehackt", und es wird öfters als nötig gezeichnet.

    Das Folgende müsste beides beheben...

    [autoit]


    [...]
    While Sleep(50)
    _DRAW()
    WEnd

    [/autoit][autoit][/autoit][autoit]

    Func _DRAW()

    [/autoit][autoit][/autoit][autoit]

    Local Static $Sec = @SEC
    If $Sec = @SEC Then Return
    $Sec = @SEC
    [...]

    [/autoit]

    lg
    M

  • Hi,
    für´n Anfang nicht schlecht :thumbup:
    Nur hat das Script bei weitem zu viele Zeilen :rofl:

    WENN binär, dann richtig; Stunden, Minuten und Sekunden NACHEINANDER in einer Zeile, farblich getrennt,
    OOOOO|OOOOOO|OOOOOO, hat den Vorteil, die Uhr auch "in" den oberen Rahmen eines Fensters oder in die Menübar schieben zu können, ohne dass Fensterteile überdeckt werden.

    Tip: Wandele zuerst die std, min und sec in EINE Binärzahl, dann kannst du die Darstellung auch in eine kurze Schleife packen.
    "Gefüllte" und "nichtgefüllte" Kreise kannst du, genau wie die Darstellung der Farben, in einen Zeichenbefehl _GDIPlus_GraphicsFillEllipseMid() zusammenfassen ;)
    Tip: Viele IF´s durch eine logische Verknüpfung ersetzen

    Weiterhin verschwindet die Uhr bei mir nach Fensterwechsel unter anderen Fenstern und ist nicht mehr auffindbar....

    Die Anzeige nur einmal in jeder Sekunde würde ich einfach per adlibregister("_draw",1000) lösen.

  • Zitat

    Nur hat das Script bei weitem zu viele Zeilen :rofl:


    Ohja :D Das ist mir auch beim Coden aufgefallen aber ich hab erstmal nur Wert darauf gelegt das es ausnahmsweise mal gut aussieht :D

    Zitat

    WENN binär, dann richtig; Stunden, Minuten und Sekunden NACHEINANDER in einer Zeile, farblich getrennt,
    OOOOO|OOOOOO|OOOOOO, hat den Vorteil, die Uhr auch "in" den oberen Rahmen eines Fensters oder in die Menübar schieben zu können, ohne dass Fensterteile überdeckt werden.


    Ich denke ich mach mehrere Ansichten

    Zitat

    Weiterhin verschwindet die Uhr bei mir nach Fensterwechsel unter anderen Fenstern und ist nicht mehr auffindbar....


    Die sollte eig. direkt am Anfang schon im Hintergrund bleiben, ich hab den Style $WS_OVERLAPPED drin aber der funktioniert nicht so wie er eig soll?

    Zitat

    Die Anzeige nur einmal in jeder Sekunde würde ich einfach per adlibregister("_draw",1000) lösen.


    Dann kann es aber doch zu verzögerungen kommen oder nicht?

    mfg BB

    "IF YOU'RE GOING TO KILL IT
    OPEN SOURCE IT!"

    by Phillip Torrone

    Zitat von Shoutbox

    [Heute, 11:16] Andy: ....böseböseböseböse....da erinnere ich mich daran, dass man den Puschelschwanz eines KaRnickels auch "Blume" nennt....ob da eins zum anderen passt? :rofl: :rofl: :rofl: :rofl:

    https://autoit.de/index.php?page…leIt#post251138

    Neon Snake

  • Zitat

    Dann kann es aber doch zu verzögerungen kommen oder nicht?

    nein, die Funktion wird exakt alle 1000 Millisekunden aufgerufen. Wenn bspw. die Funktion 800ms dauert, dann wird 200ms gewartet, dauert die Funktion 5ms, dann wird die Funktion auch erst nach 995ms aufgerufen.
    Probleme gibts nur dann, wenn die Funktion länger dauert als das vorgegebene Wiederholungsintervall.

  • Jetzt funktioniert bei mir der Clear nicht mehr korrekt. d.H. der Hintergrund wird immer dunkler, bis man nichts mehr erkennen kann.

    Hab durch ausprobieren rausbekommen, dass ein Clear mit 0xFF000000 das Problem löst. (frag aber nicht warum^^)
    (Mein System ist XP. vllt hast du 7 und der Fehler trat bei dir nicht auf...)

    lg
    M

  • Zitat

    (Mein System ist XP. vllt hast du 7 und der Fehler trat bei dir nicht auf...)


    Jup. Diese transparenten Fenster verursachen unter XP immer Probleme. Ich hab leider kein XP zum testen und kann mir auch nicht vorstellen woran das liegt.

  • Ich benutze jetzt FillRect um den Hintergrund zu zeichnen, damit man die unterschiedlichen Größen benutzen kann. Mir GraphicsClear geht das leider nicht bzw nicht so einfach, aber dann würde es unter XP funktionieren weil es vorher auch ging.

    mfg BB

    "IF YOU'RE GOING TO KILL IT
    OPEN SOURCE IT!"

    by Phillip Torrone

    Zitat von Shoutbox

    [Heute, 11:16] Andy: ....böseböseböseböse....da erinnere ich mich daran, dass man den Puschelschwanz eines KaRnickels auch "Blume" nennt....ob da eins zum anderen passt? :rofl: :rofl: :rofl: :rofl:

    https://autoit.de/index.php?page…leIt#post251138

    Neon Snake