Spoiler anzeigen
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <Timers.au3>
Dim $ws[12] = [0, 0, 10, -7, 50, -7, 60, 0, 50, 7, 10, 7] ;Koordinaten Polygonzug: von links nach rechts WAAGRECHTER Balken, von rechts nach links SENKRECHTER Balken
Dim $ziffer[10] = [239, 10, 118, 94, 154, 220, 253, 14, 254, 222] ;alle gesetzten bits des Indexes in der 7-segmentanzeige ergeben die Ziffer
Dim $balkenpos[8] = [0, "60.0", "0.0", "60.60", "0.60", "0.60", "0.120", "0.0"] ;position der Leuchtbalken der 7-Segmentanzeige innerhalb der Ziffer
Dim $p[7][2] ;nimmt die polygonzug-koordinaten zum Zeichnen auf
$p[0][0] = 6 ;6 Punkte im Polygonzug
Global $hgui = GUICreate('Uhr', 620, 175, -1, -1, $WS_POPUP, $WS_EX_CONTROLPARENT) ;GUI erstellen ohne Rahmen
GUISetBkColor(0x000000) ;Hintergrund der GUI schwarz
WinSetTrans($hgui, "", 205) ;transparenz
GUISetState() ;GUI anzeigen
_GDIPlus_Startup()
Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hgui) ;"Leinwand" erstellen, auf der gezeichnet werden kann
;_time()
_Timer_SetTimer($hgui, 1000, "_TIMER_CALLBACK")
Do ;Endlosschleife, solange bis..
Until GUIGetMsg() = -3 ;..ESC gedrückt wird
_Timer_KillAllTimers($hgui)
_GDIPlus_GraphicsDispose($hGraphic) ;freigeben
_GDIPlus_Shutdown()
Func _TIMER_CALLBACK($hWnd, $Msg, $iIDTimer, $dwTime)
;Uhrzeit anzeigen :o)
For $k = 1 To 6 ;die 6 Ziffern der Uhrzeit
$setbits = $ziffer[StringMid(String(@HOUR & @MIN & @SEC), $k, 1)] ;gesetzte Bits in der siebensegmentanzeige anhand der Ziffer in der Uhrzeit holen
For $bitnr = 7 To 1 Step -1 ;alle Bits durchlaufen
_drawpolygon(BitAND($setbits, 128), $k * 100 - 80 + ($k = 1 Or $k = 3 Or $k = 5) * 20, $bitnr) ;parameter: bit gesetzt ja/nein, position der gesamten ziffer,nummer des bits(gerade=waagrechter balken, ungerade=senkrechter balken)
$setbits = BitShift($setbits, -1) ;nächstes Bit holen
Next
Next
$brush = _GDIPlus_BrushCreateSolid(0xFF440000 + (@SEC / 2 = Int(@SEC / 2)) * 0xBB0000) ;Pinsel erstellen, wenn Ziffer gerade, dann farbig, ansonsten schwarz
_GDIPlus_GraphicsFillEllipse($hGraphic, 202, 55, 15, 15, $brush) ;Punkte zeichnen
_GDIPlus_GraphicsFillEllipse($hGraphic, 402, 55, 15, 15, $brush)
_GDIPlus_GraphicsFillEllipse($hGraphic, 202, 105, 15, 15, $brush)
_GDIPlus_GraphicsFillEllipse($hGraphic, 402, 105, 15, 15, $brush)
_GDIPlus_BrushDispose($brush) ;Pinsel auflösen
EndFunc ;==>_TIMER_CALLBACK
Func _drawpolygon($bit, $xpos, $bitnr) ;zeichnet einen polygonzug ("Balken") an die entsprechende Position
$split = StringSplit($balkenpos[$bitnr], ".", 3) ;x- und y-koordinaten des Balkens innerhalb der Ziffer holen
$b = (($bitnr / 2) = Int($bitnr / 2)) ;$bit gerade => $b = true => Balken waagrecht, ansonsten Balken senkrecht
$step = -1 + 2 * $b ;schrittweite durch das $WS-Array
For $i = 11 - 11 * $b To 11 * $b Step 2 * $step ;array mit waagrechten (bit=gerade) oder (Bit=ungerade) senkrechten Balken füllen
$r = Int(Abs((11 * (Not ($b))) - $i) / 2) + 1 ;abhängig von der Reihenfolge, egal ob $i von 0 bis 11 oder von 11 bis 0, $r muss immer 1,2,3,4,5,6
$p[$r][0] = $ws[$i] + $split[0] + $xpos ;x- und
$p[$r][1] = $ws[$i + $step] + $split[1] + 30 ;y-position in das polygonarray schreiben
Next
$brush = _GDIPlus_BrushCreateSolid(0xFF440000 + ($bit <> 0) * 0xBB0000) ;wenn bit gesetzt, dann farbig, ansonsten schwarz
_GDIPlus_GraphicsFillPolygon($hGraphic, $p, $brush) ;Balken zeichnen
_GDIPlus_BrushDispose($brush)
EndFunc ;==>_drawpolygon
Macht im Grossen und Ganzen dasselbe wie dein Script....
Schau dir mal deine Funktion für das Zeichnen von zwei Segmenten an:
Spoiler anzeigen
Func _Segment_H0_()
Local $Segment_Hour_Null[$SegmentName[0]] = [$Segment_Hour_Null[0]] ;_Segment_HLinks / 00
$Segment_Hour_Null[1] = $SegmentHour[1]
$Segment_Hour_Null[2] = $SegmentHour[2]
$Segment_Hour_Null[3] = $SegmentHour[3]
$Segment_Hour_Null[4] = $SegmentHour[5]
$Segment_Hour_Null[5] = $SegmentHour[6]
$Segment_Hour_Null[6] = $SegmentHour[7]
Local $Segment_Hour_Null_Greyed[$SegmentName[0] - 5] = [$Segment_Hour_Null_Greyed[0]]
$Segment_Hour_Null_Greyed[1] = $SegmentHour[4]
;~
For $i = 1 To UBound($Segment_Hour_Null) - 1
_GDIPlus_GraphicsFillPolygon($Graphic, $Segment_Hour_Null[$i], $Brush)
Next
For $ia = 1 To UBound($Segment_Hour_Null_Greyed) - 1
_GDIPlus_GraphicsFillPolygon($Graphic, $Segment_Hour_Null_Greyed[$ia], $Brush_Greyed)
Next
EndFunc ;==>_Segment_H0_
#endregion ### _Segment_H0_ ###
;==========
#region ### _Segment_H01 ###
Func _Segment_H01()
Local $Segment_Hour_NullEins[$SegmentName[0] - 4] = [$Segment_Hour_NullEins[0]] ;_Segment_HLinks / 01
$Segment_Hour_NullEins[1] = $SegmentHour_10[3]
$Segment_Hour_NullEins[2] = $SegmentHour_10[6]
Local $Segment_Hour_NullEins_Greyed[$SegmentName[0] - 1] = [$Segment_Hour_NullEins_Greyed[0]]
$Segment_Hour_NullEins_Greyed[1] = $SegmentHour_10[1]
$Segment_Hour_NullEins_Greyed[2] = $SegmentHour_10[2]
$Segment_Hour_NullEins_Greyed[3] = $SegmentHour_10[4]
$Segment_Hour_NullEins_Greyed[4] = $SegmentHour_10[5]
$Segment_Hour_NullEins_Greyed[5] = $SegmentHour_10[7]
;~
For $i = 1 To UBound($Segment_Hour_NullEins) - 1
_GDIPlus_GraphicsFillPolygon($Graphic, $Segment_Hour_NullEins[$i], $Brush)
Next
For $ia = 1 To UBound($Segment_Hour_NullEins_Greyed) - 1
_GDIPlus_GraphicsFillPolygon($Graphic, $Segment_Hour_NullEins_Greyed[$ia], $Brush_Greyed)
Next
EndFunc ;==>_Segment_H01
Der obere Teil ist lediglich eine Zuweisung, die man bequem in eine For/To schleife legen könnte, genau wie die in jeder Funktion vorkommenden 2 Schleifen um _GDIPlus_GraphicsFillPolygon().
x-dimensionale Arrays, die wiederum andere y-dimensionale Arrays indizieren...
Die Frage ist, ob das herangehen an das Problem verbessert werden sollte. ![]()
Die Ziffern der Uhr sind aus Segmenten zusammengesetzt.
Das Aussehen der einzelnen Segmente allgemein kann man berechnen, alle waagrechten und alle senkrechten Segmente sehen gleich aus! (wenn man mag, kann man auch je zwei berechnen fürs schönere Aussehen)
Es gibt also insgesamt nur 2 (oder 4) Segmente alle an definierten Positionen, die je nach Uhrzeit "an" oder "aus" geschaltet werden müssen.
Für die Uhr sieht das vorgehen so aus:
1) Berechne je EIN waagrechtes und senkrechtes Segment um es später an einer bestimmten Position darzustellen. (polygonzug)
2) Weise jeder Ziffer der Uhrzeit die an-, bzw. abgeschalteten Segmente zu. (Ein- bzw. Ausgeschaltet...klingelt es....an/aus...1/0....binär
)
Jede Ziffer hat 7 Segmente, die "angeschalteten" kann man einer 1 zuordnen
Jetzt muss man die Segmente nur noch durchnummerieren.
soweit sogut,
Bei einer darzustellenden "2" wären welche Segmente angeschaltet also "1"? Na, Segmentnummer 1,3,4,5 und 7. Die anderen Segmente 2 und 6 sind "0" (aus).
In einer Reihe von Null bis Sieben sieht die 2 also so aus:
Segment 1="1"
Segment 2="0"
Segment 3="1"
Segment 4="1"
Segment 5="1"
Segment 6="0"
Segment 7="1"
Hintereinandergeschrieben "1011101"
Somit hätten wir die "2", die "Binärdarstellung" der anderen Ziffern überlasse ich dir^^
Was bringt das?
Die Ziffern 0 bis 9 (wenn man mag auch noch die Buchstaben A-F) sind in einem einzigen Array von 10 Feldern darzustellen.
dim Ziffer[10]=["xxxxxx","xxxxxxx","1011101","xxx..."]; Binär(An/Aus)darstellung der Ziffern 0 bis 9
[/autoit]
Der Index des Arrays ist die "Ziffer" die dargestellt werden soll. 2 => "1011101"
Jetzt reicht EINE Schleife von 0 bis 7, um den String "1011101" abzuklappern und bei einer "1" das entsprechende "Segment" anzuschalten!
3) Aber wo ist die Position der einzelnen Segmente?
Zeichne dir die 7 gleichgroßen Segmente einer Ziffer flächenfüllend auf ein kariertes DIN A4 Blatt.
Die Mittelpunkte der Segmente werden markiert.
Dann brauchst du nur noch "Kästchen zählen", um die Koordinaten dieser Mittelpunkte festzulegen.
Beim Aufschreiben dieser Koordimaten sollte einem etwas auffallen^^(das wäre dann für die Fortgeschrittenen^^)
Man erstellt also ein Array mit Koordinaten (Index ist die Segmentnummer s.o. )
Bei meiner Zeichnung kommen folgende koordinaten raus (x- und y-Richtung, 0;0 ist oben links)
dim Koordinaten[8]=["indexnull;gibtsnicht","16;0","0;12","32;12","16,24", usw ]; koordinaten der segmente 1 bis 7,
[/autoit]
Wer unbedingt will, kann ein 2-dimensionales Array erstellen.
4) lese die Uhrzeit aus, splitte in die einzelnen Ziffern, bspw. die 2
Nimm die Ziffer als Index für das Segmentarray $Ziffer[], du erhälst "1011101"
Laufe durch diesen String, wenn du eine "1" findest nimm die Position der "1" innerhalb des Strings und verwende diese Position als Index für das Koordinaten-Array.
Du erhälst die Koordinaten zum Zeichnen der Segmente für die 2
5)lese die nächsten Ziffern aus der Uhrzeit aus, verfahre wie bei 4.
Erhöhe nur die y-Koordinaten um einen fixen Wert => die weiteren Ziffern werden nach rechts verschoben
Das wars schon.
Wenn du die "Segmente" als Kreise darstellst, sollte die Erstellung nach obigem Rezept schnell erledigt sein.
Aber woher weiss man, ob man ein waagrechtes oder ein senkrechtes Segment zeichnen soll?
Naja, man könnte es ja einfach machen und statt "1011101" einfach "W0SWSSW" schreiben W=waagrecht S=senkrecht ![]()
Auch für einen absoluten Anfänger denke ich, ist das mit weit weniger als 100 Zeilen zu schaffen ![]()