• Hallo Com

    Ich hab mich ein wenig mit GDI+ auseinander gesetzt.
    Und habe mir zu anfang eine Digital Uhr nachgebaut

    Scheinbar gibt es Probleme bei Codes mit mehr als 900 Zeilen...
    Schade, bekomms nicht hin das er Angezeigt wird...auch nicht mit Spoiler...

    naja aufjeden fall wurd dan ein Array Spiel daraus ^^
    Aber schauts euch selbst an, Datei is hochgeladen

    greez

    Ps: Hab noch ein zwei Ideen im Hinterkopf, es wird sicher noch Updates geben :D

  • Hi,

    Zitat

    Scheinbar gibt es Probleme bei Codes mit mehr als 900 Zeilen...

    yepp, die Forensoftware erkennt nämlich, wenn 90% des codes überflüssig ist :D

    Digitaluhr in 50 Zeilen (unopimiert für bessere Lesbarkeit)

  • Zitat

    aber mir ging es nicht darum, den Code so einfach wie möglich zu halten

    ja, auch ich neige idR. zu "form follows function"
    Allerdings sollte imho das Ziel einer Programmierung nicht sein, möglichst viel Code zu erzeugen, durch den dann kein Mensch mehr durchblickt.

    Wenn man für ein "kleines" Problem so eben mal 600-800 Zeilen Code in einer zugegebenen Fleissarbeit erstellt, dazu dann Ressourcen in Form von Rechner- und Rechenkapazität verballert und mitten in dieser Aktion dann nicht feststellt, dass da etwas "schief läuft", dann weiss ich auch nicht weiter...
    Ein Forum wie dieses ist ja genau für diesen Fall da.
    Lernen und aus den Scripten bzw. Antworten der anderen das Know-How ziehen und auf das eigene Problem anwenden!

    Für jeden Anfänger, der über diesen Thread stolpert wäre es sinnvoller gewesen, du hättest gefragt, wie man diese Monsterarrays und die vielen Funktionen mit fast identischem Inhalt vermeidet bzw. programmiertechnisch einfacher realisiert!
    Erstens hättest du dich in der von dir benötigten Zeit wesentlich schneller weiterentwickelt und zweitens auch für alle anderen (auch Fortgeschrittenen) einen interessanten Thread erstellt.
    Jetzt schaut sich ein Anfänger dein Script an und kapiert nichts ;( , ein Fortgeschrittener schaut sich dein Script an und kapiert auch nicht viel mehr, bzw. erkennt sofort die programmtechnischen Defizite und würdigt deine "Arbeit" kein bisschen... ;(

    Naja, jedenfalls hast du dich durch ein Problem gekämpft und ein funktionierendes Script gebastelt, weiter so! :thumbup:

  • Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <Timers.au3>

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

    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

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

    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

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

    _GDIPlus_Startup()
    Global $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hgui) ;"Leinwand" erstellen, auf der gezeichnet werden kann
    ;_time()
    _Timer_SetTimer($hgui, 1000, "_TIMER_CALLBACK")

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

    Do ;Endlosschleife, solange bis..
    Until GUIGetMsg() = -3 ;..ESC gedrückt wird

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

    _Timer_KillAllTimers($hgui)
    _GDIPlus_GraphicsDispose($hGraphic) ;freigeben
    _GDIPlus_Shutdown()

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

    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

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

    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

    [/autoit]

    Macht im Grossen und Ganzen dasselbe wie dein Script....

    Schau dir mal deine Funktion für das Zeichnen von zwei Segmenten an:

    Spoiler anzeigen
    [autoit]

    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

    [/autoit]


    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 8o )
    Jede Ziffer hat 7 Segmente, die "angeschalteten" kann man einer 1 zuordnen
    Jetzt muss man die Segmente nur noch durchnummerieren.

    Code
    111
    2      3
    2      3 
      444
    5      6
    5      6
      777


    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.

    [autoit]

    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)

    [autoit]

    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 :rolleyes:

    Auch für einen absoluten Anfänger denke ich, ist das mit weit weniger als 100 Zeilen zu schaffen :D

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (2. Februar 2013 um 21:55)

  • So, da ich jetz besser bei Verstand bin schreib ich mal wass mir bei den weiteren posts durch den kopf ging.

    1: Danke minx für die schöne erläuterung.
    2: Versteht ihr nicht, dass ich überhauptnicht auf kurze Quelcodes oder Ressourcen Sparrend aus bin?

    Ich werde dafür nicht bezahlt ich mach dass hier just for fun.
    Und wollte einfach nur mal Zeigen wie man dass Ganze im "Schachtel" prinzip macht.
    Wie eine kollegin mal Sagte
    "Weisst du, Experimentieren und auserhalb der "Norm" zu Denken, ist vielen ein "Fremdwort" oder garnicht erst Möglich"
    In diesem sinne, Schönnen Abend noch :D

    Greez

  • Naja :D
    Das wurde ja durch deine Beiträge nicht klar.
    Zudem hast du uns ja regelrecht aufgefordert das Script zu kürzen. ;)

    "Alles was Sie sagen kann und wird gegen Sie verwendet!"
    --> Naja, weißt ja jetzt bescheid :D
    (Mir wurde das ganze schließlich auch erst nach unseren PN austausch klar.)

  • Naja wirklich aufgefordert hab ich euch nicht, da Andy meinte dass man mein Code noch stark kürzen kann, ging ich von der annahme aus, dass dieser jemand dies auch tut :whistling:

    Naja wie auch immer :D
    Ich gesteh auch mein Fehler ein dass ich bezüglich meiner Absichten mit dem Code, sehr geizig umgegangen bin.
    Nechstesmal, werd ich eindeutig DICK und FETT evt auch Unterstrichen sagen, was meine Beabsichtigung vom Code ist :D
    In diesem falle, entschuldige ich mich für meine faulheit :D

  • Zitat

    Naja wirklich aufgefordert hab ich euch nicht, da Andy meinte dass man mein Code noch stark kürzen kann, ging ich von der annahme aus, dass dieser jemand dies auch tut

    dieser jemand hat dein 900-Zeilen Script mit nahezu identischer Funktion in 50 Zeilen Code gebracht. Und zwar schon vor etlicher Zeit, s. Links zu den "Digitaluhr"-Threads und mein weiter oben gepostetes Script.

    "Stark kürzen"....das macht man bei Code und bei Usern, bei denen eine Chance besteht, dass sie etwas davon/dabei lernen.
    Da ich neben meiner Arbeit und den wenigen Stunden zusammen mit meiner Familie auch "just for Fun" programmiere, lehne ich es aber ab, nach Statements wie diesem:

    Zitat

    Versteht ihr nicht, dass ich überhauptnicht auf kurze Quelcodes oder Ressourcen Sparrend aus bin?
    Ich werde dafür nicht bezahlt ich mach dass hier just for fun.
    Und wollte einfach nur mal Zeigen wie man dass Ganze im "Schachtel" prinzip macht.
    Wie eine kollegin mal Sagte
    "Weisst du, Experimentieren und auserhalb der "Norm" zu Denken, ist vielen ein "Fremdwort" oder garnicht erst Möglich"

    jemandem, der sich nach eigenem dafürhalten "Experimentieren und ausserhalb der Norm zu denken" auf die Fahne geschrieben hat, auch noch 900 Zeilen seines aufgeblähten Codes zu beackern. Der Code funktioniert ja....

    Aber wenigstens ICH habe wieder etwas gelernt^^. Beim nächsten Posting bzw. Nachfrage werde ich mich dezent zurückhalten und NICHTS beitragen, wie sich das in einem ordentlichen Forum gehört.