Beiträge von BugFix
-
-
Im Normalfall vermeide ich die Arbeit mit der Registry, und wenn ich es dann doch mal nutze, eigentlich nur lesend. Nun wollte ich aber selbst einen Eintrag erstellen:
Folgendes Bsp.
AutoIt#RequireAdmin $iSucc = RegWrite('HKEY_LOCAL_MACHINE\SOFTWARE\BugFix', 'Test', 'REG_SZ', 'Mein-Wert') MsgBox(0, 'RegWrite', "$iSucc --> " & $iSucc & @LF & "#Error: " & @error)Ich starte das Skript, die Benutzerkontensteuerung fragt an - ich bestätige und Regwrite wird laut Return-/Errorwert auch erfolgreich durchgeführt.
In der Registry ist aber keine Änderung sichtbar! 
Aber ein RegRead('HKEY_LOCAL_MACHINE\SOFTWARE\BugFix', 'Test') zeigt, dass der Wert tatsächlich eingetragen wurde.

Weder ein Aktualisieren, noch ein Neustart des Reg-Editors veranlassen diesen, die Änderung anzuzeigen.
Ist das bei euch ebenso? Ich finde das schon recht verwirrend.
EDIT:
Auch nach einem PC-Neustart ist der Wert abfragbar, aber nicht im Reg-Editor sichtbar.
EDIT#2
Ich habe es gefunden. Obwohl ich explizit NICHT den 64-Bit Zweig angegeben habe, wird ungefragt dorthin geschrieben. Das ist natürlich Mist.
Wie kann ich dann definieren, dass nicht im 64-Bit Zweig geschrieben werden soll?
Laut Hilfe dürfte das nicht passieren:
When running on 64-bit Windows if you want to write a key or value specific to the 64-bit environment you have to suffix the HK... with 64 i.e. HKLM64.
-
Nö! Bei mir erscheint immer [Neuer Ordner] im Dialog.
OK, damit habe ich nicht gerechnet: Es gibt keinen Button, sondern oben in der Menüleiste steht (nahezu unsichtbar, da absolut flat) "Neuer Ordner". Da hätte ich die nächsten 20 Jahre nicht hingeschaut, schließlich hat das Ding da null Zusammenhang mit dem Dialog.

Am Besten noch einen Erkennung dafür einbauen, die einen roten Rahmen drum zeichnet.
Gut, nun bin ich schlauer - aber nicht einen Deut zufriedener.

-
AutoIt
$sPath = FileSelectFolder('Pfad Auswählen oder Erstellen', @ScriptDir, $FSF_CREATEBUTTON, "C:\__PFAD__")Unter Windows 10 wird das Flag $FSF_CREATEBUTTON mal locker ignoriert. Ein "Create"-Button erscheint nicht im Dialog und somit kann man den Nutzer keine Ordner erstellen lassen. Ich bin hellauf begeistert.

Version: Windows 10 Pro, 21H1
Könnt ihr das verifizieren?
Edit
Zitat von HilfeFunction FileSelectFolder
The new Vista+ dialog style is used if possible, regardless of the Use New Dialog Style flag. With the Vista dialog style the edit control and create folder buttons are always shown, ignoring the flags parameter
Auch nicht zutreffend unter Win10.
-
Das ganze bekräftigt mich in meiner Meinung, dass Leerzeichen in Dateinamen nichts verloren haben. Es war nicht alles schlecht in den 1980er Jahren.

OK, 8.3 Dateinamen muss ich auch nicht wieder haben, aber die sonstigen damaligen Restriktionen für Pfade empfand ich schon als sinnvoll. Mir kommen heute noch Umlaute in Pfadangaben "falsch" vor.

