1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Code-Jack

Beiträge von Code-Jack

  • Datenbank dezentral erweitern [gelöst]

    • Code-Jack
    • 7. November 2018 um 00:35

    Hmm, interessant, was man so heraus findet.

    Laut SQLite-Doku war mein bisheriges Autoincrement ohnehin gar nicht nötig:

    http://www.sqlitetutorial.net/sqlite-autoincrement/

    Habe es ausprobiert und beim Kreieren der Tabelle das Autoincrement einfach mal weg gelassen.

    Funzt wie eh und je. Jeder neue Eintrag bekommt automatisch eine neue, forlaufende ID, beginnend ab 1.

    SQLite tut tas einfach von sich aus, die Doku rät daher von der Verwendung von Autoincrement ab.

    Gut, habe es also raus genommen.

    Nun kann ich beim Hinzufügen von neuen Datensätzten ins ID-Feld statt "NULL" eine beliebige Zahl einsetzen. Solange die eindeutig ist, funzt das.

    AutoIt
    ;Bisher war es so (gekürzte Zeile):
    _SQLite_Exec(-1, "INSERT INTO Mainboardverwaltung VALUES(NULL,'16-04-22', ...
    
    ;Neu, jetzt so: Statt NULL eindeutige und selbst vergebene ID (in diesem Beispiel "77"):
    _SQLite_Exec(-1, "INSERT INTO Mainboardverwaltung VALUES(" & 77 & ",'16-04-22', ...

    Gut, das war schon der erste Schritt zum Erfolg.

    Nun mit GUID:

    AutoIt
    ;Tabelle jetzt so kreieren (gekürzt):
    Global $sDBHeader = "CREATE TABLE IF NOT EXISTS [Mainboardverwaltung]" _
      & "([ID] TEXT PRIMARY KEY," ...
    
    _SQLite_Exec(-1, "INSERT INTO Mainboardverwaltung VALUES('" & _WinAPI_CreateGUID() & "','16-03-27 16', ...

    Und das klappt tadellos! :)

    Die Tabelle muss also jetzt zuvor einfach "TEXT" als Primary Key bekommen, statt wie bisher INTEGER und AUTOINCREMENT.

    Denn Integer wäre auch in der 8 Byte Variante (64 Bit) zu kurz, um die GUID aufzunehmen, mit ihren 128 Bit.

    Da _WinAPI_CreateGUID() sowieso einen String liefert, passt das.

    Ich schalte den Thread mal auf "gelöst" und bedanke mich für die guten Anworten!

  • Datenbank dezentral erweitern [gelöst]

    • Code-Jack
    • 6. November 2018 um 22:22

    Yeah, danke Bitnugger!

    Die AutoIt-Hilfe ist dazu ja etwas spärlich, aber hier wurde ich fündig:

    https://msdn.microsoft.com/de-de/library/bb979128.aspx

    Ich hatte schon mit dem Gedanken gespielt, selbst so eine irre lange ID zu erzeugen; wusste gar nicht, dass AutoIt das von sich aus kann.

    Dann würde ich in Zukunft diese ellenlange ID gar nicht mehr anzeigen.

    Beim Autoincrement war es noch naheliegend, die mit höchstens 5 Zeichen angenehm kurze ID in der Maske sichtbar darzustellen. Aber es ist ja viel eleganter, diese lange GUID gar nicht darzustellen, sondern bloß intern zu verwenden.

    Dem User steht ja immer noch seine editierbare "Eigene ID" zur Verfügung.

    Selbst wenn er da mal eine Dublette hinein setzt (und das Program das nicht abfängt), so würde das zumindest programmintern nichts ausmachen.

    - Im Gegenteil: Die Verwendung der GUID "unter der Haube" ermöglicht es dem User dann in für ihn nachvollziehbarer Weise, Kopien weitgehend identischer Datensätze anzulegen. Z. b. mit im Stamm identischer Bestellnummer, wo bloß die letzte Ziffer differiert.

    Im Moment geht es mir um die Verwaltung von Notebook-Mainboards.

    Später kommt noch ein Prüfgerät für Mainboards hinzu, das mit meinem Programm kommunizieren wird (ich repariere beruflich Notebooks und entwickle auch Geräte).

    Da kommt es oft vor, dass ein Mainboard anhand seiner aufgedruckten Mainboard-Bezeichnung nicht eindeutig identifiziert ist.

    Vielmehr gibt es noch unterschiedliche Bestückungsvarianten dieses Mainboards. Und davon wiederum mehrere Revisionsnummern.

    Da können durchaus schon mal 10 leicht unterschiedliche Mainboards existieren, die alle auf die selbe Bezeichnung hören ...

    Trotz identischem Notebook-Modell und identischer Mainboardbezeichnung, hätten die dann logischerweise abweichende elektrische Daten, die mein Testgerät natürlich allesamt im Detail kennen muss.

    Ergo legt man pro MB-Bezeichnung, pro Bestückungsvariante, pro Revisionsnummer, einen eigenen Datensatz an.

    Die können dann alle durchaus eine identische "Bestellnummer" haben, bzw. "Eigene ID", aber die elektrischen Daten weichen halt voneinander ab und da wird mein Testgerät penibel drauf reagieren.

    Es erscheint mir daher spontan sinnvoll, Deinem Vorschlag zu folgen und "unter der Haube" jedem Datensatz so eine GUID zu verpassen.

    - Auch wenn ich im Startposting noch darüber gejammert hatte, dass die ID möglichst nicht zu lang werden soll. Da hatte ich halt noch die "menschenlesbarkeit" im Visier.

    Istja sogar viel besser, die im Gegenteil heftig lang zu machen und auszublenden. Es würde die User eh nur überfordern, wenn jeder Datensatz mit zwei unterschiedlichen Arten von IDs daher käme, von denen eine sich ganz hartnäckig gegen jede Editierung sträubt. ;)

  • Datenbank dezentral erweitern [gelöst]

    • Code-Jack
    • 6. November 2018 um 21:26

    Danke, das klingt schon mal nach einem brauchbaren Ansatz.

    Bisher hatte ich dafür ein Feld "Datensatz amtlich - Ja/Nein" vorgesehen, um die "offiziellen" Datensätze von denen zu trennen, die die User selbst erstellt haben.

    Aber ich denke, Dein Vorschlag ist besser: Vom User selbst angelegte Datensätze kriegen nicht bloß so ein "inoffiziell"-Flag verpasst, sondern sie fließen in eine eigene Tabelle ein.

    Dadurch kann ich die offiziellen/inoffiziellen Datensatz-IDs sauber voneinander trennen und weiterhin mit Autoincrement arbeiten.

    Lädt dann ein User seine "Datenspende" auf meinen Server hoch (wird wohl einfach auf mein Forum hinauslaufen, per Dateianhang), dann muss anschließend entweder meine Wenigkeit himself, oder einer meiner Moderatoren, sich darum kümmern, die Plausibilität zu beäugeln und die neuen Datensätze (sofern dem Anschein nach OK) in die offizielle Tabelle einfließen zu lassen, wobei sie dann eine offizielle ID verpasst bekommen.

    Lädt der "Spender" später sporadisch mal wieder die volle Datenbank herunter, dann würde im besten Fall eine Dublettenerkennung seine Tabelle mit selbst erstellten Datensätzen leeren, denn die sind ja nun eh in der offiziellen DB vorhanden.


    Ich spiele ohnehin mit dem Gedanken, Datensätze im Normalfall nicht zu löschen, sondern ein quasi unendliches "Undo/Redo" zu ermöglichen, indem der alte Stand editierter Datensätze, sowie auch gelöschte, lediglich ausgeblendet werden.

    Halt ähnlich wie der Windows-Papierkorb, aus dem man alten Müll wieder hervorkramen kann, bis er explizit geleert wird.

    Bei jedem Editieren eines Datensatzes wird dann eine vollständige Kopie erzeugt, die in diesem Recycling-Müll landet, versehen mit einer Timestamp.

    Wenn ein User Daten "spendet", dann sorgt seine Exportfunktion dafür, dass nur die jeweils aktuelle Version hochgeladen wird.

    Und dass schon einmal exportierte Datensätze dabeiausgeklammert werden.

    - Wobei das auch wieder doof ist, denn schusselige User könnten mehrfach exportieren, editieren, exportieren ... und am Ende doch nur einmal hochladen.

    Aber irgendwie muss ich ja verhindern, dass Heini Schusselmann immer und immer wieder seine Datenspende hochlädt, sich seine Tabelle aber nie leert, weil er niemals die offizielle DB herunter lädt.

    Ich befürchte da einen Fulltime-Job für meine Moderatoren, die die offizielle Datenbank pflegen. :/

    Dummerweise enthält die Datenbank auch nicht nur Text, den man problemlos auf den ersten Blick für plausibel/unplausibel erachten könnte.

    Sondern sie enthält später auch Binärdaten aus Messreihen, mit denen dann ein elektronisches Testgerät gefüttert wird.

    Eben aus diesem Grund will ich ein "unendliches Undo/Redo" ermöglichen,

    Hat sich dann mal jemand seinen funktionstüchtigen Parametersatz zerschossen, entweder per eigenem Edit, oder per Update durch Import von "offiziellen Daten", dann sind die alten Stände der Datensätze noch vorhanden und können im Bedarfsfall reaktiviert werden.

    Vor einigen Jahren habe ich mal an der Entwicklung eines Gerätes mitgearbeitet, zusammen mit einem räumlich getrennten Kollegen. Der hatte dann einen SVN-Server aufgesetzt worüber wir unsere Dateien synchron hielten.

    Etwas unheimlich war mir das aber schon, denn erstens habe ich das Ding nie ganz verstanden, zweitens musste ich dazu auf meinem Rechner einen speziellen Ordner einrichten, der sich dann irgendwie mit dem SVN-Server synchronisierte.

    - Also solche Dinge möchte ich meinen Usern lieber nicht zumuten.

    Ich mag es am liebsten, wenn man auch ganz ohne Online-Zugang alles machen kann und im Bedarfsfall Dateien klassisch altmodisch tauscht, per E-Mail, oder über ein Forum. Nix mit Cloud (die habe ich noch NIE benutzt!) und möglichst nix mit SVN - es sei denn, man überzeugt mich von dessen unverzichtbarem Nutzen.

    Also vorzugsweise klassisch.

    Es soll nur nicht in eine Arbeitsbeschaffungsmaßnahme ausarten, für denjenigen, der die offizielle Datensammlung pflegt.

    Es wird hier aber so sein, dass die Masse der neuen Daten von den Usern kommen wird.

  • Datenbank dezentral erweitern [gelöst]

    • Code-Jack
    • 6. November 2018 um 17:36

    Mal eine rein konzeptionelle Frage:

    Ich habe mit AutoIt eine Datenverwaltung geschrieben.

    Die zugehörige, prall mit Inhalten gefüllte SQLite-Datenbank wird später mitgeliefert.

    Bisher arbeitete nur ich selbst mit Programm und Datenbank.

    Zu jedem neuen Eintrag erstellt SQLite bislang einfach eine fortlaufende Datensatz-ID, per Autoincrement.

    Zusätzlich zur automatisch generierten Datensatz-ID habe ich auch ein Feld "Eigene ID". Dort kann z. B. eine Art Bestellnummer eingetragen werden, die natürlich in der Praxis wiederum eindeutig ist und sich niemals wiederholt. Aber sie kann prinzipiell frei vergeben werden.

    Soweit der Ist-Stand (der so nicht unbedingt bleiben muss).

    Problem nun:

    Angenommen, rund um die Welt arbeiten künftig mehrere User mit meinem Programm und besagter Datenbank.

    Jeder User soll natürlich in seiner lokalen Datenbank (ohne Online-Verbindung) neue Datensätze hinzufügen können.

    Jeder spendierfreudige User soll seine Einträge aber auch mit den anderen Usern teilen können.

    - Also ein Export neu angelegter Datensätze, die andere User in ihren eigenen Datenbestand hinzu "mergen" können, ohne dass es dort zu Konflikten mit bereits bestehenden Einträgen kommen darf.

    Idealerweise sollte nach so einer Datensatz-Tausch-Aktion eine jede Datenbank eines jeden einzelnen Users die gleiche Anzahl Datensätze aufweisen (sofern jeder mitmacht).

    Und - das ist der Punkt - alle Datensätze sollten dann überall die gleiche ID haben (so jedenfalls meine hemmungslose Wunschvorstellung).

    Mir fällt als Lösungsansatz nur ein zentraler Server ein, der die Aktivitäten der User koordiniert und von sich aus überall eindeutige Datensatz-IDs vergibt.

    - Das möchte ich aber möglichst nicht! Aus folgenden drei Gründen:

    • Erstens empfinde ich das Verfahren als arg kompliziert (schwacher Grund, ich weiß).
    • Zweitens als nicht hinreichend ausfallsicher. Jeder Server kann schon morgen dicht machen.
    • Drittens mag ich es grundlegend nicht, wenn Software "nach Hause telefoniert".

    Die Frage lautet also, ob es einen irgendwie dezentralen Ansatz für diese Problemstellung gibt?

    Zum Beispiel der Art, dass jeder einzelne User "auf Antrag" einmalig eine (eindeutige) Art Namenskürzel zugeteilt bekommt, welches in die Datensatz-ID mit einfließt?

    Also nix mehr mit simplem Autoincrement in SQL, sondern komplexere IDs.

    Tatsächlich hätte so ein Namenskürzel was. Ich möchte es nämlich (pseudonymisiert) nachvollziehen können, welcher User welchen der untereinander geteilten Datensätze erstellt hat.

    Schon allein deshalb, um Vandalen ausklammern zu können, die den Datenbestand (den ich ja selbst nutze!)mit Murks-Einträgen voll müllen.

    Wirklich sicher vor Vandalen wäre man mit einer derart simplen Methode zwar nicht, aber es geht hier auch nicht um Hochsicherheitstechnik.

    Vorrangiges Ziel ist halt, dass User ihre selbst erstellten Datensätze "spenden" können und dass andere User solche "Spenden" zu ihrem lokalen Datenbestand hinzu "mergen" können, wobei die Datensatz-IDs überall, in jeder einzelnen Datenbank, gleich sein sollen.


    Mein Programm wird Freeware und mehrsprachig, es ist folglich kaum absehbar, wie viele User es weltweit mal geben wird.

    Ein Namenskürzel aus nur zwei Buchstaben/Zeichen könnte daher etwas kurz sein. Aber die Datensatz-ID soll ja auch nicht irre lang werden. Bei mehr als 10.000 Datensätzen ist sie ja jetzt schon fünf Zeichen lang.

    Es würde mich aber auch nerven, mich dauernd darum kümmern zu müssen, "auf Antrag" solche Kürzel an User schicken zu müssen. Zumal ich ja mal 'nen Unfall haben könnte etc. - die User sollen dann nicht im Regen stehen, sondern die Sache soll weiter laufen.

    Ich denke, für die geschilderte Problemstellung müsste es doch schon längst kluge Ansätze geben. Aber ich habe keine gute Idee, wie so ein Ansatz aussehen könnte.

    Wer weiß Rat?

  • GDI+ Spielerei

    • Code-Jack
    • 1. November 2018 um 13:15

    Ah, das erinnert mich an die gute alte Zeit, in den 90ern, als ich noch Lasereffektgeräte baute.

    Damals programmierte ich dann auch Simulationen solcher Geräte, noch auf den Atari, in GFA-Basic (schwelg in Nostalgie) ...

    Erstaunlicherweise läuft Deine Routine auf dem PC nicht schneller, als meine, damals auf dem Atari.

    Spontan würde ich vermuten, dass einer der Gründe dafür der ist, dass Deine vorausberechneten Werte $x[$i] und $y[$i] Vom Typ her Fließkommazahlen sind. Möglicherweise bremst das die eigentliche Zeichenroutine unnötig aus.

    Probiere doch mal, dort in den vorausberechneten Arrays ganzzahlige Werte zu erzwingen.

    Weiterer Verbesserungsvorschlag:

    Mache den Hintergrund schwarz und zeichne die Figur in leuchtend grellem Rot. Dann kommt das einem Lasereffektgerät schon viel näher,

    Und dann kann man noch eine nette Sache machen:

    Vorausgesetzt, Du kriegst die Zeichnerei noch deutlich beschleunigt, müssen die von der Zeichenfunktion gesetzten Pixel "ausfaden", so ca. eine knappe halbe Sekunde nachdem sie gesetzt wurden.

    Für das Ausfaden müsste in einer Schleife jeder einzelne Pixel bei jedem Durchlauf ein kleines Stückchen dunkler gestellt werden, bis am Ende Schwarz erreicht ist, wie bei der von mir vorgeschlagenen Hintergrundfarbe.

    Ein echtes Lasereffektgerät brutzelt ja auch nicht seine Spur fest in die damit angestrahlte Wand. Sondern dort wird nur ein Laserpunkt bewegt und im Auge stellt sich so ein verblassender Nachleuchteffekt ein, der es überhaupt erst ermöglicht, solche schönen Muster wahrzunehmen.

    Wenn das mit dem Ausfaden umgesetzt ist, dann wird es denkbar, die Figur zur Laufzeit zu beeinflussen, indem man mit der Maus Schieber betätigt.

    Und noch ein Vorschlag:

    Was mir damals bei den echten Geräten irgendwie den "Kick" gab, das war dieses Surren der Motoren.

    Meine Geräte arbeiteten mit vier Motoren und das was man sah, war unmittelbar das, was man auch hörte. Abgefahren!

    Besonders effektvoll war der Effekt dadurch, dass die Motoren trotz aller Stabilisierung nie zu 100% eine eingestellte Geschwindigkeit hielten. Da war immer etwas "Leben" im Spiel, in Form von "Schwebungen", was sich natürlich unmittelbar auf die Muster auswirkte und den dabei produzierten Sound.

    Es wäre daher eine Überlegung wert, noch per Zufallsgenerator etwas wohldosierte Ungenauigkeit mit ins Spiel zu bringen und weiterhin diesen ganzen Sinuskram in Töne zu verwandeln und an die Soundkarte zu schicken.

  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 1. November 2018 um 12:35

    OK, das ist natürlich ein Argument, dem ich nichts engegen setzen kann. ;)

    - Nun funktioniert es.

    Dein :rolleyes: ist somit voll berechtigt; ich setze mir ganz kleinlaut die Eselsmütze auf und schäme mich: <:-(

    Thema nun wirklich erledigt. Danke alpines! :thumbup:

  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 1. November 2018 um 03:42

    Jetzt gibt es noch eine kleine Unelegantheit ...

    Ich wollte es erreichen, dass die aus dem sichtbaren Tab gelöschte InputBox dort auch tasächlich sofort verschwindet, ohne dass man dazu erst manuell die Tabreiter umschalten müsste.

    _GUICtrlTab_SetCurSel() ist hier mein Freund, dachte ich ...

    Doch da gibt es eine Sonderbarkeit:

    Die Zeile 57 ist erforderlich, damit Zeile 58 ihren erwarteten Dienst tut. Komisch.

    Aber noch komischer: Die umgekehrte Richtung funzt gar nicht.

    Die Zeilen 74 bis 76 kann ich vertauschen und auskommentieren wie ich will - Tab 1 wird nicht selektiert.

    Dabei liefert mir ein testweise als 78. Zeile hintendran gehängtes:

    ConsoleWrite("Current Selection: " & _GUICtrlTab_GetCurSel($idTabCtrl))

    erwartungsgemäß Das Resultat "1".

    Trotzdem erfolgt keine Umschaltung auf Tab 1, wenn zuletzt Tab 2 aktiv war.

  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 1. November 2018 um 03:14

    Danke Bitnugger!

    Der Vollständigkeit halber, falls es anderen Usern hilft, hier noch der lauffähige Code:

    AutoIt
    #include <GUIConstantsEx.au3>
    #include <GuiTab.au3>
    
    Global $hGUIParent1 = GUICreate("Parent1", 600, 400)
    Global $idTabCtrl
    Global $idTabItem1
    Global $idTabItem2
    
    Example()
    GUIDelete($hGUIParent1)
    
    Func Example()
    
        Local $InhaltInputBox3
    
        $Button1 = GUICtrlCreateButton("Move Inputbox in Tab 2", 350, 10, 200, 50)
        $Button2 = GUICtrlCreateButton("Move Inputbox in Tab 1", 350, 70, 200, 50)
    
    
        $idTabCtrl = GUICtrlCreateTab(10, 40, 300, 300)
        $idTabItem1 = GUICtrlCreateTabItem("tab1")
        Local $idInput2 = GUICtrlCreateInput("Ich möchte moven!", 50, 150, 200, 30)
        $idTabItem2 = GUICtrlCreateTabItem("tab2")
        GUICtrlCreateTabItem("")
    
    
        GUISetState(@SW_SHOW)
    
        ; Loop until the user exits.
        While 1
          Switch GUIGetMsg()
             Case $GUI_EVENT_CLOSE
               ExitLoop
    
          Case $Button1
             $idInput2 = _MoveToTab2($idInput2)
    
          Case $Button2
             $idInput2 = _MoveToTab1($idInput2)
    
            EndSwitch
        WEnd
    
    EndFunc   ;==>Example
    ;############################################################
    Func _MoveToTab2($id)
       Local $idNeueID
       Local $InhaltInputBox = GUICtrlRead($id)            ;Inhalt der gleich zu löschenden InputBox auslesen.
       Local $PositionInputBox = ControlGetPos($hGUIParent1, 'Parent1', $id)
       Local $StatusInputBox = GUICtrlGetState($id)
    
       GUICtrlDelete($id)
       GUISwitch($hGUIParent1, $idTabItem2)
       $idNeueID = GUICtrlCreateInput($InhaltInputBox, 1, 1)
       GUICtrlSetPos($idNeueID, $PositionInputBox[0], $PositionInputBox[1])
       GUICtrlSetState($idNeueID, $StatusInputBox)
       _GUICtrlTab_SetCurSel($idTabCtrl, 1)
       _GUICtrlTab_SetCurSel($idTabCtrl, 2)
    
       Return($idNeueID)
    EndFunc  ;==> MoveToTab2
    ;############################################################
    Func _MoveToTab1($id)
       Local $idNeueID
       Local $InhaltInputBox = GUICtrlRead($id)            ;Inhalt der gleich zu löschenden InputBox auslesen.
       Local $PositionInputBox = ControlGetPos($hGUIParent1, 'Parent1', $id)
       Local $StatusInputBox = GUICtrlGetState($id)
    
       GUICtrlDelete($id)
       GUISwitch($hGUIParent1, $idTabItem1)
       $idNeueID = GUICtrlCreateInput($InhaltInputBox, 1, 1)
       GUICtrlSetPos($idNeueID, $PositionInputBox[0], $PositionInputBox[1])
       GUICtrlSetState($idNeueID, $StatusInputBox)
      ; _GUICtrlTab_SetCurSel($idTabCtrl, 1)
       _GUICtrlTab_SetCurSel($idTabCtrl, 2)
       _GUICtrlTab_SetCurSel($idTabCtrl, 1)
    
       Return($idNeueID)
    EndFunc  ;==> MoveToTab1
    
    
    ;Siehe Hilfedatei: _GUICtrlTab_SetCurSel
    Alles anzeigen
  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 1. November 2018 um 02:26

    Hmm, doch noch watt:

    Mir fehlt zum vollendeten Glück noch der Befehl zum Auslesen der Koordinaten der zu löschenden InputBox.

    Ich habe den Code mal entrümpelt und zwei Buttons plus Functions spendiert, um die InputBox gezielt in einen bestimmten Tab zu "verschieben".

    Das funktioniert auch, nur gehen mir die Koordinaten hops.

    Ich brauche das Gegenstück zu GUICtrlSetPos()

    AutoIt
    #include <GUIConstantsEx.au3>
    
    Global $hGUIParent1 = GUICreate("Parent1", 600, 400)
    Global $idTabItem1
    Global $idTabItem2
    
    Example()
    GUIDelete($hGUIParent1)
    
    Func Example()
    
        Local $InhaltInputBox3
    
        $Button1 = GUICtrlCreateButton("Move Inputbox in Tab 2", 350, 10, 200, 50)
        $Button2 = GUICtrlCreateButton("Move Inputbox in Tab 1", 350, 70, 200, 50)
    
    
        GUICtrlCreateTab(10, 40, 300, 300)
        $idTabItem1 = GUICtrlCreateTabItem("tab1")
        Local $idInput2 = GUICtrlCreateInput("Ich möchte moven!", 50, 150, 200, 30)
        $idTabItem2 = GUICtrlCreateTabItem("tab2")
        GUICtrlCreateTabItem("")
    
    
        GUISetState(@SW_SHOW)
    
        ; Loop until the user exits.
        While 1
          Switch GUIGetMsg()
             Case $GUI_EVENT_CLOSE
               ExitLoop
    
          Case $Button1
             $idInput2 = _MoveToTab2($idInput2)
    
          Case $Button2
             $idInput2 = _MoveToTab1($idInput2)
    
            EndSwitch
        WEnd
    
    EndFunc   ;==>Example
    ;############################################################
    Func _MoveToTab2($id)
       Local $idNeueID
       Local $InhaltInputBox = GUICtrlRead($id)            ;Inhalt der gleich zu löschenden InputBox auslesen.
       ;Local $PositionInputBox =                          ;Hier fehlt mir der Befehl zum auslesen der Koordinaten!
       Local $StatusInputBox = GUICtrlGetState($id)
    
       GUICtrlDelete($id)
       GUISwitch($hGUIParent1, $idTabItem2)
       $idNeueID = GUICtrlCreateInput($InhaltInputBox, 1, 1)
       ;GUICtrlSetPos($idNeueID, 40, 160)
       GUICtrlSetState($idNeueID, $StatusInputBox)
       Return($idNeueID)
    EndFunc  ;==> MoveToTab2
    ;############################################################
    Func _MoveToTab1($id)
       Local $idNeueID
       Local $InhaltInputBox = GUICtrlRead($id)            ;Inhalt der gleich zu löschenden InputBox auslesen.
       ;Local $PositionInputBox =                          ;Hier fehlt mir der Befehl zum auslesen der Koordinaten!
       Local $StatusInputBox = GUICtrlGetState($id)
    
       GUICtrlDelete($id)
       GUISwitch($hGUIParent1, $idTabItem1)
       $idNeueID = GUICtrlCreateInput($InhaltInputBox, 1, 1)
       ;GUICtrlSetPos($idNeueID, 40, 160)
       GUICtrlSetState($idNeueID, $StatusInputBox)
       Return($idNeueID)
    EndFunc  ;==> MoveToTab1
    Alles anzeigen
  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 1. November 2018 um 00:25

    Funzt!

    Großartig, alpines, vielen Dank!

    Ich setzte das Thema gleich mal auf erledigt. :)

  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 31. Oktober 2018 um 23:35

    Danke für den superschnellen Rat, alpines! Allerdings klemmt es noch ...

    Ich kriege das Beispiel nicht so umgefrickelt, dass es das tut, was ich möchte. Also eine bereits existierende Inputbox innerhalb des selben Fensters in/aus einem Tab verschieben.

    Ich habe das Codebeispiel mal so geändert, dass es klarer wird, was ich vorhabe.

    AutoIt
    #include <GUIConstantsEx.au3>
    
    Example()
    
    Func Example()
        Local $hGUIParent1 = GUICreate("Parent1")
    
        Local $idInput1 = GUICtrlCreateInput("Ich möchte in den ersten Tab!", 50, 10, 200, 20)
    
    
        GUICtrlCreateTab(10, 40, 300, 300)
        Local $idTabItem1 = GUICtrlCreateTabItem("tab1")
        Local $idInput2 = GUICtrlCreateInput("Ich möchte in den zweiten Tab!", 50, 150, 200, 20)
        Local $idTabItem2 = GUICtrlCreateTabItem("tab2")
        GUICtrlCreateTabItem("")
    
        Local $idInput3 = GUICtrlCreateInput("Auch ich möchte in den ersten Tab!", 60, 350, 200, 20)
    
    
        ;GUISwitch($hGUIParent2)
        GUISetState(@SW_SHOW)
    
        ; Loop until the user exits.
        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    ExitLoop
    
            EndSwitch
        WEnd
    
    #cs
        Local $hGUIParent2 = GUICreate("Parent2", -1, -1, 100, 100)
    
    
        GUISwitch($hGUIParent1, $idTabItem1)
        GUICtrlCreateButton("OK", 50, 50, 50)
        GUICtrlCreateTabItem("")
    
        GUISetState(@SW_SHOW, $hGUIParent1)
        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    ExitLoop
            EndSwitch
        WEnd
    
    
    #ce
        GUIDelete($hGUIParent1)
       ; GUIDelete($hGUIParent2)
    EndFunc   ;==>Example
    Alles anzeigen
  • Editbox nachträglich in TabControl verschieben

    • Code-Jack
    • 31. Oktober 2018 um 22:48

    Frage: Ist es möglich, eine Editbox (oder Label, oder sonst ein Control) nachträglich in ein bereits kreiertes TabControl zu verfrachten?

    RTFM offenbarte mir dazu keine Möglichkeit.

    Wozu das gut sein soll?

    - Nun, der User soll das GUI zur Laufzeit umgestalten können. In gewissen Grenzen zumindest.

    Meine Oberfläche hat inzwischen so viele Inputboxen, dass ich gezwungen war, diese zum Teil (aber auch nur zum Teil) in TabControls zu verstauen.

    Deren Anordnung mag dem User aber nicht unbedingt schmecken. Er soll es daher selbst festlegen können, ob eine bestimmte Editbox in einem Tab sitzt, oder nicht. Und wenn ja, dann in welchem.

    Wer weiß Rat?

  • Alinas_SQLite_BuchVw

    • Code-Jack
    • 25. Oktober 2018 um 01:32
    Zitat von autoiter

    Ich bin sicher, dein Problem ist gar nicht so groß- Schau dir einfach mal SQLite-Tutorials an.

    Waah, dessen bin ich mir auch sicher! Und ich habe ausgiebig Tutorials gewälzt, trotzdem klappte es partout nicht.

    Nach ungefähr 15 Stunden kauen an diesem kleinen Problem war ich dann doch so weit, mal im Forum zu fragen.

    Aaaber - Tadaaa! - ich habe es inzwischen selbst geschaft! :party:

    Der User TheLaBu hat im folgenden Thread ein Beispiel gebracht, das ich erfolgreich abwandeln konnte:

    SQL-Ergebnis als Variable speichern

    Der aktualisierte Quelltext hängt noch einmal an, falls einem Anderen mal nützlich sein könnte.

    In dieser Form ist das Programm nämlich schon recht nahe an der ersten Brauchbarkeit (obwohl noch dick Baustelle).

    Trotzdem Danke für Deine Meldung. Ich habe schon viel aus Deinen anderen Postings gelernt!

    Dateien

    Reparaturverwaltung V0.35.au3 66,84 kB – 622 Downloads
  • Alinas_SQLite_BuchVw

    • Code-Jack
    • 24. Oktober 2018 um 23:09

    Nach zwei Jahren Abstinenz kramte ich den Quellcode endlich mal wieder hervor.

    Damals wuchs mir die Sache über den Kopf, dabei bräuchte ich das Programm eigentlich täglich ...

    - Jetzt brauche ich es aber wirklich definitiv und nicht mehr aufschiebbar!


    Aktuell scheitert es an einer simplen Sache:

    Ich möchte, wenn ein Datensatz editiert werden soll, die ganzen Inputboxen nicht mehr aus der ListView befüllen (wie einst im Ursprungs-Quelltext), sondern direkt aus der eigentlichen Quelle, also der SQLite-Datenbank.

    Grund: Die ListView soll später nur noch die relevanten Datenfelder darstellen. Der zu editierende Datensatz ist also umfangreicher, als das, was man in der ListView sieht.

    Es würde mir schon riesig helfen, wenn man mir auf die Sprünge helfen könnte, wie ich aus der Datenbanktabelle ein einzelnes Feld auslesen kann, anhand des Wertes in der Spalte "ID". Dann würde ich den Rest selbst schaffen.

    Seit gestern grase ich deswegen das Forum durch, probiere Beispiele aus, folge diversen Links auf SQL-Erklärbär-Seiten ... doch alle Beispiele bringen nicht das, was ich will, sind viel zu komplex und vergrößern meine Verwirrung nur.

    Anbei der gesamte Quelltext.

    Die Routine, die es bringen soll, ist in Zeile 659: "Func _Datensatz2Inputboxes"

    Wie man sieht, ist die Routine inzwischen vollständig zu Klump gemüllt, von den vielen dutzend erfolglosen Tests.

    Frage also: Wie kriege ich einen einzelnen Feldinhalt der Datenbank (definiert anhand der ID des in der ListView selektierten Datensatzes) ausgelesen, um ihn einer InputBox zuzuweisen?

    Dateien

    Reparaturverwaltung V0.33.au3 66,55 kB – 533 Downloads
  • Alinas_SQLite_BuchVw

    • Code-Jack
    • 2. Januar 2017 um 16:20

    Boah, ist der Kanashius schnell!
    Man kann hier wirklich nur den Hut ziehen, vor den hoch kompetenten und überaus hilfsbereiten Usern, echt!
    Großartige Leute hier, beide Daumen hoch!

    stefanwue:
    Obige Version ist noch eine recht frühe Baustelle.
    Ich habe das Programm seither ein gutes Stück weiter entwickelt. wichtig war es mir, dass man die Maske jederzeit vom Programm aus, per Maus, umgestalten kann.
    Dass die Daten für die Maskengestaltung also nicht fest im Quelltext codiert sind, sondern aus einer Ini-Datei eingelesen werden.

    Ist nie ganz fertig geworden und die aktuelle Version ist noch immer nicht wirklich einsetzbar (hat auch noch Fehler), aber ich hänge dennoch mal meinen letzten Stand an, weil sich da doch sehr viel getan hat.


    AutoIt
    ; output.code.page=65001  ;Deutsche Umlaute ermöglichen. Klappt dennoch nur manchmal ...
    #Region Header #################################################################################################################\
    ; Erstellt mit AutoIt-Version v3.3.14.2
    
    
    Global Const $sProgrammname = "Reparaturverwaltung"
    Global Const $sVersion = "0.32"
    Global Const $sRevisionsdatum = "11.06.2016"
    Global Const $sAutor = "EDV-Dompteur, Stefan Denk"
    Global Const $sWebsite = "http://www.EDV-Dompteur.de"
    
    
    ; --- P r o g r a m m b e s c h r e i b u n g -----------------------------------------------------------------------------\
    Global Const $sAbout = "Programmname: " & $sProgrammname & @CRLF & "Version: " & $sVersion & @CRLF & "Autor: " & $sAutor & @CRLF & "Website: " & $sWebsite & @CRLF _
    & @CRLF & "P r o g r a m m b e s c h r e i b u n g" _
    & @CRLF & "---------------------------------------" _
    & @CRLF & "Die hier vorliegende Software ist Freeware, also zur kostenlosen Nutzung freigegeben!" _
    & @CRLF & "Das Programm dient kleinen Reparaturbetrieben dazu, den Überblick über ihre ausgeführten Arbeiten zu behalten." _
    & @CRLF & "Die Details einer jeden Reparatur werden in einem eigenen Datensatz einer SQLite-Datenbank gespeichert." _
    & @CRLF & "Eine Übersicht, in Form einer frei sortierbaren Liste, ermöglicht es rasch nach Datum, Kunde, Gerät etc. zu sortieren."
    ; --- P r o g r a m m b e s c h r e i b u n g -----------------------------------------------------------------------------/
    
    
    ; --- History -------------------------------------------------------------------------------------------------------------\
    Global Const $sHistory = "" _
    & @CRLF & "D a n k s a g u n g:" _
    & @CRLF & "----------------------" _
    & @CRLF & "Die Code-Vorlage, auf der dieses Programm aufbaut, stammt vom User ""RR04"", aus dem großartigen Forum www.AutoIt.de" _
    & @CRLF & "Hier der Foren-Thread mit der Ursprungsversion:" _
    & @CRLF & "https://autoit.de/index.php/Thread/83862-Alinas-SQLite-BuchVw/" _
    & @CRLF & "Vielen Dank an ""RR04"", für die tolle Vorarbeit, die mir sicherlich mehrere Tage Arbeit erspart hat!" _
    & @CRLF _
    & @CRLF & "Weiterhin enthält das Programm einzelne Routinen von ""BugFix"" (bugfix@autoit.de)" _
    & @CRLF & "Vielen Dank daher auch an ""BugFix""!" _
    & @CRLF & "" _
    & @CRLF & "Vielen Dank auch an ""autoBert"", für die gezielte Hilfe bei einer bestimmten Problemlösung!" _
    & @CRLF & "" _
    & @CRLF & "Ab hier beginnen nun die Änderngen und Erweiterungen durch Fa. EDV-Dompteur, Stefan Denk:" _
    & @CRLF _
    & @CRLF & "H i s t or y:" _
    & @CRLF & "-------------" _
    & @CRLF & "V0.01 vom 28.05.2016:" _
    & @CRLF & "- Programm umbenannt und erste Umgestaltungen der Quelltext-Vorlage von RR04." _
    & @CRLF & "- Programmbeschreibung und History im Quelltext-Header implementiert; derart, dass auch eine Ausgabe dieser Texte möglich wird." _
    & @CRLF & "- Die Tabelle wird nun bei Programmstart automatisch mit Datensätzen gefüllt (wenn DB noch nicht vorhanden, wird sie zuvor erzeugt)." _
    & @CRLF _
    & @CRLF & "V0.06 vom 29.05.2016:" _
    & @CRLF & "- Der ListView-Header ist nun eine Variable, zwecks späterer Möglichkeit zum Einlesen aus einer ini-Datei." _
    & @CRLF & "- Die Beispiel-Datensätze der usprünglichen Reparaturverwaltung umgestrickt auf die Belange einer Reparaturverwaltung." _
    & @CRLF & "- Die Feldbezeichner der SQL-Datenbank verallgemeinert, zwecks leichterer Modifizierbarkeit." _
    & @CRLF & "- Neue Datenfelder definiert: Projektordner, Gesprächsnotiz, Reparaturbericht." _
    & @CRLF & "- Bugfix: Nach dem letzten Quelltext-Umbau wurden Datensätze nicht mehr aktualisiert, nach entsprechender Button-Betätigung." _
    & @CRLF & "- Programmbeschreibung und History werden jetzt mit Zeilenumbrüchen formatiert ausgegeben." _
    & @CRLF & "- Bugfix: Datenfeld 20 wurde nicht mit aktualisiert, nach dem Editieren eines Datensatzes." _
    & @CRLF & "- Menüleiste hinzugefügt. Funktionen: Exit, Programminfo, History (der Menüzweig ""Einstellungen"" ist noch ohne Funktion)." _
    & @CRLF & "- Listview: Spaltenbreiten und Textausrichtung eingestellt. Erste Vorbereitung für späteres Laden der Werte aus ini-Datei." _
    & @CRLF _
    & @CRLF & "V0.20 vom 04.06.2016:" _
    & @CRLF & "- Harmloser Bugfix: Die Einstellmöglichkeit für die Breite von ListView-Spalte 20 fehlte im Quellcode." _
    & @CRLF & "- Anzahl der Datenfelder von 20 auf 30 erhöht. Dadurch GUI-Erscheinungsbild derzeit desolat" _
    & @CRLF & "- Momentan überflüssige Felder auskommentiert und Befehl zum Verstecken von ListView-Spalten implementiert." _
    & @CRLF & "- Vorbereitungen für späteres Laden der GUI-Parameter aus einer Datei." _
    & @CRLF & "- Elegantere Methode zur GUI-Gestaltung implementiert, für späteres Laden aus Datei." _
    & @CRLF & "- Alle InputBoxen sind nun bequem parametrierbar, voll vorbereitet für späteres Laden aus CSV-Datei." _
    & @CRLF & "- Zu jeder Inputbox gehört nun ein Label, deren Ausrichtung ebenfalls bequem einstellbar ist." _
    & @CRLF & "- Die Maus-Koordinaten werden jetzt erfasst und links in der Fußzeile angezeigt." _
    & @CRLF _
    & @CRLF & "V0.25 vom 07.06.2016:" _
    & @CRLF & "- Auch das Suchfeld kann nun einfach parametriert werden." _
    & @CRLF & "- Experimentell eine Groupbox hinzugefügt." _
    & @CRLF & "- Auch Groupboxen können nun einfach parametriert werden." _
    & @CRLF & "- Statusleiste am unteren Fensterrand debugt und erweitert. Jetzt perfekt." _
    & @CRLF & "- Inputboxen lassen sich jetzt erstmals anstazweise per Maus verschieben (noch reichlich buggy)." _
    & @CRLF & "- Fehler beseitigt bei den Koordinaten der Objekt-Label. Nun auch bei Editbox in Ordnung." _
    & @CRLF & "- Absturzfehler beseitigt (trat auf bei Klick außerhalb des Fensters): Mauspositionen werden nun durch MouseGetPos ermittelt, statt durch GUIGetCursorInfo." _
    & @CRLF & "- Hintergrundbild für das Hauptfenster implementiert." _
    & @CRLF & "- Der Modus zum Umgestalten des GUI kann nun per Menü aktiviert/deaktiviert werden." _
    & @CRLF & "- Bug bemerkt: Inputboxen und ListView nicht betretbar, wenn Hintergrundbild geladen." _
    & @CRLF _
    & @CRLF & "V0.26 vom 08.06.2016:" _
    & @CRLF & "- Die Bildschirmmaske kann nun weitgehend per Maus umgestaltet werden. Noch nicht perfekt, aber bereits brauchbar." _
    & @CRLF _
    & @CRLF & "V0.27 vom 08.06.2016:" _
    & @CRLF & "- Das Verschieben von GUI-Elementen klappt nun perfekt und schließt jetzt auch deren angeheftete Labels mit ein." _
    & @CRLF _
    & @CRLF & "V0.28 vom 08.06.2016:" _
    & @CRLF & "- Es wird jetzt eine Ini-Datei erzeugt, mit den GUI-Parametern. Noch Arbeitsbedarf, anschließendes Einlesen schlägt fehl!" _
    & @CRLF _
    & @CRLF & "V0.29 vom 10.06.2016:" _
    & @CRLF & "- Kosmetik an der Maske und am Quelltext." _
    & @CRLF _
    & @CRLF & "V0.30 vom 10.06.2016:" _
    & @CRLF & "- Fehlerchen beseitigt beim Verschieben von GUI-Elementen: Klickte der Mauszeiger außerhalb verschiebbarer Objekte, so sprang das zuletzt ""überhoverte"" Element plötzlich zum Mauszeiger." _
    & @CRLF & "- Datenbank-Import ins Menü eingebaut. Derzeit nur mit Anzeige der zu importierenden Daten, aber noch ohne tatsächlichen Import." _
    & @CRLF & "- Bug beseitigt: Auch bei geladenem Hintergrundbild sind InputBox-Inhalte nun betret- und editierbar." _
    & @CRLF _
    & @CRLF & "V0.31 vom 11.06.2016:" _
    & @CRLF & "- Importfunktion jetzt funktionstüchtig!" _
    & @CRLF _
    & @CRLF & "V0.32 vom 11.06.2016:" _
    & @CRLF & "- "
    ; --- History -------------------------------------------------------------------------------------------------------------/
    
    
    ; --- Aktuelle Aufgaben ---------------------------------------------------------------------------------------------------\
    Global Const $sProgrammieraufgaben = "" _
    & @CRLF & "Folgende drei Darstellungsmodi implementieren: Kombi (Tabelle und Datensatz, wie gehabt), Tabelle (volle Größe), Datensatz (ohne Tabelle)" _
    & @CRLF & "Laden/Speichern der GUI-Parameter aus/in einer ini-Datei vervollständigen." _
    & @CRLF & "Suchfunktion derzeit nicht funktionstüchtig." _
    & @CRLF & "BUG BESEITIGEN: NAch Anwahl des Buttons ""Neuer Datensatz"" verschwindet die Beschriftung der Groupbox." _
    & @CRLF & "Verhindern, dass beim Verschieben von GUI-Elementen der Cursor die angewählte InputBox zugleich im Editiermodus betritt."
    ; --- Aktuelle Aufgaben ---------------------------------------------------------------------------------------------------/
    
    
    #include <Array.au3>
    ;
    #include <ComboConstants.au3>
    ;
    #include <Date.au3>
    ;
    #include <EditConstants.au3>
    ;
    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    ;
    #Include <Misc.au3>
    ;
    #include <StaticConstants.au3>   ;Erweiterte Einstellungen für Labels
    #include <String.au3>
    #include <SQLite.au3>
    #include <sqlite3101_dll.au3>
    ;
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>
    
    
    ;--------------
    
    
    #include <ButtonConstants.au3>
    #include <ListviewConstants.au3>
    #include <SliderConstants.au3>
    #include <File.au3>
    _GDIPlus_Startup()
    #EndRegion Header ##############################################################################################################/
    
    
    #Region Constanten & Variablen deklarieren und belegen #########################################################################\
    ; --- Globale Constanten deklarieren --------------------------------------------------------------------------------------\
    Global Const $asWDAYger[7] = ["Sonntag, ", "Montag, ", "Dienstag, ", "Mittwoch, ", "Donnerstag, ", "Freitag, ", "Samstag, "]
    ; --- Globale Constanten deklarieren --------------------------------------------------------------------------------------/
    
    
    ; --- Globale Variablen deklarieren ---------------------------------------------------------------------------------------\
    Opt("MustDeclareVars", 1) ;Zwingt den Programmierer, Variablen ordentlich zu deklarieren, vor der ersten Benutzung.
    Global $cboSerch, $iptSerch, $FormKombiansicht, $Label, $ListView, $ContextMenu, $MenuItem, $btnUpdate, $btnDelete, $iptSearch
    Global $cboSearch, $btnSearch, $btnDBladen, $btnClear, $lblBottomLine, $btnNeuerDatensatz, $btnBackUp, $Result
    Global $sTmp, $sText, $i
    Global $sListViewHeader, $iDBFeldanzahl
    Global $hGUI, $hImage1, $hImage2, $aMousePos
    Global $sUserMessageOld, $sUserMessageNew
    Global $bGUIRedesign
    Global $iDoItOnlyOnce = 0
    Global $aiGUIElementXYWH
    Global $hActualGUIElement, $hActualLabel, $iActualGUINumber
    Global $iXOffsetGUIElementToMouse, $iYOffsetGUIElementToMouse
    Global $aiGUILabelXYWH
    
    
    Opt("MouseCoordMode", 0)
    Global $iPressed = 0, $iLastCtrlID = -1
    ; --- Globale Variablen deklarieren ---------------------------------------------------------------------------------------/
    
    
    ; ---Globale Variablen mit Werten belegen ---------------------------------------------------------------------------------\
    Global $sIniFilename = @ScriptDir & "\GUI.ini"
    Global $sDatenbankVollpfad = @ScriptDir & "\Reparaturverwaltung.rr04"
    $iDBFeldanzahl = 30  ;So viele Felder gibt es in der Datenbank
    ; ---Globale Variablen mit Werten belegen ---------------------------------------------------------------------------------/
    #EndRegion Constanten & Variablen deklarieren und belegen ######################################################################/
    
    
    #Region Bedienoberfläche zeichnen ##############################################################################################\
    ; --- Fenster & Menü erzeugen-----------------------------------------------------------\
    Global $FormKombiansicht = GUICreate($sProgrammname, 1200, 768, 10, 10)  ;Das Hauptfenster erzeugen.
    GUICtrlCreatePic(@ScriptDir & '\Example Images\background.jpg', 0, 0, 1200, 768)
    GUICtrlSetState(-1, $GUI_DISABLE)  ;Verfrachtet das eben erzeugte bild in den Hintergrund (andernfalls wären Inputboxen nicht betretbar).
    
    
    ; --- Menüzweig 1 ------------------------------------------------------------\
    Global $MenuA = GUICtrlCreateMenu("Datei")
    Global $MenuItemDBImport = GUICtrlCreateMenuItem("Datenbank importieren", $MenuA)
    Global $MenuItemAExit = GUICtrlCreateMenuItem("Schließen", $MenuA)
    ; --- Menüzweig 1 ------------------------------------------------------------/
    
    
    ; --- Menüzweig 2 ------------------------------------------------------------\
    Global $MenuB = GUICtrlCreateMenu("Einstellungen")
    Global $MenuItemOptionen = GUICtrlCreateMenuItem("Maske umgestalten", $MenuB)
    ; --- Menüzweig 2 ------------------------------------------------------------/
    
    
    ; --- Menüzweig 3 ------------------------------------------------------------\
    Global $MenuC = GUICtrlCreateMenu("?")
    Global $MenuItemCProgramminfo = GUICtrlCreateMenuItem("Programminfo", $MenuC)
    Global $MenuItemCHistory = GUICtrlCreateMenuItem("History && Danksagung", $MenuC)
    ; --- Menüzweig 3 ------------------------------------------------------------/
    GUISetState(@SW_SHOW)   ;??? Was macht dieser Befehl?
    ; --- Fenster & Menü erzeugen-----------------------------------------------------------/
    
    
    ; --- Programmname darstellen ----------------------------------------------------------\
    ;$Label = GUICtrlCreateLabel("~ ~ ~ " & $sProgrammname & " Version: " & $sVersion & " ~ ~ ~", 0, 8, 1125, 28, 0x01) ; $SS_CENTER=0x01
    ;GUICtrlSetFont(-1, 16, 800, 0, "Arial")
    ;GUICtrlSetColor(-1, 0x0000FF)
    ; --- Programmname darstellen ----------------------------------------------------------/
    
    
    ; --- Liestview aufbauen --------------------------------------------------------------------------------------------------\
    ; ---- Headerzeile der ListView --------------------------------------------------------\
    $sListViewHeader= "" _
    & "ID" _
    & "|Annahme" _
    & "|Abholung" _
    & "|Gerät" _
    & "|Schadenskürzel" _
    & "|Firma" _
    & "|Vorname" _
    & "|Nachname" _
    & "|Endpreis" _
    & "|Re-Nr." _
    & "|Anzahl." _
    & "|Leihteile" _
    & "|Voranschlag" _
    & "|Rekla" _
    & "|Projektordner" _
    & "|Gesprächsnotiz" _
    & "|Reparaturbericht" _
    & "|17" _
    & "|18" _
    & "|19" _
    & "|20" _
    & "|21" _
    & "|22" _
    & "|23" _
    & "|24" _
    & "|25" _
    & "|26" _
    & "|27" _
    & "|28" _
    & "|29" _
    & "|30"
    ; ---- Headerzeile der ListView --------------------------------------------------------/
    
    
    ; --- Listwiew erzeugen ----------------------------------------------------------------\
    Global $aHeader = StringSplit($sListViewHeader, '|')
    $ListView = GUICtrlCreateListView($sListViewHeader, 0, 40, 1125, 260)
    GUICtrlSetBkColor(-1, 0xFFFFFF) ; Color weiß
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
    GUICtrlSetFont(-1, 10, 400, 0, "Arial")
    ; --- Listwiew erzeugen ----------------------------------------------------------------/
    
    
    ; --- Spaltenbreiten und Textausrichtung der Listview-Spalten festlegen ----------------\
    Global $GetHandleLV = GUICtrlGetHandle($ListView)
    _GUICtrlListView_SetColumn($GetHandleLV, 0, $aHeader[1], 40, 1)    ;ID
    _GUICtrlListView_SetColumn($GetHandleLV, 1, $aHeader[2], 80, 0)    ;Annahmedatum
    _GUICtrlListView_SetColumn($GetHandleLV, 2, $aHeader[3], 70, 0)    ;Abholdatum
    _GUICtrlListView_SetColumn($GetHandleLV, 3, $aHeader[4], 120, 0)   ;Gerät
    _GUICtrlListView_SetColumn($GetHandleLV, 4, $aHeader[5], 100, 0)   ;Schadenskürzel
    _GUICtrlListView_SetColumn($GetHandleLV, 5, $aHeader[6], 110, 0)   ;Firma
    _GUICtrlListView_SetColumn($GetHandleLV, 6, $aHeader[7], 110, 1)   ;Vorname
    _GUICtrlListView_SetColumn($GetHandleLV, 7, $aHeader[8], 110, 0)   ;Nachname
    _GUICtrlListView_SetColumn($GetHandleLV, 8, $aHeader[9], 60, 1)    ;Endpreis
    _GUICtrlListView_SetColumn($GetHandleLV, 9, $aHeader[10], 60, 1)   ;Rechnungsnummer
    _GUICtrlListView_SetColumn($GetHandleLV, 10, $aHeader[11], 60, 1)  ;Anzahlung
    _GUICtrlListView_SetColumn($GetHandleLV, 11, $aHeader[12], 150, 0) ;Leihteile
    _GUICtrlListView_SetColumn($GetHandleLV, 12, $aHeader[13], 60, 1)  ;Voranschlag
    _GUICtrlListView_SetColumn($GetHandleLV, 13, $aHeader[14], 70, 0)  ;Reklamation (Verknüpfung auf neuen Datensatz)
    _GUICtrlListView_SetColumn($GetHandleLV, 14, $aHeader[15], 100, 0) ;Projektordner
    _GUICtrlListView_SetColumn($GetHandleLV, 15, $aHeader[16], 100, 0) ;Gesprächsnotiz
    _GUICtrlListView_SetColumn($GetHandleLV, 16, $aHeader[17], 100, 0) ;Reparaturbericht
    _GUICtrlListView_SetColumn($GetHandleLV, 17, $aHeader[18], 40, 0)  ;Festnetz
    _GUICtrlListView_SetColumn($GetHandleLV, 18, $aHeader[19], 40, 0)  ;Mobil
    _GUICtrlListView_SetColumn($GetHandleLV, 19, $aHeader[20], 40, 0)  ;E-Mail
    _GUICtrlListView_SetColumn($GetHandleLV, 20, $aHeader[21], 80, 0)  ;Status (In Arbeit / Abholbereit / Abgeholt)
    _GUICtrlListView_SetColumn($GetHandleLV, 21, $aHeader[22], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 22, $aHeader[23], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 23, $aHeader[24], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 24, $aHeader[25], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 25, $aHeader[26], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 26, $aHeader[27], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 27, $aHeader[28], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 28, $aHeader[29], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 29, $aHeader[30], 40, 0)  ;
    _GUICtrlListView_SetColumn($GetHandleLV, 30, $aHeader[31], 40, 0)  ;
    ; --- Spaltenbreiten und Textausrichtung der Listview-Spalten festlegen ----------------/
    
    
    $ContextMenu = GUICtrlCreateContextMenu($ListView)
    $MenuItem = GUICtrlCreateMenuItem("Datensatz bearbeiten", $ContextMenu)
    ; --- Liestview aufbauen --------------------------------------------------------------------------------------------------/
    
    
    ; --- Main Area -----------------------------------------------------------------------------------------------------------\
    ; --- Buttons, Labels und Inputfelder erzeugen -----------------------------------------------------------------------\
    Global $iAnzahlGUIElemente = 24  ;Später ändern, wenn aus Datei eingelesen!!!
    Global $aCtrlLabel[$iDBFeldanzahl + 1], $aHandleGUIElement[$iDBFeldanzahl + 1]
    Global $asGUI_Element[$iAnzahlGUIElemente]     ;Array mit Anzahl GUI-Elementen erzeugen.
    Global $iYSchrittweite = 35
    
    
    
    
    ReadIniFile()
    
    
    
    
    
    
    
    
    ; --- Information
    ;$aHandleGUIElement[$iDBFeldanzahl] = GUICtrlCreateEdit("Gesprächsnotiz", 895, 400, 217, 160)
    ;$aCtrlLabel[$iDBFeldanzahl] = GUICtrlCreateLabel($aHeader[$iDBFeldanzahl + 1], 895, 372, 100, 22)
    
    
    ; --- Button "Datensatz Update"
    $btnUpdate = GUICtrlCreateButton("DS Update", 895, 583, 105, 28)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    ; --- Button "Datensatz löschen"
    $btnDelete = GUICtrlCreateButton("DS Löschen", 1010, 583, 105, 28)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    ; --- Suche
    $cboSearch = GUICtrlCreateCombo("Suche im Feld:", 50, 8, 150, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST))
    GUICtrlSetData(-1, $sListViewHeader)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    $btnSearch = GUICtrlCreateButton("Suche starten", 570, 8, 110, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    ; --- Button "Datenbank laden"
    $btnDBladen = GUICtrlCreateButton("Suche beenden", 700, 8, 130, 25)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    ; --- Button "Eingabefelder leeren"
    $btnClear = GUICtrlCreateButton("Eingabefelder leeren", 620, 583, 241, 28)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    ; --- Buttons, Labels und Inputfelder erzeugen -----------------------------------------------------------------------/
    ; --- Main Area -----------------------------------------------------------------------------------------------------------/
    
    
    ; --- Horizontale, gestrichelte Linie erzeugen -------------------------------\
    Const $trR = _StringRepeat("-", 368)
    $lblBottomLine = GUICtrlCreateLabel($trR, 10, 615, 1110, 8)
    ; --- Horizontale, gestrichelte Linie erzeugen -------------------------------/
    
    
    ; --- Bottom Area ---------------------------------------------------------------------------------------------------------\
    ; --- Untere Inputfelder erzeugen --------------------------------------------\
    Global $aCtrllbl[3], $aCtrlipt[3], $aLblTxt[3] = ["Auftragsanzahl:", "Ges. Seitenzahl:", "Ges. Buch NP:"]
    For $l = 0 To 2
      $aCtrllbl[$l] = GUICtrlCreateLabel($aLblTxt[$l], 10 + ($l) * 260, 640, 120, 22)
      GUICtrlSetFont(-1, 12, 400, 0, "Arial")
      $aCtrlipt[$l] = GUICtrlCreateInput($l, 140 + ($l) * 260, 638, 120, 26, 0x0002) ; $ES_RIGHT=0x0002
      GUICtrlSetFont(-1, 12, 400, 0, "Arial")
     Next
    ; --- Untere Inputfelder erzeugen --------------------------------------------/
    
    
    ; --- Button "Neuer Datensatz" erzeugen -----------------------------------\
    $btnNeuerDatensatz = GUICtrlCreateButton("Neuer Datens.", 1010, 635, 105, 28)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    ; --- Button "Datensatz kopieren" erzeugen -----------------------------------/
    
    
    ; --- Button "Datenbank-Backup" erzeugen -------------------------------------\
    $btnBackUp = GUICtrlCreateButton("DB BackUp", 895, 635, 105, 28)
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    ; --- Button "Datenbank-Backup" erzeugen -------------------------------------/
    ; --- Bottom Area ---------------------------------------------------------------------------------------------------------/
    
    
    #EndRegion Bedienoberfläche zeichnen ###########################################################################################/
    
    
    
    
    #Region SQL starten & Datenbank in Listview laden (DB gegebenenfalls zuerst erzeugen) ##########################################\
    _SQLite_Startup(@ScriptDir & "\sqlite3.dll", False, 1) ; BugFix Idee, da DLL ja nicht mehr mitgeliefert wird
    If @error Then
       $sTmp = "SQLite.dll konnte nicht geladen werden!"
        MsgBox($MB_SYSTEMMODAL, "SQLite Error", $sTmp)
        Exit -1
    EndIf
    
    
    Local $bTabelleErzeugen = 0
    If Not FileExists($sDatenbankVollpfad) Then
       $bTabelleErzeugen = True
    EndIf
    
    
    Global $g_db_Database = _SQLite_Open($sDatenbankVollpfad)  ;Datenbank öffnen. Falls noch nicht vorhanden, dann erzeugen & öffnen.
    If @error Then
       $sTmp = "Die Datenbank:" & @CRLF & $sDatenbankVollpfad & @CRLF & "konnte nicht geöffnet werden!"
        MsgBox($MB_SYSTEMMODAL, "SQLite Error", $sTmp)
        Exit -1
    EndIf
    
    
    If $bTabelleErzeugen = True Then
      ; --- Datenbank-Tabelle erzeugen-----------------------------------------------------------------------------------------\
      Global $sDBHeader = "CREATE TABLE IF NOT EXISTS Reparaturverwaltung(ID INTEGER PRIMARY KEY AUTOINCREMENT," _
      & "F01," _ ;Annahme
      & "F02," _ ;Abholung
      & "F03," _ ;Gerät
      & "F04," _ ;Schadenskürzel
      & "F05," _ ;Firma
      & "F06," _ ;Vorname
      & "F07," _ ;Nachname
      & "F08," _ ;Endpreis
      & "F09," _ ;Rechnungsnummer
      & "F10," _ ;Anzahlung
      & "F11," _ ;Leihteile
      & "F12," _ ;Voranschlag
      & "F13," _ ;Reklamationsdatum
      & "F14," _ ;Projektordner
      & "F15," _ ;Gesprächsnotiz
      & "F16," _ ;Reparaturbericht
      & "F17," _
      & "F18," _
      & "F19," _
      & "F20," _
      & "F21," _
      & "F22," _
      & "F23," _
      & "F24," _
      & "F25," _
      & "F26," _
      & "F27," _
      & "F28," _
      & "F29," _
      & "F30);"
      ; --- Datenbank-Tabelle erzeugen ----------------------------------------------------------------------------------------/
    
    
      ; --- Mehrere Beispiel-Datensätze erzeugen ------------------------------------------------------------------------------\
      _SQLite_Exec($g_db_Database, $sDBHeader)
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-03-22 11','16-03-22 18','Medion Akoya 731','Buchse defekt','','Herbert','Mustermann','100,00','576','20.00','USB-HDD-Gehäuse','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-03-21 12','16-03-22 11','HP dv7','Buchse defekt','RA Rechtsverdreh','Ede','Knastmann','100,00','1039','','','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-03-27 16','16-03-28 11','Lenovo 730','Scharnier lose','','Cornelia','Turteltaub','120,00','1038','100.00','','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-04-22 09','16-04-27 11','Lenovo 1100','Einschaltproblem','','Waltrude','von der Weide','80,00','1040','10.00','','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-06-22 15','16-06-29 11','Toshiba Satellite 50','Stabilitätsproblem','Schokofabrik ABC','Ali','Bahbah','47,50','413','10.00','Leihgerät 4','-','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-07-22 13','16-07-22 17','Sony Vaio MG3000','Grafikfehler','','','Megenstadter','22,50','-','22.50','','-','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-03-22 11','16-03-28 15','Lenovo AS200','Sturzschaden','Druckerei Müller','Willybald','Mustermann','100,00','-','','','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-01-22 12','16-03-23 15','Toshiba Satellite X20','Flüssigkeitsschaden','','Fridolin','Kaiserschmarrn','90,00','1041','','','100.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'15-03-22 11','15-04-01 12','MSI XC70S','Buchse defekt','???','','Maienbaum','0,00','-','','','0.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-03-22 16','16-03-23 10','HP HDX18','Flüssigkeitsschaden','Werbeagentur DeLuxe','Veronika','Glitterstrass','1050,79','1042','500.00','','1000.00','','','','','','','','','','','','','','','','','','');")
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL,'16-05-27 16','','Asus X738','Einschaltproblem','Druckerei Müller','Willybald','Mustermann','','','','','100,00','','','','','','','','','','','','','','','','','','');")
     ; --- Mehrere Beispiel-Datensätze erzeugen ------------------------------------------------------------------------------/
    EndIf
    
    
    _SQLite_CountRows('Reparaturverwaltung')
    #EndRegion SQL starten & Datenbank in Listview laden (DB gegebenenfalls zuerst erzeugen) #######################################/
    
    
    ; --- Statusbar am untersten Fensterrand ----------------------------------------------------------------------------------\
    Global $idStatusbar = _GUICtrlStatusBar_Create($FormKombiansicht)
    
    
    GUISetState(@SW_SHOW)
    ;_timeStatus() ; Funktion aufrufen sofortige einmalige Ausführung nach Programmstart
    AdlibRegister('_timeStatus', 1000) ; Start alle 1000 milisec.
    
    
    Global $idStatusbar_PartsWidth[4]
    $idStatusbar_PartsWidth[0]=700
    $idStatusbar_PartsWidth[1]=$idStatusbar_PartsWidth[0]+180
    $idStatusbar_PartsWidth[2]=$idStatusbar_PartsWidth[1]+150
    $idStatusbar_PartsWidth[3]=-1 ;$idStatusbar_PartsWidth[2]+200
    
    
    _GUICtrlStatusBar_SetParts($idStatusbar, $idStatusbar_PartsWidth) ;200, 400, 700, -1) ;$idStatusbar_PartsWidth)
    Global $sMausXY
    _GUICtrlStatusBar_SetText($idStatusbar, $sMausXY, 0)
    _GUICtrlStatusBar_SetText($idStatusbar, " _SQLite_LibVersion = " & _SQLite_LibVersion(), 1)
    
    
    _GUICtrlStatusBar_SetMinHeight($idStatusbar, 20)  ;!!!
    ; --- Statusbar am untersten Fensterrand ----------------------------------------------------------------------------------/
    #Region Listview Füllen und Darstellungs-Einstellungen vornehmen ###############################################################\
    _ListViewFill()  ;Listview füllen, mit den Datensätzen der (nun garantiert vorhandenen und geöffneten) Datenbank-Datei.
    
    
    _GUICtrlListView_HideColumn($Listview, 17)
    _GUICtrlListView_HideColumn($Listview, 18)
    _GUICtrlListView_HideColumn($Listview, 19)
    _GUICtrlListView_HideColumn($Listview, 20)
    _GUICtrlListView_HideColumn($Listview, 21)
    _GUICtrlListView_HideColumn($Listview, 22)
    _GUICtrlListView_HideColumn($Listview, 23)
    _GUICtrlListView_HideColumn($Listview, 24)
    _GUICtrlListView_HideColumn($Listview, 25)
    _GUICtrlListView_HideColumn($Listview, 26)
    _GUICtrlListView_HideColumn($Listview, 27)
    _GUICtrlListView_HideColumn($Listview, 28)
    _GUICtrlListView_HideColumn($Listview, 29)
    _GUICtrlListView_HideColumn($Listview, 30)
    #EndRegion Listview Füllen und Darstellungs-Einstellungen vornehmen ############################################################/
    
    
    #Region Hauptschleife ##########################################################################################################\
    $hGUI = $FormKombiansicht ;GUICreate('Drag & Drop Images Example', 541, 340, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_CLIPCHILDREN))
    Global Const $SC_DRAGMOVE = 0xF012
    Global $iMouseButtonLeft
    Global $aRect[4]
    AutoItSetOption ("MouseCoordMode", 2 )  ;Mauskoordinaten sollen sich auf den Bereich unterhalb der Menüleiste beziehen.
    
    
    While True
    
    
      ; --- Mauskoordinaten erfassen und darstellen --------------------------------------------------\
      $sMausXY=MouseGetPos()   ;GUIGetCursorInfo()  ;Die Verwendung von MouseGetPos, statt GUIGetCursorInfo vermeidet Absturz wenn außerhalb des Fensters geklickt wird.
      _GUICtrlStatusBar_SetText($idStatusbar, $sMausXY[0] & " / " & $sMausXY[1], 0)                 ;!!!!!!!! Verursacht Absturz wenn Fenster Fokus verliert !!!!!!!
      ;_GUICtrlStatusBar_SetText($idStatusbar, "lala", 0) ;$sMausXY[0] & " / " & $sMausXY[1], 0)    ;!!!!!!!! Verursacht den obigen Absturz nicht !!!!!!!
      ; --- Mauskoordinaten erfassen und darstellen --------------------------------------------------/
    
    
      Switch GUIGetMsg()
    
    
      ; --- Menü-Einträge ----------------------------------------------------------------------------\
      Case $MenuItem
        _iptClear()
        _ListView2ipt()
    
    
      Case $MenuItemDBImport
    	_DB_Import()
        _ListViewFill()
        _iptClear()
        _SQLite_CountRows('Reparaturverwaltung')
    
    
    
    
      Case $MenuItemAExit
        _Exit()
    
    
      Case $MenuItemCProgramminfo
        msgbox(0, "", $sAbout)
    
    
      Case $MenuItemCHistory
        msgbox(0, "", $sHistory)
    
    
      Case $MenuItemOptionen
        Optionen()
      ; --- Menü-Einträge ----------------------------------------------------------------------------/
    
    
      ; --- Buttons ----------------------------------------------------------------------------------\
      Case $btnNeuerDatensatz
        _NeuerDatensatz()
        _ListViewFill()
        _iptClear()
        _SQLite_CountRows('Reparaturverwaltung')
    
    
      Case $btnDelete
        _DsDelete()
        _ListViewFill()
        _SQLite_CountRows('Reparaturverwaltung')
    
    
      Case $btnUpdate
        _DsUpdate()
        _ListViewFill()
    
    
      Case $btnSearch
        _ListViewFill("SELECT ROWID,* From Reparaturverwaltung WHERE " & GUICtrlRead($cboSearch) & " LIKE '" & GUICtrlRead($iptSearch) & "';")
      ; --- Obiges funktioniert derzeit nicht mehr, weil: -------------------------------\
      ; --> Query:    SELECT ROWID,* From Reparaturverwaltung WHERE Annahme LIKE '0';
        ; --> Error:    no such column: Annahme
      ; Problem sind die inzwischen abweichenden Namen der ListView Rows von den Datensatzfeldern
      ; --- Obiges funktioniert derzeit nicht mehr, weil: -------------------------------/
    
    
      Case $btnDBladen
        _ListViewFill()
    
    
      Case $btnClear
        _iptClear()
    
    
      Case $btnBackUp
        _DB_BackUp()
      ; --- Buttons ----------------------------------------------------------------------------------/
    
    
      ; --- GUI-Events -------------------------------------------------------------------------------\
      Case $GUI_EVENT_PRIMARYDOWN                                      ;Test
        ;_SendMessage($aHandleGUIElement[4], $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)  ;Test
        ConsoleWrite("Linker Mausbutton gedrückt" & @CRLF)
        $iMouseButtonLeft = 1
    
    
      Case $GUI_EVENT_PRIMARYUP                                      ;Test
        ;_SendMessage($aHandleGUIElement[4], $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)  ;Test
        ConsoleWrite("Linker Mausbutton losgel." & @CRLF)
        $iMouseButtonLeft = 0
    
    
      Case $GUI_EVENT_SECONDARYDOWN                                      ;Test
        ;_SendMessage($aHandleGUIElement[4], $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)  ;Test
        ConsoleWrite("Rechtsklick" & @CRLF)
      ; --- GUI-Events -------------------------------------------------------------------------------/
    
    
      Case $ListView
        _GUICtrlListView_RegisterSortCallBack($ListView, false)
        _GUICtrlListView_SortItems($ListView, GUICtrlGetState($ListView))
    
    
      Case -3   ;Der rote Schließknopf rechts oben am Fenster wurde betätigt.
       _Exit()
    
    
      EndSwitch
    
    
    
    
      if $bGUIRedesign=1 then   ;Im Menü wurde der Eintrag zum Umgestalten des GUI aktiviert.
        GUI_Redesign()
      EndIf
    
    
    
    
    WEnd
    #EndRegion Hauptschleife #######################################################################################################/
    
    
    ; ### Functions ################################################################################################################\
    Func _timeStatus()
      Local $zeit = _DateTimeFormat(_NowCalc(), 5)
      _GUICtrlStatusBar_SetText($idStatusbar, " " & $asWDAYger[@WDAY - 1] & _DateTimeFormat(_NowCalc(), 2), 2)
      _GUICtrlStatusBar_SetText($idStatusbar, " Uhrzeit: " & $zeit, 3)
    EndFunc   ;==>_timeStatus
    ; #############################################################################
    Func _ListViewFill($QLite = "SELECT ROWID,* FROM Reparaturverwaltung;")
      Local $hQuery, $aRow
      _GUICtrlListView_DeleteAllItems($ListView)
    ;~ 	_SQLite_Query(-1, "SELECT ROWID,* FROM Reparaturverwaltung;", $hQuery)
      _SQLite_Query(-1, $QLite, $hQuery)
      While _SQLite_FetchData($hQuery, $aRow, False, False) = $SQLITE_OK ; Read Out the next Row
        GUICtrlCreateListViewItem(_ArrayToString($aRow, '|', 1, 21), $ListView)
        GUICtrlSetBkColor(-1, 0xF0E68C) ; (0xF9F9F9) helles Grau (0xB9D1EA) helles blau (0xF0E68C)
      WEnd
      _SQLite_QueryFinalize($hQuery)
      _GUICtrlListView_RegisterSortCallBack($ListView) ; CallBack registrieren zum sortieren
    EndFunc   ;==>_ListViewFill
    ; #############################################################################
    Func _DsDelete()  ;Datensatz löschen.
      _SQLite_Exec(-1, "DELETE From Reparaturverwaltung WHERE ID = " & GUICtrlRead($aHandleGUIElement[0]) & ";")
    EndFunc   ;==>_DsDelete
    ; #############################################################################
    Func _DsUpdate()  ;Datensatz updaten
      _SQLite_Exec(-1, "UPDATE Reparaturverwaltung SET " _
      & "F01 = '" & GUICtrlRead($aHandleGUIElement[1]) & "'," _
      & "F02 = '" & GUICtrlRead($aHandleGUIElement[2]) & "'," _
      & "F03 = '" & GUICtrlRead($aHandleGUIElement[3]) & "'," _
      & "F04 = '" & GUICtrlRead($aHandleGUIElement[4]) & "'," _
      & "F05 = '" & GUICtrlRead($aHandleGUIElement[5]) & "'," _
      & "F06 = '" & GUICtrlRead($aHandleGUIElement[6]) & "'," _
      & "F07 = '" & GUICtrlRead($aHandleGUIElement[7]) & "'," _
      & "F08 = '" & GUICtrlRead($aHandleGUIElement[8]) & "'," _
      & "F09 = '" & GUICtrlRead($aHandleGUIElement[9]) & "'," _
      & "F10 = '" & GUICtrlRead($aHandleGUIElement[10]) & "'," _
      & "F11 = '" & GUICtrlRead($aHandleGUIElement[11]) & "'," _
      & "F12 = '" & GUICtrlRead($aHandleGUIElement[12]) & "'," _
      & "F13 = '" & GUICtrlRead($aHandleGUIElement[13]) & "'," _
      & "F15 = '" & GUICtrlRead($aHandleGUIElement[14]) & "'," _
      & "F15 = '" & GUICtrlRead($aHandleGUIElement[15]) & "'," _
      & "F16 = '" & GUICtrlRead($aHandleGUIElement[16]) & "'," _
      & "F17 = '" & GUICtrlRead($aHandleGUIElement[17]) & "'," _
      & "F18 = '" & GUICtrlRead($aHandleGUIElement[18]) & "'," _
      & "F19 = '" & GUICtrlRead($aHandleGUIElement[19]) & "'," _
      & "F20 = '" & GUICtrlRead($aHandleGUIElement[20]) & "'," _
      & "F21 = '" & GUICtrlRead($aHandleGUIElement[21]) & "'," _
      & "F22 = '" & GUICtrlRead($aHandleGUIElement[22]) & "'," _
      & "F23 = '" & GUICtrlRead($aHandleGUIElement[23]) & "'," _
      & "F24 = '" & GUICtrlRead($aHandleGUIElement[24]) & "'," _
      & "F25 = '" & GUICtrlRead($aHandleGUIElement[25]) & "'," _
      & "F26 = '" & GUICtrlRead($aHandleGUIElement[26]) & "'," _
      & "F27 = '" & GUICtrlRead($aHandleGUIElement[27]) & "'," _
      & "F28 = '" & GUICtrlRead($aHandleGUIElement[28]) & "'," _
      & "F29 = '" & GUICtrlRead($aHandleGUIElement[29]) & "'," _
      & "F30 = '" & GUICtrlRead($aHandleGUIElement[30]) & "'" _
      & "WHERE ID = " & GUICtrlRead($aHandleGUIElement[0]) & ";")
    EndFunc   ;==>_DsUpdate
    ; #############################################################################
    Func _NeuerDatensatz()  ;Inhalte aller InputBoxen uns MemoBoxen etc. auslesen und in neuen Datensatz speichern.
      _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL, '" _
      & GUICtrlRead($aHandleGUIElement[1]) & "','" _
      & GUICtrlRead($aHandleGUIElement[2]) & "','" _
      & GUICtrlRead($aHandleGUIElement[3]) & "','" _
      & GUICtrlRead($aHandleGUIElement[4]) & "','" _
      & GUICtrlRead($aHandleGUIElement[5]) & "','" _
      & GUICtrlRead($aHandleGUIElement[6]) & "','" _
      & GUICtrlRead($aHandleGUIElement[7]) & "','" _
      & GUICtrlRead($aHandleGUIElement[8]) & "','" _
      & GUICtrlRead($aHandleGUIElement[9]) & "','" _
      & GUICtrlRead($aHandleGUIElement[10]) & "','" _
      & GUICtrlRead($aHandleGUIElement[11]) & "','" _
      & GUICtrlRead($aHandleGUIElement[12]) & "','" _
      & GUICtrlRead($aHandleGUIElement[13]) & "','" _
      & GUICtrlRead($aHandleGUIElement[14]) & "','" _
      & GUICtrlRead($aHandleGUIElement[15]) & "','" _
      & GUICtrlRead($aHandleGUIElement[16]) & "','" _
      & GUICtrlRead($aHandleGUIElement[17]) & "','" _
      & GUICtrlRead($aHandleGUIElement[18]) & "','" _
      & GUICtrlRead($aHandleGUIElement[19]) & "','" _
      & GUICtrlRead($aHandleGUIElement[20]) & "','" _
      & GUICtrlRead($aHandleGUIElement[21]) & "','" _
      & GUICtrlRead($aHandleGUIElement[22]) & "','" _
      & GUICtrlRead($aHandleGUIElement[23]) & "','" _
      & GUICtrlRead($aHandleGUIElement[24]) & "','" _
      & GUICtrlRead($aHandleGUIElement[25]) & "','" _
      & GUICtrlRead($aHandleGUIElement[26]) & "','" _
      & GUICtrlRead($aHandleGUIElement[27]) & "','" _
      & GUICtrlRead($aHandleGUIElement[28]) & "','" _
      & GUICtrlRead($aHandleGUIElement[29]) & "','" _
      & GUICtrlRead($aHandleGUIElement[30]) & "');")
    EndFunc   ;==>_NeuerDatensatz
    ; #############################################################################
    Func _ListView2ipt()
    ;~ 	MsgBox(0, "Information", "Selected Mark: " & _GUICtrlListView_GetSelectionMark($ListView))
      Local $electionMark = _GUICtrlListView_GetSelectionMark($ListView)
      If $electionMark > -1 Then
        Local $aLVitem = _GUICtrlListView_GetItemTextArray($ListView, $electionMark)
        For $i = 1 To $aLVitem[0]
    ;~ 			MsgBox(0, "Information", "ItemTextArray: " & $aIpt[$i-1] & "  " & $aLVitem[$i])
          GUICtrlSetData($aHandleGUIElement[$i - 1], $aLVitem[$i])
        Next
      EndIf
    EndFunc   ;==>_ListView2ipt
    ; #############################################################################
    Func _iptClear()
      For $i = 0 To 30
        GUICtrlSetData($aHandleGUIElement[$i], "")
      Next
    EndFunc   ;==>_iptClear
    ; #############################################################################
    ;==========================================================================
    ; Function Name....: _SQLite_CountRows
    ; Description......: Ermittelt die Anzahl von Datensätzen für eine Tabelle
    ; Parameter(s).....: $_sTable  Tabellenname
    ; Requirement(s)...: Eine mit _SQLite_Open() geöffnete DB
    ; .................: #include <SQLite.au3>
    ; Return Value(s)..: Erfolg:   Anzahl der Datensätze
    ; .................: Fehler:   -1   @error = 1,  @extended = SQLite-@error
    ; Author(s)........: BugFix (bugfix@autoit.de)
    ;==========================================================================
    Func _SQLite_CountRows($_sTable)
      Local $hQuery, $aQuery, $iRet = 0, $iErr
      If $SQLITE_OK <> _SQLite_Query(-1, "SELECT count(*) FROM " & $_sTable & ";", $hQuery) Then
        $iErr = _SQLite_ErrCode()
        _SQLite_QueryFinalize($hQuery)
        Return SetError(1, $iErr, -1)
      EndIf
      While _SQLite_FetchData($hQuery, $aQuery) = $SQLITE_OK
        $iRet = $aQuery[0]
      WEnd
      _SQLite_QueryFinalize($hQuery)
      ;MsgBox(0, "", $iRet)
    ;~ 	Return $iRet
      GUICtrlSetData($aCtrlipt[0], $iRet)
    EndFunc   ;==>_SQLite_CountRows
    ; #############################################################################
    Func _DB_BackUp()
      Local $BackUpFolder = @ScriptDir & "\_BackUps"
      If Not FileExists($BackUpFolder) Then DirCreate($BackUpFolder)
      Local $hFileOpen = FileOpen($BackUpFolder & "\" & @YEAR & "-" & @MON & "-" & @MDAY & "_BuchVw.db.txt", 2)
      If $hFileOpen = -1 Then Exit MsgBox(0, "Fehler", "Die Datei konnte nicht geöffnet werden.")
    
    
      Local $aResult, $iRows, $iColumns
      Local $iRval = _SQLite_GetTable2d(-1, "SELECT * FROM Reparaturverwaltung;", $aResult, $iRows, $iColumns)  ;Variablen doppelt deklariert (siehe Vorzeile).
    
    
      FileWriteLine($hFileOpen, $sListViewHeader)
    
    
      For $iR = 1 To $iRows
        $sText = ""
        For $iC = 0 To $iColumns - 1
          $sText &= $aResult[$iR][$iC]
          If $iC < $iColumns - 1 Then $sText &= "|"
        Next
        FileWriteLine($hFileOpen, $sText)
      Next
      FileClose($hFileOpen)
      MsgBox(64, "Info", "DB BackUp ist fertig !", 3)
    EndFunc   ;==>_DB_BackUp
    ; #############################################################################
    Func _Stringbreite($sT_Lbl)
    ; Ermittelt die Breite des Strings in Pixeln.
    ; Basiert auf folgender Quelle:
    ; https://autoit.de/index.php/Thread/13627-TextMeter/?postID=105795#post105795&page=Thread&postID=105795
    ; Dank an den User "BugFix"!
      Local $nText = $sT_Lbl
      Local $aFont[8] = [8,0,'Courier New',10,400,0,0,0]
      Local $gui
    
    
      If $nText = '' Then Return
        ;_GDIPlus_Startup()
        Local $hFormat = _GDIPlus_StringFormatCreate(0)
        Local $hFamily = _GDIPlus_FontFamilyCreate($aFont[2])
        Local $hFont = _GDIPlus_FontCreate($hFamily, $aFont[3], $aFont[1], 3)
        Local $tLayout = _GDIPlus_RectFCreate(15, 171, 0, 0)
        Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($gui)
        Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $nText, $hFont, $tLayout, $hFormat)
        Local $iWidth = Ceiling(DllStructGetData($aInfo[0], "Width"))
        ;Local $iHeight = Ceiling(DllStructGetData($aInfo[0], "Height"))
        ;_GDIPlus_StringFormatDispose($hFormat)
        ;_GDIPlus_FontDispose($hFont)
        ;_GDIPlus_FontFamilyDispose($hFamily)
        ;_GDIPlus_GraphicsDispose($hGraphic)
        ;_GDIPlus_ShutDown()
        ;GUICtrlSetData($inHeight, $iHeight)
        ;GUICtrlSetData($inWidth, $iWidth)
      Return $iWidth
    ;MsgBox(0, "", $iWidth)
    EndFunc   ;==>_Stringbreite
    ; #############################################################################
    Func _DB_Import()
    	;Listet zunächst alle Ordner der ersten Ebene des vorgegebenen Pfades.
    	;Im zweiten Schritt werden die Ordnernamen (die bei mir einem ganz bestimmten Strickmuster entsprechen) zerhackstückelt
    	;und in folgende Felder aufgedröselt:
    	;0) Datum
    	;1) Gerät
    	;2) Schaden
    	;3) Vorname
    	;4) Nachname
    	;5) Zusatzinfos
    	;6) Dem ursprünglichen Ordnernamen, wie er roh vorlag.
    
    
        ;Local $avGUI_Parameter[0]
        Local $sSplittedString[0]
        Local $avZerlegterDatensatz[7]
        Local $iPosition, $sVollname, $sZusatzinfos
        Local $aArray
    
    
        Local $sOrdnerPfad = "H:\Notebook-Reparatur\#00 - erledigt"
    	Local $sVorname, $sNachname
    
    
        ; Alle Ordner der ersten Ebene eines bestimmten Pfades auflisten, ohne versteckten Inhalten:
        $aArray = _FileListToArrayRec($sOrdnerPfad, "*", $FLTAR_FOLDERS + $FLTAR_NOHIDDEN + $FLTAR_NOSYSTEM)
        _ArrayDisplay($aArray, "Sollen diese " &$aArray[0] & " Ordnernamen zu neuen Datensätzen konvertiert werden?")
    
    
    	For $i = 1 to UBound($aArray)-1
    	  ConsoleWrite("DS " & $i & @CRLF)
    	  $sSplittedString=Stringsplit($aArray[$i], ",")   ;Grob aufgesplittete Parameter
    	  ;
    	  ;Datum:
    	  $avZerlegterDatensatz[0] = StringLeft($sSplittedString[1], 8)        ;Datum
    	  ;
    	  ;Gerät:
    	  $avZerlegterDatensatz[1] = StringTrimLeft($sSplittedString[1], 9)    ;Gerät
    	  ;
    	  ;Schaden:
    	  $avZerlegterDatensatz[2] = StringStripWS($sSplittedString[2], 1 )    ;Schaden (um das führende Leerzeichen bereinigt)
          ;
    	  ;Name:
    	  $iPosition = StringInStr($sSplittedString[3], " - ")          ;Testen, ob hinter dem Namen noch Zusatzinfos kommen (wenn " - " vorkommt)
          If $iPosition <> 0 Then                                       ;Ja, es gibt Zusatzinfos
    		 $sVollname = StringLeft($sSplittedString[3], $iPosition)   ;Aus dem String den Namen extrahieren
    		 $sZusatzinfos = StringMid($sSplittedString[3], $iPosition, StringLen($sSplittedString[3]))  ;Aus dem String die Zusatzinfos extrahieren.
    	  Else                                 ;Es gibt keine Zusatzinfos hinter dem Namen.
    		 $sVollname=$sSplittedString[3]
    		 $sZusatzinfos = ""
    	  EndIf
          $sVollname = StringStripWS($sVollname, 1)           ;Führendes Leerzeichen vom Namen entfernen
          $iPosition = StringInStr($sVollname, " ")           ;Üblicherweise beginnt der Name mit einem Vornamen, gefolgt von einem Leerzeichen.
    	  if $iPosition <> 0 Then                             ;Wenn dem so ist ...
    		$sVorname = StringLeft($sVollname, $iPosition)
    		$sNachname = StringMid($sVollname, $iPosition, StringLen($sVollname))
    	  Else
    		$sVorname = ""
    		$sNachname = $sVollname
    	  EndIf
    
    
          $avZerlegterDatensatz[3] = $sVorname
          ;
    	  ;Nachname
    	  $avZerlegterDatensatz[4] = StringStripWS($sNachname, 1)
    
    
          ;Zusatzinfos
    	  $avZerlegterDatensatz[5] = StringStripWS($sZusatzinfos, 1)
    
    
          ;Voller Pfad
    	  $avZerlegterDatensatz[6] = $aArray[$i]
    	 ; $avZerlegterDatensatz[6] =
    
    
          ;_ArrayDisplay($avZerlegterDatensatz, "Fein zerlegter Pfad")
    
    
    	  ; --- Neuen Datensatz schreiben --------------------------------------------------\
    	    _SQLite_Exec(-1, "INSERT INTO Reparaturverwaltung VALUES(NULL, '" _
      & $avZerlegterDatensatz[0] & "','" _  ; 1 Annahme
      & "" & "','" _  ; 2 Abholung
      & $avZerlegterDatensatz[1] & "','" _  ; 3 Gerät
      & $avZerlegterDatensatz[2] & "','" _  ; 4 Schaden
      & "" & "','" _                        ; 5 Firma
      & $avZerlegterDatensatz[3] & "','" _  ; 6 Vorname
      & $avZerlegterDatensatz[4] & "','" _  ; 7 Nachname
      & "" & "','" _  ;08 Endpreis
      & "" & "','" _  ;09
      & "" & "','" _  ;10
      & "" & "','" _  ;11
      & "" & "','" _  ;12
      & "" & "','" _  ;13
      & $avZerlegterDatensatz[6] & "','" _  ;14 Vollpfad
      & "" & "','" _  ;15
      & "" & "','" _  ;16
      & "" & "','" _  ;17
      & "" & "','" _  ;18
      & "" & "','" _  ;19
      & "" & "','" _  ;20
      & "" & "','" _  ;21
      & "" & "','" _  ;22
      & "" & "','" _  ;23
      & "" & "','" _  ;24
      & "" & "','" _  ;25
      & "" & "','" _  ;26
      & "" & "','" _  ;27
      & "" & "','" _  ;28
      & "" & "','" _  ;29
      & "" & "');")   ;30
       ; --- Neuen Datensatz schreiben --------------------------------------------------/
    
    
    
    
        Next
    EndFunc   ;==>_DB_Import
    ; #############################################################################
    Func ReadIniFile()
      Local $aCtrls[1]
      Local $Section_GUI_Parameter
      Local $aSplit
    
    
      ;If Not FileExists($sIniFilename) Then
        ; --- GUI-Parameter der Input-Boxen und deren Labels ------------------------------------------------------------\
        ;                       1   2   3  4 5      6 7        8 9   10 11  12  1314     1516 17
        $asGUI_Element[0]  = "Inputbox000=| 15|320|100| 22|L|0x0000|0|Zeile 0    |U|   0| 0|110| 22|L|0x0000|0|Datensatz-ID"
        $asGUI_Element[1]  = "Inputbox001=|150|375|100| 22|L|0x0000|0|Zeile 1    |L|  -5| 0|110| 22|L|0x0000|0|Annahmedatum"
        $asGUI_Element[2]  = "Inputbox002=|150|400|100| 22|L|0x0000|0|Zeile 2    |L|  -5| 0|110| 22|R|0x0000|0|Abholdatum"
        $asGUI_Element[3]  = "Inputbox003=|390|375|200| 22|L|0x0000|0|Zeile 3    |O|  -5| 0|110| 22|R|0x0000|0|Gerät"
        $asGUI_Element[4]  = "Inputbox004=|390|400|200| 22|L|0x0000|0|Zeile 4    |U|   0| 0|110| 22|R|0x0000|0|Schadenskürzel"
        $asGUI_Element[5]  = "Inputbox005=|150|495|100| 22|L|0x0000|0|Zeile 5    |L|  -5| 0|110| 22|R|0x0000|0|Firma"
        $asGUI_Element[6]  = "Inputbox006=|150|520|100| 22|L|0x0000|0|Zeile 6    |L|  -5| 0|110| 22|R|0x0000|0|Vorname"
        $asGUI_Element[7]  = "Inputbox007=|150|545|100| 22|L|0x0000|0|Zeile 7    |L|  -5| 0|110| 22|R|0x0000|0|Nachname"
        $asGUI_Element[8]  = "Inputbox008=|450|550|100| 22|R|0x0000|0|Zeile 8    |L|  -5| 0|110| 22|R|0x0000|0|Endpreis"
        $asGUI_Element[9]  = "Inputbox009=|450|575|100| 22|R|0x0000|0|Zeile 9    |L|  -5| 0|110| 22|R|0x0000|0|Re-Nr."
        $asGUI_Element[10] = "Inputbox010=|450|450|100| 22|R|0x0000|0|Zeile 10   |L|  -5| 0|110| 22|R|0x0000|0|Anzahlung"
        $asGUI_Element[11] = "Inputbox011=|450|475|100| 22|L|0x0000|0|Zeile 11   |L|  -5| 0|110| 22|R|0x0000|0|Leihteile"
        $asGUI_Element[12] = "Inputbox012=|450|500|100| 22|R|0x0000|0|Zeile 12   |L|  -5| 0|110| 22|R|0x0000|0|Voranschlag"
        $asGUI_Element[13] = "Inputbox013=|140|320|100| 22|L|0x0000|0|Zeile 13   |U|   0| 0| 85| 22|L|0x0000|0|Rekla"
        $asGUI_Element[14] = "Inputbox014=|270|320|500| 22|L|0x0000|0|Zeile 14   |U|   0| 0|130| 22|L|0x0000|0|Projektordner"
        $asGUI_Element[15] = "Inputbox015=|750|475|100| 22|L|0x0000|0|Zeile 15   |L|  -5| 0|110| 22|R|0x0000|0|Gesprächsnotiz"
        $asGUI_Element[16] = "Inputbox016=|750|350|100| 22|L|0x0000|0|Zeile 16   |L|  -5| 0|120| 22|R|0x0000|0|Reparaturbericht"
        $asGUI_Element[17] = "Inputbox017=|750|375|100| 22|L|0x0000|0|Zeile 17   |L|  -5| 0|110| 22|R|0x0000|0|Festnetz"
        $asGUI_Element[18] = "Inputbox018=|750|400|100| 22|L|0x0000|0|Zeile 18   |L|  -5| 0|110| 22|R|0x0000|0|Mobil-Nr."
        $asGUI_Element[19] = "Inputbox019=|750|425|100| 22|L|0x0000|0|Zeile 19   |L|  -5| 0|110| 22|R|0x0000|0|E-Mail"
        $asGUI_Element[20] = "Inputbox020=|750|450|100| 22|L|0x0000|0|Zeile 20   |L|  -5| 0|110| 22|R|0x0000|0|Status"
        $asGUI_Element[21] = "Inputbox021=|270| 10|250| 22|L|0x0000|0|Zeile 21   |L|   0| 0| 70| 22|R|0x0000|0|Suche:"
        $asGUI_Element[22] = "Groupbox001=| 64|475|200|100|L|0x0000|0|Adressdaten|R|   0| 0| 70| 22|L|0x0000|0|"
        $asGUI_Element[23] = "Editbox001= |895|400|217|160|L|0x0000|0|Memo       |U|  -5| 0| 70| 22|L|0x0000|0|Gesprächsnotiz"
        ; --- GUI-Parameter der Input-Boxen und deren Labels ------------------------------------------------------------/
    
    
        For $iGUI_ElementNr = Ubound($asGUI_Element)-1 to 0 Step -1
          IniWriteSection($sIniFilename, "GUI-Parameter", $asGUI_Element[$iGUI_ElementNr])
        Next
       ;EndIf
    
    
    $aCtrls = IniReadSection($sIniFilename, "GUI-Parameter")
    
    
    
    
    
    
    #cs
    ;$aCtrls = IniReadSection($sIni, "Moveable")
    If $aCtrls[0][0] > 0 Then
    	_ArrayColInsert($aCtrls, 2)
    	_ArrayColInsert($aCtrls, 2)
    	_ArrayColInsert($aCtrls, 2)
    	_ArrayColInsert($aCtrls, 2)
    	_ArrayColInsert($aCtrls, 2)
    	_ArrayColInsert($aCtrls, 2)
    	For $iCtrl = 1 To $aCtrls[0][0]
    		$aSplit = StringSplit($aCtrls[$iCtrl][1], '|')
    		For $iCol = 1 To $aSplit[0]
    			$aCtrls[$iCtrl][$iCol] = $aSplit[$iCol]
    		Next
    	Next
    EndIf
    $aCtrls[0][1] = "Text"
    $aCtrls[0][2] = "left"
    $aCtrls[0][3] = "Top"
    $aCtrls[0][4] = "width"
    $aCtrls[0][5] = "height"
    $aCtrls[0][6] = "Style"
    $aCtrls[0][7] = "ID"
    
    
    _ArrayDisplay($aCtrls)
    #ce
    
    
    
    
    
    
    
    
    
    
    
    
    ;_ArrayDisplay($asGUI_Element, "Array-Inhalt") ; Debugausgabe (besserer Ersatz für MsgBox, um ein ganzes Array auf einen Schlag anzeigen zu lassen).
    
    
    ; --- Input-Boxen (und Labels) für Datenbankfelder --------------------------------------------------------------\
    Global $avGUI_Parameter[19]  ;Anzahl der Parameter eines Parametersatzes.
    Global $sF_Obj
    Global $iX_Obj, $iY_Obj, $iW_Obj, $iH_Obj, $hE_Obj, $sT_Obj
    Global $sA_Lbl, $sA_LblTxt
    Global $iX_Lbl, $iY_Lbl, $iW_Lbl, $iH_Lbl, $hE_Lbl, $sT_Lbl
    Global $iStrgW
    Global $iXOffsetLabelToElement[$iAnzahlGUIElemente], $iYOffsetLabelToElement[$iAnzahlGUIElemente]  ;Zwei Arrays, die den Offset zwischen Obekt und Label speichern.
    
    
    For $iGUI_ElementNr = 0 to Ubound($asGUI_Element)-1  ;30 Zeilen
      ; --- Pro Schleifendurchlauf die Parameter je eines GUI-Elements auslesen --------------------------------\
      $avGUI_Parameter=Stringsplit($asGUI_Element[$iGUI_ElementNr], "|")    ;Aufgesplittete Parameter
      ;MsgBox(0,"",$avGUI_Parametersatz[2])
    
    
      $sF_Obj = StringStripWS ($avGUI_Parameter[1], 3)    ;Funktion des Objektes (von Leerzeichen links und Rechts befreit)
    
    
      $iX_Obj = $avGUI_Parameter[2]            ;X-Position des Objektes
      $iY_Obj = $avGUI_Parameter[3]            ;Y-Position des Objektes
      $iW_Obj = $avGUI_Parameter[4]            ;Weite des Objektes
      $iH_Obj = $avGUI_Parameter[5]            ;Höhe des Objektes
      $hE_Obj = $avGUI_Parameter[6]            ;Erweiterte Parameter, siehe AutoIt Help: GUICtrlCreateLabel, bzw. GUI Control Styles
      $sT_Obj = $avGUI_Parameter[9]            ;Textvorbelegung (wenn Inputbox)
    
    
      $sA_Lbl = $avGUI_Parameter[10]           ;Positionsangabe, bezogen auf das Objekt: "L"=Links / "U"=Unten / "R"=Rechts / "O"=Oben.
    
    
      $iX_Lbl = $avGUI_Parameter[11] ; + $iX_Obj  ;X-Position des Labels
      $iY_Lbl = $avGUI_Parameter[12] ;+ $iY_Obj  ;Y-Position des Labels
      $iW_Lbl = $avGUI_Parameter[13]           ;Weite des Labels
      $iH_Lbl = $avGUI_Parameter[14]           ;Höhe des Labels
      $sA_LblTxt= $avGUI_Parameter[15]         ;Ausrichtung des Labeltextes (linksbündig/rechtsbündig)
      $hE_Lbl = $avGUI_Parameter[16]           ;Erweiterte Parameter, siehe AutoIt Help: GUICtrlCreateLabel, bzw. GUI Control Styles
      $sT_Lbl = $avGUI_Parameter[18]           ;Text des Labels
    
    
      $iStrgW=_Stringbreite($sT_Lbl)            ;Breite des vordefinierten Label-Strings in Pixeln.
      ; --- Pro Schleifendurchlauf die Parameter je eines GUI-Elements auslesen --------------------------------/
    
    
      ; --- Positionen der Labels (in Bezug auf deren Inputboxen), sowie deren Textausrichtung festlegen -------\
      Select   ;Label-Position (L/U/R/O) und Textausrichtung (L/R) des Labels
      Case $sA_Lbl="L" and $sA_LblTxt="L"     ;LL - Labelposition (L)inks, Textausrichtung (L)inksbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl - $iW_Lbl
        $iY_Lbl = $iY_Obj + $iY_Lbl
    
    
      Case $sA_Lbl="L" and $sA_LblTxt="R"     ;LR - Labelposition (L)inks, Textausrichtung (R)echtsbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl - $iW_Lbl ; + $iStrgW
        $hE_Lbl=BitOR($hE_Lbl, 0x0002)
        $iY_Lbl = $iY_Obj + $iY_Lbl
    
    
      Case $sA_Lbl="U" and $sA_LblTxt="L"     ;UL - Labelposition (U)nten, Textausrichtung (L)inksbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl
        $iY_Lbl = $iY_Obj + $iY_Lbl + $iH_Obj
    
    
      Case $sA_Lbl="U" and $sA_LblTxt="R"     ;UR - Labelposition (U)nten, Textausrichtung (R)echtsbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl + $iW_Obj - $iW_Lbl
        $hE_Lbl=BitOR($hE_Lbl, 0x0002)
        $iY_Lbl = $iY_Obj + $iY_Lbl + $iH_Lbl
    
    
      Case $sA_Lbl="R" and $sA_LblTxt="L"     ;RL - Labelposition (R)echts, Textausrichtung (L)inksbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl + $iW_Obj
        $iY_Lbl = $iY_Obj + $iY_Lbl
    
    
      Case $sA_Lbl="R" and $sA_LblTxt="R"     ;RR - Labelposition (R)echts, Textausrichtung (R)echtsbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl + $iW_Obj ;- $iW_Lbl
        $hE_Lbl=BitOR($hE_Lbl, 0x0002)
        $iY_Lbl = $iY_Obj + $iY_Lbl
    
    
      Case $sA_Lbl="O" and $sA_LblTxt="L"     ;OL - Labelposition (O)ben, Textausrichtung (L)inksbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl
        $iY_Lbl = $iY_Obj + $iY_Lbl - $iH_Lbl
    
    
      Case $sA_Lbl="O" and $sA_LblTxt="R"     ;OR - Labelposition (O)ben, Textausrichtung (R)echtsbündig
        $iX_Lbl = $iX_Obj + $iX_Lbl ;+ $iW_Lbl
        $hE_Lbl=BitOR($hE_Lbl, 0x0002)
        $iY_Lbl = $iY_Obj + $iY_Lbl - $iH_Obj
    
    
      EndSelect
      ; --- Positionen der Labels (in Bezug auf deren Inputboxen), sowie deren Textausrichtung festlegen -------/
    
    
      if StringLeft($sF_Obj, 8)="Inputbox" then
      ;if $GUIElement_Nr=1 Then  ;Die erste Inputbox enthält die ID des Datensatzes. Daher auf nicht editierbar schalten.
         ;BitXOR $ES_READONLY
        ;EndIf
        $aHandleGUIElement[$iGUI_ElementNr] = GUICtrlCreateInput($sT_Obj, $iX_Obj, $iY_Obj, $iW_Obj, $iH_Obj, $hE_Obj, 0)   ;Inputbox
      EndIf
    
    
      if StringLeft($sF_Obj, 8)="Groupbox" then
        $aHandleGUIElement[$iGUI_ElementNr] = GUICtrlCreateGroup($sT_Obj, $iX_Obj, $iY_Obj, $iW_Obj, $iH_Obj)
      EndIf
    
    
      if StringLeft($sF_Obj, 7)="Editbox" then
        $aHandleGUIElement[$iGUI_ElementNr] = GUICtrlCreateEdit($sT_Obj, $iX_Obj, $iY_Obj, $iW_Obj, $iH_Obj)
      EndIf
    
    
    ; --- Label erzeugen -----------------------------------------------------------------------------\
      $aCtrlLabel[$iGUI_ElementNr] = GUICtrlCreateLabel($sT_Lbl, $iX_Lbl, $iY_Lbl, $iW_Lbl, $iH_Lbl, $hE_Lbl, 0)   ;Label, zugehörig zu obiger Inputbox.
      GUICtrlSetFont($aCtrlLabel[$iGUI_ElementNr], 12, 400, 0, "Arial")
      GUICtrlSetFont($aHandleGUIElement[$iGUI_ElementNr], 12, 400, 0, "Arial")
    ; --- Label erzeugen -----------------------------------------------------------------------------/
    
    
      $iXOffsetLabelToElement[$iGUI_ElementNr] = $iX_Obj - $iX_Lbl
      $iYOffsetLabelToElement[$iGUI_ElementNr] = $iY_Obj - $iY_Lbl
    
    
    Next
    ; --- Input-Boxen (und Labels) für Datenbankfelder --------------------------------------------------------------/
    GUICtrlSetFont(-1, 12, 400, 0, "Arial")
    
    
    EndFunc  ;==> ReadIniFile()
    ; #############################################################################
    Func Optionen()
      ;MsgBox(0, "Optionen", "Hallo")
      ;$aHandleGUIElement[$iGUI_ElementNr]
      $bGUIRedesign = BitXOR($bGUIRedesign, 0x1)  ;Binärwert von $bGUIRedesign toggeln.
      if $bGUIRedesign=1 then   ;Im Menü wurde der Eintrag zum Umgestalten des GUI aktiviert.
        MsgBox(0, "", "" _
        & "Sie können nun einzelne Bedienelemente" _
        & @CRLF & "mit der Maus verschieben." _
        & @CRLF & "Zum Beenden diesen Menüeintrag erneut anwählen!")
      EndIf
    EndFunc
    ; #############################################################################
    FUNC GUI_Redesign()
      Local $iNewX, $iNewY
      $sUserMessageNew=""
    
    
      ; --- Ermitteln, über welchem GUI-Element der Hauszeiger hoovert. ------------------------------------------------------------\
      if $iDoItOnlyOnce = 0 then   ;Null, wenn gerade kein GUI-Element mit der Maus angewählt ist. Andernfalls Eins.
        For $iGUI_ElementNr = 0 to Ubound($asGUI_Element)-1   ;Alle GUI-Elemente im Array durchlaufen.
          ;ConsoleWrite("Nr.: " & $iGUI_ElementNr & @CRLF)
          $aiGUIElementXYWH = ControlGetPos($FormKombiansicht, "", $aHandleGUIElement[$iGUI_ElementNr])  ;Pro Durchlauf die X/Y-Position eines GUI-Elements ermitteln
          if not @error and $sMausXY[0] > $aiGUIElementXYWH[0] and $sMausXY[0] < ($aiGUIElementXYWH[0]+$aiGUIElementXYWH[2])  and  $sMausXY[1] > $aiGUIElementXYWH[1] and $sMausXY[1] < ($aiGUIElementXYWH[1]+$aiGUIElementXYWH[3])then
            ; --- Das GUI-Element unter dem Mauszeiger wurde gefunden! --------------------------------------------------------\
    		$sUserMessageNew="Feld-Nr. " & $iGUI_ElementNr
    		$hActualGUIElement = $aHandleGUIElement[$iGUI_ElementNr]         ;Das Handle des GUI-Elements unter dem Mauszeiger.
    		$hActualLabel = $aCtrlLabel[$iGUI_ElementNr]                     ;Das Handle des an das GUI-Element angeheftete Label.
    		$iActualGUINumber = $iGUI_ElementNr                              ;Die Nummer des GUI-Elements im Array aller GUI-Elemente.
    		$iXOffsetGUIElementToMouse = $sMausXY[0] - $aiGUIElementXYWH[0]  ;Der X-Offset des GUI-Elemnts zur Maus, im Moment des Linksklicks.
    		$iYOffsetGUIElementToMouse = $sMausXY[1] - $aiGUIElementXYWH[1]  ;Der Y-Offset des GUI-Elemnts zur Maus, im Moment des Linksklicks.
    		$iDoItOnlyOnce = 1   ;Verhindert erneuten Schleifenaufruf, so lange die linke Maustaste gedrückt bleibt (nachdem das GUI-Element nun ja gefunden wurde).
            ExitLoop
            ; --- Das GUI-Element unter dem Mauszeiger wurde gefunden! --------------------------------------------------------/
    	  Else  ;Mauszeiger hovert derzeit nicht über einem verschiebbaren Element.
    		$sUserMessageNew = ""             ;Feld-Nr. " & $iGUI_ElementNr
    		$hActualGUIElement = 0            ;$aHandleGUIElement[$iGUI_ElementNr]   ;Das Handle des GUI-Elements unter dem Mauszeiger.
    		$hActualLabel = 0                 ;$aCtrlLabel[$iGUI_ElementNr]          ;Das Handle des an das GUI-Element angeheftete Label.
    		$iActualGUINumber = 0             ;$iGUI_ElementNr                       ;Die Nummer des GUI-Elements im Array aller GUI-Elemente.
    		$iXOffsetGUIElementToMouse = 0    ;$sMausXY[0] - $aiGUIElementXYWH[0]    ;Der X-Offset des GUI-Elemnts zur Maus, im Moment des Linksklicks.
    		$iYOffsetGUIElementToMouse = 0    ;$sMausXY[1] - $aiGUIElementXYWH[1]    ;Der Y-Offset des GUI-Elemnts zur Maus, im Moment des Linksklicks.
    		$iDoItOnlyOnce = 0
    	  EndIf
        Next
      EndIf
      ; --- Ermitteln, über welchem GUI-Element der Hauszeiger hoovert. ------------------------------------------------------------/
    
    
      if $sUserMessageNew <> $sUserMessageOld then
        _GUICtrlStatusBar_SetText($idStatusbar, $sUserMessageNew, 1)
        $sUserMessageOld=$sUserMessageNew
      EndIf
    
    
      If $iDoItOnlyOnce = 1 then
    	;GUICtrlSetState($hActualGUIElement, $GUI_DISABLE)                ;Editierbare Elemente (InputBoxen etc.) deaktivieren, so dass der Curser sie nicht betritt.
    	;$iDoItOnlyOnce = 2
      EndIf
    
    
      ; --- So lange die linke Maustaste gedrückt ist, folgen das gewählte GUI-Element & dessen Label dem Mauszeiger -----\
      if $iMouseButtonLeft then
        $iNewX = $sMausXY[0] - $iXOffsetGUIElementToMouse   ;Die neue X-Position des GUI-Elements.
    	$iNewY = $sMausXY[1] - $iYOffsetGUIElementToMouse   ;Die neue Y-Position des GUI-Elements.
        GUICtrlSetPos($hActualGUIElement, $iNewX, $iNewY)   ;GUI-Element an die neue Position verschieben.
    	GUICtrlSetPos($hActualLabel, $iNewX - $iXOffsetLabelToElement[$iActualGUINumber], $iNewY - $iYOffsetLabelToElement[$iActualGUINumber])    ;Angeheftetes Label ebenfalls mit verschieben.
      Else
    	If $iDoItOnlyOnce = 1 then
    	$iDoItOnlyOnce = 0   ;Maustaste wurde losgelassen - Vorbereitung für das Verschieben des nächsten Elements (obige For-Schleife kann wieder betreten werden).
        ;GUICtrlSetState($hActualGUIElement, $GUI_ENABLE)                ;Editierbares Element (InputBoxen etc.) wieder deaktivieren, so dass der Curser sie wieder betreten kann.
        EndIf
      EndIf
      ; --- So lange die linke Maustaste gedrückt ist, folgen das gewählte GUI-Element & dessen Label dem Mauszeiger -----/
    EndFunc   ;==>GUI_Redesign()
    ; #############################################################################
    Func _Exit() ;Datenbank schließen und Programmende.
      _GUICtrlListView_UnRegisterSortCallBack($ListView)
      _SQLite_Close($g_db_Database)
      _SQLite_Shutdown()
      _GDIPlus_ShutDown()
      Exit
    EndFunc   ;==>_Exit
    ; ### Functions ################################################################################################################/
    
    
    ; --- Codeschnippsel-Ablage ---
    ;$maus_x = -(MouseGetPos(0) - $center)
    ;$maus_y = (MouseGetPos(1) - $center)
    ;_GDIPlus_GraphicsDrawLine($hGraphic, $center + $x1, $center + $y1, $center + $x2, $center + $y2, $hPen) ;quadrat
    ; Local $mpos = GUIGetCursorInfo()   ;Mauskoordinaten relativ zum Fenster.
    Alles anzeigen


    Wie gesagt: Noch immer volle Baustelle, aber schon sehr viel weiter entwickelt, als die im weiter oben stehenden Posting enthaltene Version.

  • Programmier-Ideen?

    • Code-Jack
    • 8. November 2016 um 02:50

    Was ich seit mindestens 15 Jahren vermisse, ist ein vernünftiges, mehrstufiges Clipboard!
    Eines das tatsächlich (nebenwirkungsfrei!) schlicht so funktioniert, wie man es erwartet, ohne blöde Einschränkungen, wie "Text only".
    Und WICHTIG: Ohne grafischer Oberfäche!!!

    Also nix mit "Bitte wählen sie aus, welchen Inhalt sie einfügen wollen".
    Sondern rein tastaturgesteuert und ausschließlich mit den üblichen Tastenkombinationen bedienbar.
    Man markiert irgendwo einen Inhalt und drückt Ctrl+c. Dann markiert man den zweiten Inhalt und drückt wieder Ctrl+c ... das wiederholt man so oft man mag.
    Und mit jedem Ctrl-v wird der jeweils zuerst ins Clipboard kopierte Inhalt gepastet und sogleich aus dem Cache entfernt.
    First in, first out.

    Ich habe im Laufe der Jahre bestimmt 20 Clipboard-Tools ausprobiert, doch keines tat diesen simplen Job so, wie ich es erwartete.

    Für den Psion Serie5 hatte ich vor vielen Jahren mal exakt so ein Tool geschrieben, das rundum perfekt seinen Dienst tut - bis heute. Doch für Win-Dosen traue ich mir das nicht zu, da funktioniert erstens das Clipboard ganz anders, zweitens könnte ich unter Windows kein Programm schreiben, dass sich permanent so tief im System einnistet und die entsprechenden drei Tastenkombinationen abfängt.
    Und - nein - es mag an einen Keylogger erinnern, aber ich wünsche mir tatsächlich nur ein mehrstufiges Clipboard, ganz ohne Hintergedanken (ein kompiliertes Programm würde mir völlig genügen).


    Ach ja, da wäre noch eine Programmidee:
    Als alter Atarianer vermisse ich seit dem Umstieg auf Windows den guten Tastenklick des Atari!
    Jaja, der Tastenklick war immer umstritten, bitte keine Diskussion deswegen; ich jedenfalls liebte ihn einfach und konnte durch ihn viel fehlerfreier schreiben.
    In meinen Augen ist ein Tastenklick eine Grundfnktion, die jeder Computer ganz selbstverständlich an Board haben sollte. Unbegreiflich, wieso PCs das partout nicht können. XP jedenfalls nicht - keine Ahnung, wie es bei Win 7/8/10 ist.

    Es gibt ein paar Tools, die vorgeblich einen Tastenklick realisieren sollen. Aber auch hier fand ich bislang keines, das immer und überall schlicht funktioniert, ohne blöde Nebenwirkungen zu entfalten

    Also wer für diese beiden Probleme eine Lösung herbei zaubert, der kann sich meiner Jubelsprünge und innigen Lobpreisungen sicher sein! :)

  • ERLEDIGT --> Raspberry Pi® 2 Model B Advanced-Set 1 GB

    • Code-Jack
    • 29. August 2016 um 14:38

    @Xori, was gleubst du, was mit einem so hauchdünnen Hölzchen, in das Stege gesägt wurden, passiert, wenn man mit dem heißen Lötkolben ganz nah ran geht?
    - Die zarten Stege würden augenblicklich verkohlen.
    Aber wie ich schon schrieb, sägte und feilte ich mir bereits einen Kamm aus einem Reststück Platinen-Basismaterial. Das hält erstens die Hitze aus, zweitens ist es mechanisch wesentlich belastbarer.

    In der Praxis war ich mit dem Kamm aber nicht zufrieden. Ich bräuchte noch einen zweiten. Jedes Litzenende wird dann durch beide Kämme (die tiefe Schlitze haben) geführt und in der Mitte, zwischen den Kämmen, würde ich mit der Lötspitze rangehen.
    Nun sollen die Stege aber auf voller Länge (4-5mm) zwischen den Litzen sein, um Brückenbildung zu verhindern. Zwischen die beiden tief geschlitzten Kämme aus dünnem Material müsste daher noch ein dritter, weniger tief geschlitzter, aber breiterer Kamm.
    Also drei Kämme, in zwei unterschiedlichen Bauformen.

    Ist jetzt schwer zu erklären, aber wenn man es mal probiert hat, merkt man, wo es in der Praxis klemmt, was im theoretischen Geistesblitz so völlig plausibel und einfach erschien.
    Am besten mal selbt probieren, dann merkst du, wo es überall klemmt!


    @BugFix, ja, natürlich besitze ich eine Heißluftstation (ich repariere Notebook-Mainboards!). Aber die Isolierung der Adern würde bei Heißluftzufuhr unweigerlich verbrutzeln, da wird wohl auch Kapton nicht viel dran ändern.
    Gut, ich könnte mal probieren, die Flachkabel bis zur Abisolierung zwischen zwei Bleche einzuspannen, so dass nur die unisolierten Enden herausschauen.

    Es gibt aber ein Problem, das man erst dann auf dem Schirm hat, wenn man es wirklich mal probiert hat, zwei Flachbandkabel zusammenzulöten: Die abisolierten Enden stehen nicht kerzengerade in reih und Glied (sie bilden also keinen "Kamm"), sondern sie stehen trotz aller Sorgfald beim Abisolieren und Vorverzinnen leicht in unterschiedliche Richtung.
    Richtet man sie manuell aus, so "bewegen" sie sich, sobald Hitze zugeführt wird, weil dann die Isolierung weich wird und sich dort entspannt, wo sie zuvor den stärksten Druck hatte.

    Das mit den zwei kammartigen Alublechen hatte ich gestern übrigens auch schon probiert. Die musste ich nicht mal sägetechnisch herstellen, sondern ich hatte noch leere Trägerbleche für IC-Einzelkontakte (kennt nicht jeder). Die haben zwar das doppelte Rastermaß (100MIL), aber zwei Stück, um eine halbe Position versetzt, ergeben die gewünschten 50MIL, die ich für das Flachkabel brauche.

    Es ist richtig schwer zu erklären, warum es so ist, aber es funktionierte damit nicht gut. Dabei erschien es so plausibel!
    Ich konnte es selbst nicht glauben, dass das so nicht funzt und bog immer wieder an den Stegen herum, veränderte deren Winkel, probierte es von unten druntergelegt, wie von oben draufgesteckt - doch es geht einfach nicht gut.

    Ich glaube, eine weiche Silikonform wäre optimal.
    Die Herstellung ist auf mechanischem Wege aber praktisch unmöglich. Ich könnte mal versuchen, eine zu gießen. Also zuerst ein Negativ aus hartem Material sägen/feilen und dann 'nen Silikonabdruck davon machen.

    Hätte nie gedacht, dass das so ein Zirkus wird!
    Zwei Kabel zusammenlöten - Sache von 5 Minuten ... denkt man.

  • ERLEDIGT --> Raspberry Pi® 2 Model B Advanced-Set 1 GB

    • Code-Jack
    • 28. August 2016 um 23:36

    Nee, geht nicht. Das Flachband ist 120cm lang.
    Daraus wird zunächst die Spule gelötet und dann kommt eine Falttechnik zum Einsatz.
    Die endgültige Spule ist flach, langgezogen, an beiden Enden der Strecke je zweifach gecknickt und in der Länge auch noch wie ein Bogen gewölbt.

    Die Knicke an den Enden will ich eigentlich gar nicht gerne haben, sie sind aber unvermeidbar.
    Noch ist der Aufbau sowieso nur experimentell, aber später sollen es dann 100 Stück werden.

    Da tut es richtig weh, jetzt schon aufwändige Montagevorrichtungen zu bauen, wenn noch gar nicht klar ist, ob die Spulen in der angestrebten Form überhaupt wie gewünscht funktionieren.
    Aber mit geringem Aufwand kriege ich hier partout keine Vorrichtung hin.
    Habe mir vorhin was per Laubsäge und Schlüsselfeilen aus 'nem Stück Platine gebastelt, aber funzt so alles nicht.

    Besser wäre eine Silikonform, denn die ist flexibel, so dass ich gut mit dem Lötkolben dazwischen komme.
    Habe darum (wiederum per Laubsäge) in die Kante einer Silikonmatte kurze Schlitze gesägt. Aber die sind viel zu schmal, eben weil das Material weich ist; da entspricht die Schnittbreite nicht wie gewünscht dem Durchmesser der Säge, sonden das Material reißt eher ein. Der Schitt ist also "unendlich" dünn. Da bekomme ich die Drähte nicht hinein gewürgt.

    Eine erste Spule habe ich inzwischen ganz von Hand gelötet. Hätte bald 'nen Wutanfall bekommen, dabei!
    Irgendwie nimmt die Litze das Lötzinn schon mal nicht sonderlich gut an. Das Vorverzinnen gelingt nur mäßig, trotz Flux. Und beim Versuch, die Enden zusammen zu löten, wird die Verbindung manchmal nicht gut, häufig bilden sich aber Brücken zur Nachbarlitze, die nur schwer wieder zu trennen sind, ohne die Isolierung zu verschmurgeln.

    Ich werde als nächstes dickere Druckbleistiftminen besorgen, in der Hoffnung, mir daraus eine Graphitfom basteln zu können.

  • ERLEDIGT --> Raspberry Pi® 2 Model B Advanced-Set 1 GB

    • Code-Jack
    • 28. August 2016 um 18:52

    Jaaaa, Theorie und Praxis sind aber zwei Paar Schuhe! "Bau mal eben einen Kamm ..."
    Dass man ein Prinzip erfasst hat, heißt noch nicht, dass man es auch mit vertretbarem Aufwand und möglichst ohne Materialkäufe realisieren kann.

    Eben wähnte ich mich bereits auf einem sehr guten Weg:
    Ich nahm eine dünne Spiral-Zugfeder, zog sie auf die korrekte Länge und schraubte sie flach auf eine Holzleiste.
    Dann schmierte ich dort Moltofill hin, so dass sich links und recht der langgezogenen Feder eine kleine Rampe ergab und die Drahtfitzel nicht beliebig tief nach unten in die Feder rutschen können, weil darunter (also in der Feder) halt Moltofill ist.
    Dazu entfernte ich mit einem dünner geschnitzen Zahnstocher, per "Sägebewegung" gerade so viel von dem Moltofill aus den Federwindungen, dass die erste Litze vollständig dort eintaucht, die zweite, oben aufgelegt, aber so gerade eben nicht.
    Da konnte ich nun mit meinem Lötkolben zwar nicht entlang der Reihe ratschen (das würde die oberen Litzenenden doch aufspleißen, aber ich konnte zumindest relativ zügig einzeln verlöten.

    Die böse Überraschung kam, als die die Kabel aus der Feder nehmen wollte.
    Zwar benetzt und hält das Lötizinn nicht an der Feder, aber es wölbte sich gewissermaßen um den Federdraht ein Stück weit herum, so dass die verlöteten Kabel fest an der Feder klemmten.
    Am Ende riss mir die Feder aus dem Moltofill - Versuch gescheitert. :(

    Mit einigen weiteren Bastelversuchen werde ich sicher noch eine brauchbare Lösung finden, aber es ist halt wirklich nicht so einfach, wie man denkt.
    Auch mit 40 Jahren privater und beruflicher Löterfahrung ist man also noch nicht am endgültigen Ende der Lernkurve angelangt, wo man jede zunächst "einfach" erscheinende Lötaufgabe locker aus dem Handgelenk bewältigt!

  • ERLEDIGT --> Raspberry Pi® 2 Model B Advanced-Set 1 GB

    • Code-Jack
    • 28. August 2016 um 17:36

    Sowas meinte ich, mit einer improvisierten Vorrichtung, Xori.
    Aber wenn schon, dann so, dass sich eine kammartige Barriere zwischen allen Adern befindet, so dass ich einfach mit dem Lötkolben a der ganzen Reihe entlang ratschen kann.

    Müsste ich die Adern einzeln fixieren und zusammenlöten, so wie Du es beschreibst, würde das viel zu lange dauern.

    Der "Kamm" müsste hitzefest sein (Silikon / Kapton / Graphit / Edelstahl / Gips), muss Lötzinn abweisen, darf nicht zu schnell verschleißen (nix Gips) und soll mir auch nicht die Lötspitze ruinieren (nix Edelstahl).

    Eine Grahiptplatte von ca. 4mm Stärke, die ich senkrecht fixiere und per Säge mit Kammschlitzen versehe, dürfte sehr gut geeignet sein. Habe ich natürlich nicht da, also muss mit vorhandenem Material improvisiert werden.
    Hauchdünnes Kaptonband habe ich da, mir fehlt aber eine zündende Idee, wie ich daraus mit vertretbarem Aufwand eine geeignete Vorrichtung basteln kann.

    Statt aus Flachbandkabel könnte ich auch eine Flexi-Platine anfertigen lassen, aber die kostet in den benötigten Dimensionen mindestens 60,- EUR. Bei hundert Stück ist das einfach zu teuer.
    Ein von Hand wickeln der Spulen kommt sowieso nicht in Frage, weil die letztlich benötigte Spulengeometrie dazu zu kompliziert ist (Details erspare ich mir mal). Das mit dem Flachbandkabel erschien mir daher als preiswerte und akzeptable Alternative. Aber wenn ich pro Exemplar eine Stunde am Basteln bin, dann sind 100 Stunden futsch. Also 10-12 Tage stramme Idiotenarbeit. Das muss schon irgendwie rationeller bleiben.

    Wenn man in den von mir verlinkten Videos sieht, wie dort vielpolige ICs durch Entlangziehen des Lötkolbens an den Pins ruckzuck verlötet werden, dann entspricht das meiner Idealvorstellung. Das geht aber mit feiner Litze so einfach nicht; oder ich stelle mich zu dumm an. Also muss ich wohl eine Hilfsvorrichtung basteln. doch an der möchte ich auch nicht unbedingt erst erst zwei Tage werkeln müssen.

    Experimentierplatine, so entlang an den Löchern abgesägt, dass sich ein kurzer Kamm ergibt, würde ja theoretisch einigermaßen gehen, wenn das Flachbandkabel nur halb so viele und doppelt so breite Adern hätte.
    Realistisch ist es kaum machbar, da noch jeweils einen Zwischensteg einzusägen.

    Vielleicht kann ich eine kleine Spiralfeder wickeln und auf passende Breite ziehen. Wenn die beim Löten nicht zuviel Hitze wegzieht, könnte das klappen.
    Elegant wäre der Ansatz, nach dem Ausrichten eine stark, aber sorgfältig definiert erhitze Schraube in die Spiralfeder zu stecken, so dass von deren abklingender Restwärme die vorverzinnten (oder mit Lötpaste versehenen) Litzen auf einen Schlag zusammenschmelzen, so dass der Lötkolben gar nicht mehr zum Einsatz kommen muss.

    Ist schon anspruchsvoll!
    Man merkt hier hoffentlich den Unterschied, zu: "ich habe schon mal auf dem Labortisch ein Kabel an 'nen Arduino gelötet - Löten ist einfach!"

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™