MouseHover bei Checkboxen wider Willen

  • eine passendere Überschrift zu meinem Problem fiel mir nicht ein :S

    Ich habe mich nun mal an mein 1. Projekt gewagt und einen Programminstaller erstellt. ( Bitte Nachsicht, ich bin mir sicher, das man den mit 80 % weniger Code hätte erstellen können, Bugfix dürfte seine wahre Freude darüber haben, 2000 Zeilen Code mittels Arrays in etwa 100 Zeilen zu packen, Hilfestellung durchaus willkommen :D )

    Zu meinem Problem.

    Beim Start des Programms wird das Vorhandensein diverser Software auf betreffendem PC überprüft. In Abhängigkeit dessen was gefunden wird, unterscheidet das Programm nach "nicht vorhanden", "vorhanden, aber veraltet" oder "aktuell".

    Entsprechend werden Checkboxen gesetzt. Wenn "aktuell" ist die Checkbox unchecked und hidden, "nicht aktuell" = unchecked und unhidden, "fehlt" = checked.

    So ist fehlende Software zum Installieren vormarkiert, bei nicht aktueller Software kann entschieden werden, ob installiert werden soll.

    Wird selektierte Software installiert, wird nach Abschluss jedes installierten Programmes der Status entsprechend neu geprüft und aktualisiert.

    Soweit funktioniert das auch alles.

    Da eine Deinstallation seitens Programm nicht vorgesehen ist ( reicht zum Testen die Systemsteuerung ) , würde das Programm eine Deinstallation nicht bemerken, ohne das Programm neu zu starten. Daher habe ich mir hilfsweise einen Refreshbutton gemacht, welcher die Funktionen zum Prüfen des Status durchläuft.

    Auch das macht er ( wenn programmtechnisch sicher nicht "optimal" gelöst ).

    Nun habe ich im Testbetrieb aber festgestellt, das es zu mir nicht erklärbaren Effekten kommt, deren Ursache mir unbekannt ist. Habe ich beispielsweise selektiv ausgewählt, was er installieren soll und ich danach den Refreshbutton drücke ( was eigentlich nicht nötig wäre ), setzt er mir logischerweise wieder da einen Haken in die Checkbox, wo der Status "nicht installiert" ist, was ja auch richtig ist.

    Fahre ich nun mit dem Mauszeiger über die Checkboxen, welche er nun wieder markiert hat, verschwinden diese wie von Geisterhand, ohne von mir gezielt angeklickt zu werden. Das ist ärgerlich, zumal er trotzdem die Programme installieren würde, deren Haken einfach verschwinden.

    Mir geht es im Moment vorrangig darum, ob dieses Phänomen bekannt ist, oder ob ihm ggf. eine Opt-Anweisung fehlt, es ein Bug der Version ist ( mit Beta noch nicht getestet ) , es programmiertechnisches Unvermögen sein könnte, er unter manchen Unständen ein eigenständiges "MouseHover" macht, oder ob man bei Checkboxen noch irgendwelche Stati machen muss; in manchen Programmiersprachen ( FoxPro, VB, C++ etc. ) gibt es wohl das Attribut "refresh" um eine Änderung einer Checkbox zu manifestieren. ?(

    Ich hänge gleich mal den Code an, für den Spoiler dürfte er zu groß sein. Auf die Programme selbst verzichte ich dabei, das Paket hat derzeit gepackt runde 500 MB ( ich lass lediglich Flash für IE mal drauf )

    Ich habe das Programm gesplittet, Hauptprogramm mit den beiden Fenstern, und die Funktionen als UDF, die Icons als DLL. Auf die zugehörigen Grafiken verzichte ich, da sie firmenspezifische Inhalte haben.

    ( Das Programm soll eigentlich derzeit für WinXP SP3 sein, da ich aber unter Win7 teste, hab ich die Plausiblitätsprüfung nach OS derzeit nicht aktiv )


    Zusammenfassend kurze Anleitung zur Nachstellung des Problems. Aufruf des Programms, deaktiveren eines Hakens ( z.B. Adobe Reader ) , Refreshbutton drücken, Haken müßte wieder drin sein, mit der Maus über entsprechenden Checkbox fahren, Haken müßte verschwinden.

  • Hi Prickel,

    so wie ich das beim überfliegen dieses umfangreichen Quellcodes gesehen habe machst du einen entscheidenden Fehler. Der Refreshbutton ruft die Funktionen aus der UDF auf, ich nehm nun mal _Runtime_1 zum Beispiel. Dort und auch in allen anderen der Funktionen erstellst du unter anderem die Checkbox, sowie zig andere GUI Elemente. Das Problem ist hierbei jedoch, dass diese ja bereits existieren. du erstellst mit jedem mal den du diesen Button betätigst die selben Controls erneut. Das hat zur Folge, dass die neuen Controls über den alten liegen, aber beide noch da sind. Das führt dann ggf. zu Anzeigefehlern.

    Du solltest das also ändern und jedes Control nur einmalig beim initialisieren der GUI erstellen. In den UDF Funktionen prüfst du dann nur noch ob die Elemente benötigt werden oder nicht und machst diese dann unsichtbar, deaktiviert , unchecked, anderer label text oder was auch immer du gerne hättest. Damit du den Zustand von bestehenden Elementen nachträglich verändern kannst ist es zwingend notwendig die zugehöriigen ControlIDs in Variablen oder in deinem Fall besser in Arrays zu speichern. Statt GUICtrlSetState(-1, $GUI_DISABLE) verwendest du dann eben GUICtrlSetState($CheckRun1, $GUI_DISABLE)

  • Hier mal noch einige Verbesserungsvorschläge um deinen Code radikal zu vereinfachen und besser erweiterbar zumachen:

    1. Benutze eine ini Datei um zu bestimmen welche Programme in der GUI vorhanden sein sollen, wie diese heissen und wo sich die Installdatei befindet, dadurch kannst du später einfach neue Software hinzufügen oder die Version ändern ohne den GUI Aufbau im Quellcode anzupassen.

    Code
    [Runtimes]
    Adobe Flash Player 10 Active X=Pfad zur Installdatei|ggf. auch noch id des icons, falls dieses nicht aus der installdatei eingelesen wird
    Adobe Flash Player 10 Plugin=...
    ....
    [Tools+Apps]
    Adobe Reader X=...
    ...
    [...]

    2. Benutze ein 2D Array zum speichern aller GUI Relevanten Dinge, dazu zählen Sachen wie der Labeltext den du aus der ini ausliest, als auch die Controlid des Labels, die Controlid der zugehörigen Checkbox usw.
    Beispiel Array könnte so aufgebaut sein

    Code
    ...........Spalte0|Spalte1|Spalte2|Spalte3...
    Zeile 0: -------------------------------------------------
    Zeile 1: Runtimes|Adobe Flash Player 10 Active X|Pfad exe|Pfad Icon|Controlid Label|Control ID Checkbox
    Zeile 2: Runtimes|Adobe Flash Player 10 Plugin|Pfad exe|Pfad Icon|Controlid Label|Control ID Checkbox
    Zeile 3: Tools+Apps|Adobe Reader X|Pfad exe|Pfad Icon|Controlid Label|Control ID Checkbox

    3. Arbeite mit Schleifen um die Controls zu erstellen und speichere die ID's im dafür gedachten Array. Das hat den Vorteil, dass du unmengen an nichtssageneden Variablen einsparst und ausserdem nur wenige Zeilen Code für hunderte Controls benötigst.

    [autoit]


    global $aControls[$AnzahlGefundenerIniSchluessel][$AnzahlDerSpaltenDieDugerneHabenWillst]

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

    for $i=1 to ubound($aControls)-1
    if $aControls[$i][0]="Runtimes" then $left = 50
    if $aControls[$i][0]="Tools+Apps" then $left = 250
    if $aControls[$i][0]=".NET" then $left = 450
    ;usw

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

    $aControls[$i][4]=guictrlcreatelabel($acontrols[$i][1],$left,$i*30,100,20) ; hier erstellst du ein Label mit dem Namen den du zuvor aus der ini Datei ausgelesen und in [$i][1] gespeichert hast, dabei musst du die Koordinaten des Controls durch $i bestimmen lassen, so dass die controls je nach $i Wert eben um soundsoviel Pixel nach unten verschoben werden
    $aControls[$i][5]=guictrlcreatecheckbox("",$left+120,$i*30)
    next

    [/autoit]

    Wenn du da etwas Hirnschmalz reinstecks kannst du die GUI Erstellung schön vereinfachen. Mein Beispiel ist hier noch fehlerhaft/unvollständig, aber es geht ja nur darum zu zeigen wie man sowas machen kann.

    Gut aber ich will dir das nicht aufdrängen, denn es wäre sicher erhebliche Arbeit um deinen bestehenden Code daraufhin zu verändern. Über soetwas hätte man sich besser vorher Gedanken gemacht. Vielleicht hast du ja mal Lust und Zeit dich in dynamische GUI Erstellung reinzuarbeiten und kannst das dann irgendwann mal anpassen. Für zukünftige Änderungen/Erweiterungen fährst du mit den hier erklärten Methoden jedenfalls besser.

    Einmal editiert, zuletzt von misterspeed (12. Juli 2011 um 22:28)

  • Hui, ein Haufen konstruktiver Ansätze :thumbup: , danke.

    Zum grundsätzlichen Aufbau, da ist sicherlich noch viel Potential für Verbesserungen, die habe ich aber erst mal zurück gestellt, um erst einmal eine "lauffähige" Version zu bekommen. Für flexibleres Ändern veränderbarer Punkte wie z.B. Versionsnummern oder Programmaufrufe sind sicherlich ini-Dateien oder eine SQ-Lite Datenbank hilfreicher, da muss ich mich aber erst einmal hineinarbeiten ( >= Version 4.0 :D ). Allerdings sind Deine Ideen und Beispiele bzgl. Arrays sehr viel versprechend, in der Richtung hatte ich mal einen Prototyp gemacht im Zusammenhang mit Listviews.

    (Edit, beim 2. durchlesen Deiner Beispiele ist mir auch der Hinweis Deines 1. Beispiels mit der ini-Datei aufgefallen, muß sagen, gefällt :) )

    Dein Eindruck ist ganz sicher richtig und mein Ansatz war einfach und sicherlich auch bequem. Für das Herausfinden eines Programmstatusses habe ich ja in der UDF entsprechend auch je eine Funktion, die entsprechend Rückgabewerte liefern und an Hand dessen einen Status liefern. Meine Hoffnung dabei war, das mit durchlaufen der Funktion ein bestimmter Status geschaffen wird.

    Bei der Überlegung der Refreshfunktion kam mir der Gedanke bei der Umsetzung, hier auf die vorhandene Funktion zurück zu greifen, um ein erneutes Auslesen des Status zu erhalten. Ich habe/hatte dabei vorausgesetzt, das damit die alten Variablenwerte neu gesetzt werden, da mir adhoc auch kein adäquater Befehl a la Guictrldelete($CheckRun1, $GUI_DISABLE) bekannt wäre, der sicher gestellt hätte, das kein alter Status noch im Speicher hängen könnte.

    Dein Ansatz mit den Arrays gefällt mir, Du hast das ich glaube so gut beschrieben, das ich das glaub umsetzen zu können :)

    Hoffnung hab ich aber noch immer auf eine gute Arraylösung, die rund 20 - 25 gleich aufgebauten Einzelfunktionen à ca. 50 Zeilen in eine Arrayfunktion verpackt zu bekommen , na gut, geplant für Version 3.0 :D ( Dein Beispiel 3 )

    Dein Argument ist vollkommen richtig, das man den Aufbau zu Beginn in die Richtung Deiner Beispiele hätte aufziehen sollen. Auf Grund meiner noch recht bescheidenen Kenntnisse hätte ich aber das Gefühl gehabt, mich damit etwas zu übernehmen und recht früh an meine Grenzen zu stoßen, sehe aber viel Potential auf Grund guter Beispiele Deinerseits, einen (fast) funktionierenden Stand in diese Richtung zu optimieren, wenngleich es sicherlich den aufwendigeren Weg bedeutet. Ich dachte einfach, ich fang mal mit dem Golf 1 an, nicht gleich mit dem Golf 6 [Blockierte Grafik: http://kaffeedateseminar.de/_chat/img/emoticons/mocking.gif]

    Dank Dir für prima Ansätze :)

    Einmal editiert, zuletzt von Prickel (12. Juli 2011 um 23:38)

  • Ich hab auch mal so angefangen, doch gerade bei derart umfangreichen GUI's stösst man eben schnell an die Grenzen. und es kostet unmengen an Zeit sowas dann nachträglich wieder zu ändern. Ich würde heute kein umfangreiches Projekt mehr anfangen ohne mir vorher Gedanken über eine optimalen Funktionsaufbau zu machen, man benötigt da zwar Zeit dafür letzten Endes hat man aber ein flexibleres und einfacheres Ergebnis und spart sich zukünftig die Zeit bei Änderungen / Erweiterungen.

    Unabhängig von meine vorschlägen zur dynamischen GUI Erstellung hast du aber in deiner UDF schon durch simple Zusammenfassung der reduntanten Funktionen erhebliches Optimierungspotential. So wie ich das überflogen habe unterscheiden sich die Funktionen sogut wie garnicht, lediglich durch die ControlID und die Suchbegriffe / Versionsnummern. Ich hab dir mal anhand von runtimes1-14 ein Beispiel erstellt wie du alle 14 Funktionen durch eine einzige ersetzen kannst, ganz ohne Arrays und komplett an deinen bisherigen Code angelehnt:

    Spoiler anzeigen
    [autoit]


    #cs
    $checkrun 1-14 erstellst du in du in der haupt au3 ganz oben da wo du auch die restlichen gui elemente erstellst, also hier:
    ; Abfrage 1. Anwendungen
    ;
    _NET_1()
    _NET_2()
    _NET_3()
    _NET_4()
    _NET_5()
    _Runtime_1() ; statt dem funktionsaufruf machst du hier die ganzen ctrlcreates und setdata, setcolor usw, eben das was ich dir unten aus der neuen runtime entfernt habe....
    _Runtime_2()
    _Runtime_3()
    _Runtime_4()
    _Runtime_5()
    _Runtime_6()
    _Runtime_7()
    _Runtime_8()
    _Runtime_9()
    _Runtime_10()
    _Runtime_11()
    _Runtime_12()
    _Runtime_13()
    _Runtime_14()
    _Anwendung_1()
    _Anwendung_4()
    _Anwendung_5()
    _Anwendung_7()
    _Anwendung_8()
    _Office_6()

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

    ;
    ; ********************************************************************************************************************************************************************************************************************************
    ; Ende Anwendungen

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

    ACHTUNG: hier dann einmalig gleich die Funktion alleRuntimesChecken aufrufen, damit bei Programmstart nach Controlerstellung alle Checkboxen gesetzt werden...

    alleruntimeschecken()

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

    #ce

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

    Func alleRuntimesChecken() ; das rufst du dann z.b. beim button druck refresh auf, bzw auch einmalig nachdem du die controls oben in der haupt au3 erstellt hast
    _Runtime($uRunSuch1,$uRunAktVer1,$CheckRun1) ; du übergibst der Funktion alle Daten die sie braucht, somit kann die selbe Funktion für alle Controls verwendet werden
    _Runtime($uRunSuch2,$uRunAktVer2,$CheckRun2)
    _Runtime($uRunSuch3,$uRunAktVer3,$CheckRun3)
    _Runtime($uRunSuch4,$uRunAktVer4,$CheckRun4)
    _Runtime($uRunSuch5,$uRunAktVer5,$CheckRun5)
    _Runtime($uRunSuch6,$uRunAktVer6,$CheckRun6)
    _Runtime($uRunSuch7,$uRunAktVer7,$CheckRun7)
    _Runtime($uRunSuch8,$uRunAktVer8,$CheckRun8)
    _Runtime($uRunSuch9,$uRunAktVer9,$CheckRun9)
    _Runtime($uRunSuch10,$uRunAktVer10,$CheckRun10)
    _Runtime($uRunSuch11,$uRunAktVer11,$CheckRun11)
    _Runtime($uRunSuch12,$uRunAktVer12,$CheckRun12)
    _Runtime($uRunSuch13,$uRunAktVer13,$CheckRun13)
    _Runtime($uRunSuch14,$uRunAktVer14,$CheckRun14)
    EndFunc

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

    Func _Runtime($uRunSuch,$uRunAktVer,$CheckRun) ; Für alle runtimes bzw falls die funktion auch zu net ud dem anderen kram identishc ist kannste das für alles benutzen hab mir die funktionen nicht im detail angesehen...
    $iEval = 1
    $iSearch = 0
    $sVersion = ""
    $sDisplay = ""

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

    While 1
    $sCurrent = RegEnumKey($uRegUninst, $iEval)
    If @error Then ExitLoop
    $sKey = $uRegUninst & $sCurrent
    $sDisplay = RegRead($sKey, "DisplayName")

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

    If StringRegExp($sDisplay, ".*" & $uRunSuch & ".*") Then ; $uRunSuch1 durch $uRunSuch ersetzt, welches beiom Funktionsaufruf übergeben wird
    $sVersion = RegRead($sKey, "DisplayVersion")
    $iSearch = 1
    If $iSearch = 1 Then
    If _VersionCompare($uRunAktVer, $sVersion)=-1 or _VersionCompare($uRunAktVer, $sVersion)=1 Then ; $uRunAktVer1 durch $uRunAktVer ersetzt, wird beim Aufruf übergeben
    GUICtrlSetState($checkRun, $GUI_ENABLE) ; $checkRun1 durch $checkRun ersetzt, die kontrollerstellung hier komplett entfernt, das machste in der main au3
    Else
    GUICtrlSetState($checkRun, $GUI_DISABLE) ; $checkRun1 durch $checkRun ersetzt, die kontrollerstellung hier komplett entfernt, das machste in der main au3
    EndIf
    ExitLoop
    ElseIf $iSearch = 0 Then
    ExitLoop
    EndIf
    EndIf
    $iEval += 1
    WEnd
    If $iSearch = 0 Then
    GUICtrlSetState($CheckRun, $GUI_CHECKED)
    EndIf
    EndFunc

    [/autoit]

    Das ganze ist nicht getestet und ich weiss gerade auch nicht wie du die Icons setzt, ich glaube du brauchst zusätzlich zum setstate für die checkboxen auch noch ein setdata oder so für die statusicons, sofern die sich je nach suche unterscheiden sollten, aber dein Code ist mir zu umfangreich um mich durch sämtliche Funktionen zu wühlen um 100% zu verstehen wo du was und vorallem wie du das machst. Denke mit dieser Beispielzusammenfassung kannst du das auch selbst umsetzen. Sollte danach noch Wunsch zur Optimierung bestehen, z.B. über , ini Files, Arrays und zugehöroge Schleifen kannst du ja deinen optimierten und von redundanz bereinigten Code nochmal posten. Doppelte Funktionen braucht man nicht! Immer wenn du große Passagen per C&P übernimmst ist das ein Zeichen, dass du das auch mit einer einzigen Funktion hättest realisieren können. Das ist denke ich eine sehr einfach Aufgabe die du jetzt ohne großes Einarbeiten in dir noch fremde Themenbereiche erledigen kannst. Viel Spass und Erfolg beim kürzen deines Quellcodes ;)

  • ... auch nicht wie du die Icons setzt, ....

    kurz und spontan, bevor ich Deinen Source verinnerliche,

    [autoit]

    $uLabelRun1 = GUICtrlCreateLabel($uRunAnz1 & " " & $sVersion, 70, 130, 200, 17)
    GUICtrlSetFont(-1, 8, 100, 1, $uFontGui)
    GUICtrlCreateIcon($uFileIconLib, 9, 23, 128, 16, 16)
    GUICtrlCreateIcon($uFileIconLib, 11, 50, 128, 16, 16)

    [/autoit]

    die 1. Ziffer ( 9 ) bei "GUICtrlCreateIcon($uFileIconLib, 9, 23, 128, 16, 16)" , also die, welche vor den Koordinaten des Controlls steht, definiert lediglich die Icon-ID, welche er sich aus der pp-update.dll holt, also das 9. Icon. Damit verhindere ich nur, das Icon isoliert einzustellen und somit einen großen Fundus an Icons bereitstellen zu müssen.

    Ich weiß, das ich das auch noch ändern sollte, bzw. durch eine Variable ersetzen sollte, und den Fokus der Variable auf die ini-Datei setzen sollte, um flexibler Änderungen zu ermöglichen. Es ist zwei mal drin, 1. ist das entsprechende Programmicon, 2. das Statusicon.

    Dank IcoFX ist das Handling von Icons in DLL's fix zu handeln.

    So, nun lasse ich Dein Beispiel mal sacken und hoffe auf ein gutes Händchen bei der Umsetzung, so das ich, hoffe ich, bald eine deutlich reduzierte und verbesserte Variante einstellen kann.

    Ein großes Danke schön schicke ich aber schon einmal voraus. :)

  • Ok dann hier noch die Ergänzung zum Beispiel mit den Icons. Da das Programm Icon sich nicht zur Laufzeit ändern muss brauchste da wie gehabt keine Variable. Beim Status Icon brauchst du hingegen eine. Du gibst erstmal allen Status Icons das selbe Bild beim erstellen. In deiner runtime Funktion tauscht du das bild je nach Status dann aus. Das machst du dann so:

    Spoiler anzeigen
    [autoit]


    ; Main.au3
    ;...
    $CheckRun1=guictrlcreatecheckbox(...)
    guictrlcreateicon(...) ; das unwichtige Programmicon, bleibt immer gleich, muss also wohl auch nicht in der status funktion erneuert werden, daher nicht notwendig die controlid zu speichern
    $StatusIconRun1=guictrlcreateicon(...) ; hier dann z.B. standardmässig erstmal ein rotes X... oder was auch immer du im Angebot hast in der dll
    ;...

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

    ; UDF:

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

    Func alleRuntimesChecken()
    _Runtime($uRunSuch1,$uRunAktVer1,$CheckRun1, $StatusIconRun1) ; icon control id muss nun auch übergeben werden
    _Runtime($uRunSuch2,$uRunAktVer2,$CheckRun2, $StatusIconRun2)
    ;...
    endfunc

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

    Func _Runtime($uRunSuch,$uRunAktVer,$CheckRun,$StatusIconRun) ; icon control id wird nun benötigt
    ;...
    ;hier hattest du ja deine if konstruktion, da setzt du nun je nach statusfall das Icon neu
    GUICtrlSetImage ( $iconStatusRun, $uFileIconLib, 9)
    ;...
    endfunc

    [/autoit]

    EDIT:
    Ahja so wie ich das grad sehe brauchst du in der runtime Funktion dann auch noch die ctrlid des Labels um es mit setstate du deaktivieren, also die Funktion noch um einen 5. Parameter ergänzen, so wie ich es gerade für das Status Icon gemacht habe.
    Die Funktion alleRuntimesChecken könnte man btw in einer 3 zeiligen For Schleife unterbringen wenn alle Controlids, Namen und Versionsnummern in einem Array gespeichert wären, so wie im ersten Verbesserungsvorschlag von mir umrissen, aber denke mit der Funktionszusammenfassung hast du schonmal einiges erreicht und deine Quellcode locker auf ein drittel geschrumpft. ;)

    Einmal editiert, zuletzt von misterspeed (13. Juli 2011 um 19:29)

  • Grundsätzlich scheint es zu gehen, aber ich doktor schon den ganzen Abend an der Version. 8|

    Programmname liefert er sauber zurück, aber bei der Versionsinfo liefert er logischerweise nur einen Rückgabewert zurück, nämlich den letzten.

    Da werde ich wohl nicht drum herum kommen, das Auslesen der Version in ein Array zu setzen :wacko:

  • Ich hab das ehrlich gesagt nicht ganz durchblickt wie du die Versionsnummern aus der Registry ausliest. Soweit ich das richtig verstanden hab ist das aber doch immer gleich und wird nur durch die Variable $uRunSuch beeinflusst. Wenn das seither funktioniert hat muss das ja eigentlich auch mit der Zusammenfassung noch funktionieren, sofern du daran gedacht hast diese Variable umzubenennen wie in meinem Beispiel. Wenn du natürlich da noch $uRunSuch1 drin stehen hast liefert dir die funktion auch immer die Versionsnummer des ersten Programms.

  • Ich hab das ehrlich gesagt nicht ganz durchblickt wie du die Versionsnummern aus der Registry ausliest.

    Das Prinzip ist so aufgebaut. Ich habe zwei Programmname im Source, der 1. ist der, der als Label angezeigt wird, der 2. der, der in der REG als Suchstring gesucht wird. Bei der Version gebe ich die aktuelle Version vor und vergleiche sie mit dem Rückgabewert der REG in Abhängigkeit des gefundenen Programmnamens.

    Für beides nutze ich den UNINSTALL-Zweig, weil da eigentlich mittlerweile alle Setups Programmname und Version zuverlässig reinschreiben.

    Wenn er über die Funktion eine Übereinstimmung der Suchvariable (REG "Displayname") findet, sucht er mit der Suchvariable $Version ( REG "Displayversion" ) die installierte Version und vergleicht sie mit dem Variablenwert in der UDF mittels _VersionCompare.

    [autoit]

    $sDisplay = RegRead($sKey, "DisplayName")

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

    If StringRegExp($sDisplay, ".*" & $uRunSuch & ".*") Then
    $sVersion = RegRead($sKey, "DisplayVersion")
    $iSearch = 1
    If $iSearch = 1 Then
    If _VersionCompare($uRunAktVer, $sVersion)=-1 or _VersionCompare($uRunAktVer, $sVersion)=1 Then

    [/autoit]