-
Gibt viele Wege.
Du kannst z.B. mit Stringsplit (Trennzeichen: \) die Pfadangabe splitten. Der letzte Wert im Array ist dann der Ordnername.
Wenn ich mich recht erinnere, bin gerade nicht am Rechner, gibt es auch die Funktion _PathSplit, die macht dasselbe.
Du kannst auch mit StringInStr den letzten Backslash suchen und bis zu dieser Position abschneiden (StringTrimLeft).
-
Allerdings bleibt das Problem, dass sich das GUI beim verschieben des Fensters zerschießt und auch so bleibt, auch wenn ich ein anderes GUI aufrufe (Untermenü).
Naja, der Ex-Style deiner Child-Windows ist falsch.
So klappt es:
(Vermeide Globale Variablen, wenn sie nicht zwingend erforderlich sind)
AutoIt
Alles anzeigen#include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WindowsConstants.au3> #include <GuiRichEdit.au3> #include <ColorConstants.au3> example() Func example() Local $hGUI, $Menu1, $OpenGUI1, $OpenGUI2, $Menu2, $About Local $hGUI1, $idMsgButton, $idButton1 Local $hGUI2, $idButton2 Local $hAbout, $idAboutBox, $btOK $hGUI = GUICreate("GUI", 200, 217, 100, 100, Default, BitOR($WS_EX_COMPOSITED,$GUI_WS_EX_PARENTDRAG)) $Menu1 = GUICtrlCreateMenu( "GUI" ) $OpenGUI1 = GUICtrlCreateMenuItem( "Open GUI1", $Menu1 ) GUICtrlSetState($OpenGUI1, $GUI_DISABLE) $OpenGUI2 = GUICtrlCreateMenuItem( "Open GUI2", $Menu1 ) $Menu2 = GUICtrlCreateMenu( "Help" ) $About = GUICtrlCreateMenuItem( "About", $Menu2 ) ;GUI1 $hGUI1 = GUICreate("GUI 1", 200, 200, 0, 0, BitOR($WS_POPUP,$WS_CHILD), $WS_EX_MDICHILD, $hGUI) $idMsgButton = GUICtrlCreateButton("Msgbox 1", 10, 10, 80, 30) $idButton1 = GUICtrlCreateButton("Show GUI 2", 10, 60, 80, 30) ;GUI2 $hGUI2 = GUICreate("GUI 2", 200, 200, 0, 0, BitOR($WS_POPUP,$WS_CHILD), $WS_EX_MDICHILD, $hGUI) $idButton2 = GUICtrlCreateButton("Show GUI 1", 10, 10, 80, 30) ;About $hAbout = GUICreate("About", 100, 100, 10, 10, BitOR($WS_POPUP,$WS_THICKFRAME), $WS_EX_MDICHILD , $hGUI) $idAboutBox = _GUICtrlRichEdit_Create( $hAbout, "About", 0, 0, 100, 70, BitOR( $ES_READONLY, $ES_MULTILINE ) ) _GUICtrlRichEdit_SetCharColor( $idAboutBox, _WinAPI_SwitchColor( $COLOR_RED ) ) _GUICtrlRichEdit_AppendText( $idAboutBox, @CRLF & "Hallo Welt" ) $btOK = GUICtrlCreateButton('OK', 10, 75, 80, 20) GUISetState(@SW_SHOW, $hGUI) GUISetState(@SW_SHOW, $hGUI1) Local $aMsg While 1 $aMsg = GUIGetMsg(1) ; Use advanced parameter to get array If Not IsHWnd($aMsg[1]) Then ContinueLoop ; preventing subsequent lines from processing when nothing happens Switch $aMsg[1] ; check which GUI sent the message Case $hGUI Switch $aMsg[0] Case $GUI_EVENT_CLOSE ; If we get the CLOSE message from this GUI: $g_hGUI1 ... ExitLoop ; ... exit the loop and thus exit the program Case $OpenGUI1 GUISetState(@SW_HIDE, $hGUI2) GUISetState(@SW_SHOW, $hGUI1) GUICtrlSetState($OpenGUI2, $GUI_ENABLE) GUICtrlSetState($OpenGUI1, $GUI_DISABLE) Case $OpenGUI2 GUISetState(@SW_HIDE, $hGUI1) GUISetState(@SW_SHOW, $hGUI2) GUICtrlSetState($OpenGUI2, $GUI_DISABLE) GUICtrlSetState($OpenGUI1, $GUI_ENABLE) Case $About GUISetState(@SW_SHOW, $hAbout) EndSwitch Case $hGUI1 Switch $aMsg[0] ; Now check for the messages for $g_hGUI1 Case $idMsgButton MsgBox($MB_OK, "MsgBox 1", "Test from GUI 1") Case $idButton1 GUISetState(@SW_HIDE, $hGUI1) GUISetState(@SW_SHOW, $hGUI2) GUICtrlSetState($OpenGUI2, $GUI_DISABLE) GUICtrlSetState($OpenGUI1, $GUI_ENABLE) EndSwitch Case $hGUI2 Switch $aMsg[0] ; Now check for the messages for $g_hGUI2 Case $idButton2 GUISetState(@SW_HIDE, $hGUI2) GUISetState(@SW_SHOW, $hGUI1) GUICtrlSetState($OpenGUI2, $GUI_ENABLE) GUICtrlSetState($OpenGUI1, $GUI_DISABLE) EndSwitch Case $hAbout If $aMsg[0] = $btOK Then GUISetState(@SW_HIDE, $hAbout) EndSwitch WEnd EndFunc ;==>example -
Das Problem ist, dass wenn die Funktion in dem beschriebenen Szenario (S. Fall 2) erneut aufgerufen wird IMMER DIE 0 zurückgegeben wird, obwohl die Variable $newPath0, die retuniert wird, eine Pfadangabe enthält. Dass ist mein Problem, zu dem ich keinen Lösungsansatz habe.
Das ist durch die Rekursion!!! Nach Beendigung des 2.ten Funktionsaufrufes (der einen gültigen Pfad ergibt), wird der erste Funktionsaufruf fortgesetzt!!! - Das ist das Wesen rekursiver Funktionen, deshalb mein Hinweis, dass man da verflixt aufpassen muss.
Übrigens hatte Oscar dir ja die beste Lösung bereits serviert.
Hier mal noch ein paar Ausgabezeilen mehr in deiner Funktion. Teste das, dann wird es dir vielleicht klar.
AutoIt
Alles anzeigenFunc _setTargetPath( $mode ) If StringIsInt( $mode ) And StringLen( $mode ) = 1 And StringRegExp( $mode, '[0-1]' ) Then ; Prüfung des Parameters If $mode = 0 Then ; Aufruf beim Hinzufügen eines neuen Eintrages Local $newPath0 = FileSelectFolder( "Zielverzeichnis auswählen", $targetPath ) If $newPath0 = "" Then ; Es wurde KEIN ZIELPFAD ausgewählt Return $newPath0 ElseIf $newPath0 <> "" And __validatePathAccess( $newPath0 ) Then ; Es wurde ein KORREKTER ZIELPFAD ausgewählt ConsoleWrite( @CRLF & " Rueckgabewert vor RETURN = >>>" & $newPath0 & "<<< (ElseIf-Zweig)" & @CRLF & @CRLF ) Return $newPath0 ; jetzt springt der Codeablauf an die Position nach dem rekursiven Aufruf ####### !!!! ######## ; PROBLEM: Wenn _setTargetPath() erneut aufgerufen wird, nachdem die Funktion unmittelbar davor in ; den Else-Zweig (Ungenügende Zugriffsrechte für das ausgewählte Verzeichnis) gesprungen ist, ; dann wird der eigentliche Inhalt von $newPath0 als Rückgabewert ignoriert. Obwohl ein ; korrektes Verzeichnis (Pfadangabe oder "") ausgewählt wurde und die betreffende Variable ; $newPath0 unmittelbar vor dem RETURN den korrekten Wert ausgibt. Stattdessen wird eine 0 (Null) ; zurückgegeben und in _aufrufendeFunktion() an $targetPath übergeben. ; Dieses Verhalten gilt unabhängig davon, ob _setTargetPath() mit dem Parameter 0 oder 1 aufgerufen wird. Else ; Ungenügende Zugriffsrechte für das ausgewählte Verzeichnis ConsoleWrite('fehlende Zugriffsrechte in Pfad: >>' & $newPath0 & '<<' & @CRLF) ; ####### !!!! ######## _setTargetPath( 0 ) ; Sollte das ausgewählte Verzeichnis nicht über die ausreichenden Zugriffsrechte ; verfügen (Schreibrechte), dann wird dem Benutzer die Verzeichnisauswahl erneut ; angeboten (durch erneuten Aufruf der Funktion), bis ein zulässiges Ergebnis (valide Pfadangabe ; oder ein leeren String) zurückgegeben werden kann. ConsoleWrite('Jetzt wird der erste Funktionsaufruf fortgesetzt!, "$newPath0" = ' & $newPath0 & @CRLF) ; ####### !!!! ######## EndIf ElseIf $mode = 1 Then ; Aufruf beim Ändern eines oder meherer vorhandener Einträge ; Abweichende Programmlogik zu $mode = 0. Jedoch besteht das Problem mit dem falschen Rückgabewert auch hier, ; da diese Programmteile identisch zu $mode = 0 sind. EndIf Else ; Falscher Übergabeparameter $mode EndIf EndFunc ; ==> _setTargetPath( $mode ) -
Wie ich es sehe, würde genau das hier geschehen, wenn der Rückgabewert des rekursiven Aufrufs 'returniert' werden würde.
Genau
- Wenn das Wörtchen Wenn nicht wär... 
Ich finde allerdings 'eine einzige feste Zeile' am Ende der Funktion für die Rückgabe auch übersichtlicher. Aber auch für diesen Fall müsste der Rückgabewert aus dem rekursiven Aufruf gespeichert werden (es sei denn, man benutzt eine globale Variable (!igittigitt!).

Bin ich absolut dabei.

-
sollte sein: Beim rekursiven Funktionsaufruf geht der Rückgabewert der Funktion verloren.
Das sehe ich anders.
Eine rekursive Funktion muss ihren Return zwingend am Ende der Funktion ausführen (oder als letzen Schritt in jedem If-Statement oder Switch/Select-Zweig). Ansonsten kann die Ausführung zu kruden Ergebnissen führen. Eine unsauber geschriebene, rekursiv arbeitende Funktion kann dir echt den Tag versauen. Es kann bei 99 Aufrufen alles paletti sein und beim 100.ten gehts schief ohne auf Anhieb sichtbaren Grund.

-
; PROBLEM: Wenn _setTargetPath() erneut aufgerufen wird, nachdem die Funktion unmittelbar davor in
; den Else-Zweig (Ungenügende Zugriffsrechte für das ausgewählte Verzeichnis) gesprungen ist,
; dann wird der eigentliche Inhalt von $newPath0 als Rückgabewert ignoriert.Das ist auch völlig korrekt. Du rufst die Funktion aus sich selbst heraus auf. Dabei übernimmt dieser Aufruf aber keine bisherigen Werte. Es ist ein absolut frischer Aufruf.
Möchtest du bis dahin erstellte Werte beim rekursiven Aufruf nutzen, übergib diese einfach in einem zusätzlichen optionalen Parameter (z.B. $newPath0_rec), den du mit Null vorbelegst.
In der Funktion prüfst du dann bei Verwendung der Variablen $newPath0, ob $newPath0_rec <> Null ist und weist dann diesen Wert zu.
Der treffendere Titel für dein Problem ist somit: Bei rekursivem Funktionsaufruf gehen bisher in der Funktion erstellte Werte verloren.

-
Wer von Euch benutzt DELL Geräte in der Firma und wie zufrieden seit Ihr?
Wir hatten unsere erste Ausstattung in der Firma mit Dell. Grundsätzlich waren wir zufrieden.
Aber:
Was gestört hat und letztlich gegen eine weitere Nutzung von Dell sprach
- Im deutschen Support nur Tschechen oder Inder, die der deutschen Sprache nicht wirklich mächtig waren
- Produktsupport ist nicht Global, d.h. du bekommst Support nur in dem Land, indem du den PC erworben hast, nicht mal Garantie ist einforderbar
- Verwendung von eigenen Komponenten, d.h. dass man nicht selbst Motherboard, Netzteil oder Lüfter tauschen kann, da Dell diese Komponenten nicht vertreibt
Bei der letzten Hardwareaktualisierung sind wir jetzt auf Mikro-PC (ZOTAC) umgestiegen. Größe einer Zigarrenschachtel und lüfterloser Betrieb sind echt angenehm.
-
Wenn beim Beenden der Anwendung, Fenster auf Datensicherung notwendig? Dann bestätigen, Sicherung abwarten
Ich kenne die Software nicht, könnte mir aber vorstellen, dass sie auch über eine kommandozeilengesteuerte Datensicherung verfügt (bei guter Software ist das Standard). Insofern würde ich dort einen Task einrichten, der all das übernimmt. Da brauchst du nicht mal irgendein Programm zu schreiben.
-
Und er gefällt mir auch nicht nicht mehr.
Fühlst du dich jetzt jünger?

Aber nun habe ich wenigstens eine Zuordnung im Kopf. Ich hatte mir auch mal ein Skript von dir gespeichert, weiß inzwischen aber gar nicht mehr welches.
Aber an deinen Namen kann ich mich noch gut erinnern. -
Kannst du nicht einen Schalter für die Silent-Installation setzen, das diese Webseite am Ende nicht aufgerufen wird?
Kann er, wenn er googeln würde:
PicPick Silent Install (How-To Guide) | SILENT INSTALL HQPicPick is a full-featured screen capture tool, intuitive image editor, color picker, color palette, pixel-ruler, protractor, crosshair, whiteboard and more.…silentinstallhq.com
-
Streng genommen sind das keine Timer und vor allem laufen sie nicht. Das sind einfach Variablen die den Zeitpunkt von TimerInit speichern. Mit TimerDiff ermittelst du dann die Zeitdifferenz.
-
Ich dachte, ich bräuchte noch in jedem Tab einen Button, über den ich den aktuellen Tab abarbeiten lassen kann. Wenn es eine Möglichkeit gibt, den ausgewählten Tab festzustellen, brauch ich ja nur noch einen Button unter den Tabs im GUI, aber das weiß ich nicht, ob oder wie das geht.
Dem Manne kann geholfen werden:
Beachte den advanced mode.
-
Die restlichen GUI-Einträge werden ja anhand der Größe des Arrays erstellt. Das Array kann <100, aber auch >1000 Einträge haben, das kann ich nicht hardcoden.
Das ist klar, sowas wird auch nicht hardcodiert - du musst ja auf jeden Fall irgendeine Liste in ein Array lesen - dieses hat dann einen UBound und den verwendet man dann statt der Bsp.-500.
Jede Liste/jedes Tab bzw. jedes Pack soll noch einen Button bekommen, den ich dann auslesen kann.
Wozu das?
Ganz ehrlich - ich kann mir momentan dein Konzept dahinter nicht vorstellen. Vielleicht ist es ja auch schlüssig, aber das sollte dann auch mit schlüssiger Codierung einhergehen.
Wenn ich viele, seeehr viele Einträge sehe, springt mich spontan immer das Listview als optimales Ctrl an. Du kannst gefühlt unzählige Infos zu jedem Eintrag speichern, lässt aber nur das Erforderliche anzeigen. Eine GUI sollte m.M.n. zuerst die erforderliche Funktionalität bedienen und erst danach kann man sich über Optik Gedanken machen.
Vielleicht schilderst du dein Vorhaben mal nur in Stichworten oder in Art eines PAP. Empfehle ich immer. Oft ist es so, dass einem Ungereimtheiten beim Schreiben des PAP selbst auffallen.
-
Ich habe eine Liste mit "ID" und "Name", die sehr lang sein kann. Darum habe ich sie in Pakete aufgeteilt. Die Paketgröße soll variabel sein, als Beispiel nehm ich mal eine Größe von 10. Also habe ich eine variable Anzahl an Paketen von jeweils 10 Einträgen mit "ID und "Name", also einen 3D-Array.
Es reicht hier sogar ein 1D-Array!
ID = Index
Name = Array[Index]
Wenn du z.B. 500 Einträge hast, erstellst du einfach das Array nachdem alle anderen GUI-Elemente erstellt sind, wie folgt:
AutoIt
Alles anzeigen; alle Gui-Elemente sind erstellt ; Erstellen Dummy-Ctrl für die nächste ID-Nummer = Anzahl der bisher vergebenen ID Global $nextID = GUICtrlCreateDummy() +1 ; "+1", da Dummy selbst eine ID "verbraucht" ; Array definieren Global $aNames[500 + $nextID +1] ; hier "+1", da Index nullbasiert ist ; Zuweisungen ; Annahme, die Liste ist in ein Array eingelesen, mit Zähler an [0] (anderenfalls: $i= 0 To Ubound($aList) -1) Global $tmpID For $i = 1 To $aList[0] $tmpID = GUICtrlCreate.... ; Control erstellen $aNames[$tmpID] = $aList[$i] ; Name aus Liste an ID-Nummer im Array speichern Next ; Ereignis abfragen Global $msg = GuiGetMsg() While True For $i = $nextID To Ubound($aNames) -1 ; beginnend bei erster im Array gespeicherter ID If $msg = $i Then ConsoleWrite($aNames[$i] & @CRLF) ExitLoop EndIf Next Switch $msg Case -3 .... .... WEndDu kannst das auch irgendwo innerhalb der Gui-Erstellung ausführen. Du darfst nur zwischendurch keine anderen Ctrl erstellen, sonst stimmt die Zuordnung nicht.
Ansonsten, wie Oscar bereits sagte:
Bitte ein lauffähiges Minimalskript erstellen, d. h. ein Skript ohne Formatierungen oder Parent-Child-Geschichten, solange diese nicht Teil des Problems sind.
-