Das geht sicherlich einfacher (vor allem erstmal mit Arrays arbeiten).
Allerdings wäre es höflicher und würde mehr Leute zum helfen animieren, wenn Du zumindest schonmal die GUI als kompletten Code hier einstellst (bitte Spoiler und AutoIt-Code-Tags benutzen). Eventuelle Helfer wollen nicht erst alles "zusammenzimmern" müssen.
Beiträge von Oscar
-
-
So reicht doch völlig:
[autoit]
[/autoit]
$link = 'www.google.de' ; <- GuiCtrlRead($Input1)
ShellExecute($link)
Dann wird der Link mit dem Standardbrowser des Benutzers aufgerufen. -
Der Ansatz ist doch schon ganz gut. Etwas erweitert und es klappt:
Spoiler anzeigen
[autoit]
[/autoit]
FileDelete("check.txt")
FileWrite("check.txt", "Zeile 1" & @CRLF & "Zeile 2" & @CRLF & "Zeile 3" & @CRLF & "Zeile 4")
$Suchstring = "Zeile 2"
$Dateitext = FileRead('check.txt')
If StringRegExp($Dateitext, '.*(?:\A|\r\n)(' & $Suchstring & ')(?:\z|\r\n).*') Then
MsgBox(0, "", "String vorhanden!")
Else
MsgBox(0, "", "Nö")
EndIf -
Um dem Benutzer den Fortschritt anzuzeigen, könnte man ja auch das aktuell durchsuchte Verzeichnis per ToolTip anzeigen.
Hier mal mit Aktualisierungsintervall von 50 ms:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <Array.au3>
$iTimer = TimerInit()
$sDir = @ProgramFilesDir
$ret = _RecursiveFileListToArray($sDir, '\.exe\z', 1, 1, True)
ToolTip('')
ConsoleWrite(TimerDiff($iTimer) & @CR)
If IsArray($ret) Then
_ArrayDisplay($ret)
Else
ConsoleWrite($ret)
EndIf;===============================================================================
[/autoit] [autoit][/autoit] [autoit]
; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $fRecursion][, $sDelim])
; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
; Parameter(s): $sPath = Startverzeichnis
; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
; $iFlag = Auswahl
; 0 = Dateien & Verzeichnisse
; 1 = nur Dateien
; 2 = nur Verzeichnisse
; $iFormat = Rückgabeformat
; 0 = String
; 1 = Array mit [0] = Anzahl
; 2 = Nullbasiertes Array
; $fRecursion = Verzeichnisse rekursiv durchsuchen
; False = Nein
; True = Ja
; $sDelim = Trennzeichen für die String-Rückgabe
; Requirement(s): AutoIt 3.3.0.0
; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
; Author(s): Oscar (http://www.autoit.de)
; Anregungen von: bernd670 (http://www.autoit.de)
; und: AspirinJunkie (http://www.autoit.de)
;===============================================================================
Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $fRecursion = True, $sDelim = @CRLF, $fOpenDLL = True)
Local $hSearch, $sFile, $sReturn = '', $aD
Local Static $hDll
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*')
If Not @error And $hSearch <> -1 Then
If $fOpenDLL Then $hDll = DllOpen('kernel32.dll')
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If @extended Then
$aD = DllCall($hDll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sFile)
If @error Or BitAND($aD[0], 0x400) Then ContinueLoop
If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
If $fRecursion Then $sReturn &= _RecursiveFileListToArray(_ShowProgress($sPath & $sFile & '\'), $sPattern, $iFlag, 0, True, $sDelim, False)
ContinueLoop
EndIf
If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
If $fOpenDLL Then DllClose($hDll)
EndIf
If $iFormat = 2 Then $iFormat = 3
If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFuncFunc _ShowProgress($sPath)
[/autoit]
Local Static $iTimer2 = TimerInit()
If TimerDiff($iTimer2) > 50 Then
$iTimer2 = TimerInit()
ToolTip($sPath, 20, 20, 'Suche exe-Dateien...', 1, 5)
EndIf
Return $sPath
EndFunc -
Mit Hilfe der Timer-UDF ist sowas möglich:
Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <Timers.au3>$hGui = GUICreate('Test', 320, 120, 10, 10)
[/autoit] [autoit][/autoit] [autoit]DllCall('uxtheme.dll', 'none', 'SetThemeAppProperties', 'int', 0) ; auf den klassischen Style umschalten
[/autoit] [autoit][/autoit] [autoit]
$idProgress = GUICtrlCreateProgress(10, 10, 300, 30)
DllCall('uxtheme.dll', 'none', 'SetThemeAppProperties', 'int', 7) ; zurück zum Standard-WindowsstyleGUISetState()
[/autoit] [autoit][/autoit] [autoit]
WinSetOnTop($hGui, '', 1)$iTimer = TimerInit()
[/autoit] [autoit][/autoit] [autoit]
$iEndTime = 10000 ; <- Zeit in Millisekunden, bis Notepad automatisch geschlossen wird
_Timer_SetTimer($hGui, 20, '_UpdateProgress')RunWait('Notepad.exe') ; <- wartet auf das beenden von Notepad
[/autoit] [autoit][/autoit] [autoit]_Timer_KillAllTimers($hGui)
[/autoit] [autoit][/autoit] [autoit]
GUIDelete($hGui)
ExitFunc _UpdateProgress($hWnd, $Msg, $iIDTimer, $dwTime)
[/autoit]
#forceref $hWnd, $Msg, $iIDTimer, $dwTime
Local $iTimerDiff = TimerDiff($iTimer)
If $iTimerDiff > $iEndTime Then Return ProcessClose('Notepad.exe')
Local $iPercent = Int(100 / $iEndTime * $iTimerDiff)
GUICtrlSetData($idProgress, $iPercent)
EndFunc -
Eine "unscharfe" Dateisuche ist so nicht möglich.
Du musst schon alle (Txt-)Dateien aus dem Ordner einlesen (_FileListToArray) und dann im Script testen (StringRegExp). -
Was hat das aber für einen Sinn, wenn ich auf den Anfang des Einlesens mit Live-Aktualisierung bereits solange warten muss, wie bei einer anderen Funktion bereits das gesamte Einlesen dauert.
Ich weiß, dass es sinnvoll ist den Benutzer anzuzeigen wie weit das Programm gerade ist, aber eine Prozentanzeige ist halt dahingehend sehr schlecht, weil man erstmal die 100% rausbekommen muss.
Eine Anzeige ("Bitte warten...dauert u.U. einige Minuten") wäre wohl meist ausreichend. Wenn unbedingt die Prozentanzeige gewünscht ist, dann auf keinen Fall bei jeder Datei aktualisieren, sondern mittels Timer nur alle 200ms oder so.
Das würde dann auch das flackern minimieren. -
Das DirGetSize dauert ja schon "ewig". Da ist meine Funktion bereits mit dem einlesen fertig.
Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <Array.au3>
$iTimer = TimerInit()
$sDir = @ProgramFilesDir
$ret = _RecursiveFileListToArray($sDir, '\.exe\z', 1, 1, True)
ConsoleWrite(TimerDiff($iTimer) & @CR)
If IsArray($ret) Then
_ArrayDisplay($ret)
Else
ConsoleWrite($ret)
EndIf;===============================================================================
[/autoit]
; Function Name: _RecursiveFileListToArray($sPath[, $sPattern][, $iFlag][, $iFormat][, $fRecursion][, $sDelim])
; Description:: gibt Verzeichnisse (rekursiv) und/oder Dateien zurück, die einem RegExp-Pattern entsprechen
; Parameter(s): $sPath = Startverzeichnis
; $sPattern = ein beliebiges RexExp-Pattern für die Auswahl
; $iFlag = Auswahl
; 0 = Dateien & Verzeichnisse
; 1 = nur Dateien
; 2 = nur Verzeichnisse
; $iFormat = Rückgabeformat
; 0 = String
; 1 = Array mit [0] = Anzahl
; 2 = Nullbasiertes Array
; $fRecursion = Verzeichnisse rekursiv durchsuchen
; False = Nein
; True = Ja
; $sDelim = Trennzeichen für die String-Rückgabe
; Requirement(s): AutoIt 3.3.0.0
; Return Value(s): Array/String mit den gefundenen Dateien/Verzeichnissen
; Author(s): Oscar (http://www.autoit.de)
; Anregungen von: bernd670 (http://www.autoit.de)
; und: AspirinJunkie (http://www.autoit.de)
;===============================================================================
Func _RecursiveFileListToArray($sPath, $sPattern = '', $iFlag = 0, $iFormat = 1, $fRecursion = True, $sDelim = @CRLF, $fOpenDLL = True)
Local $hSearch, $sFile, $sReturn = '', $aD
Local Static $hDll
If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
$hSearch = FileFindFirstFile($sPath & '*')
If Not @error And $hSearch <> -1 Then
If $fOpenDLL Then $hDll = DllOpen('kernel32.dll')
While True
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If @extended Then
$aD = DllCall($hDll, 'dword', 'GetFileAttributesW', 'wstr', $sPath & $sFile)
If @error Or BitAND($aD[0], 0x400) Then ContinueLoop
If StringRegExp($sPath & $sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 2) Then $sReturn &= $sPath & $sFile & '\' & $sDelim
If $fRecursion Then $sReturn &= _RecursiveFileListToArray($sPath & $sFile & '\', $sPattern, $iFlag, 0, True, $sDelim, False)
ContinueLoop
EndIf
If StringRegExp($sFile, $sPattern) And ($iFlag = 0 Or $iFlag = 1) Then $sReturn &= $sPath & $sFile & $sDelim
WEnd
FileClose($hSearch)
If $fOpenDLL Then DllClose($hDll)
EndIf
If $iFormat = 2 Then $iFormat = 3
If $iFormat And $sReturn = '' Then Return StringSplit($sReturn, '', $iFormat)
If $iFormat Then Return StringSplit(StringTrimRight($sReturn, StringLen($sDelim)), $sDelim, $iFormat)
Return $sReturn
EndFunc -
Wenn man ein Programm schreibt, in dem man die zur Verfügung stehenden Laufwerke dem Benutzer zur Auswahl anbieten will, dann steht man vor dem Problem (während der Laufzeit des Scripts) eine Änderung der zur Verfügung stehenden Laufwerke mitzubekommen. Das könnte man einerseits so lösen, dass man eine Prüfroutine alle paar Sekunden aufruft oder (was ein besserer Weg ist) Windows anweisen, eine Funktion in unserem Script aufzurufen, wenn sich an der Laufwerksauswahl etwas ändert. Das Ganze kann man mit Hilfe von GUIRegisterMsg und $WM_DEVICECHANGE erreichen.
Hier mal ein Beispiel:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>Global Const $WM_DEVICECHANGE = 0x0219 ; Notifies an application of a change to the hardware configuration of a device or the computer.
[/autoit] [autoit][/autoit] [autoit]
Global Const $DBT_DEVICEARRIVAL = 0x8000 ; A device or piece of media has been inserted and is now available.
Global Const $DBT_DEVICEREMOVECOMPLETE = 0x8004 ; A device or piece of media has been removed.$hGui = GUICreate('Automatische Laufwerkserkennung', 380, 200)
[/autoit] [autoit][/autoit] [autoit]
GUICtrlCreateLabel('Laufwerke mit Datenträger:', 20, 30, 180, 20)
$idDrivesReady = GUICtrlCreateCombo('', 20, 50, 120, 20, $CBS_DROPDOWNLIST)
GUICtrlCreateLabel('Laufwerke ohne Datenträger:', 220, 30, 180, 20)
$idDrivesNotReady = GUICtrlCreateCombo('', 220, 50, 120, 20, $CBS_DROPDOWNLIST)
_ReadDrives()
GUISetState()
GUIRegisterMsg($WM_DEVICECHANGE, 'MY_WM_DEVICECHANGE')Do
[/autoit] [autoit][/autoit] [autoit]
Until GUIGetMsg() = $GUI_EVENT_CLOSEFunc MY_WM_DEVICECHANGE($hWnd, $Msg, $wParam, $lParam)
[/autoit] [autoit][/autoit] [autoit]
#forceref $hWnd, $Msg, $lParam
Switch $wParam
Case $DBT_DEVICEARRIVAL
ConsoleWrite('A device or piece of media has been inserted and is now available.' & @CR)
_ReadDrives()
Case $DBT_DEVICEREMOVECOMPLETE
ConsoleWrite('A device or piece of media has been removed.' & @CR)
_ReadDrives()
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>MY_WM_DEVICECHANGEFunc _ReadDrives()
[/autoit]
Local $aDrives, $sDrivesReady, $sDrivesNotReady, $sTmp
GUICtrlSetData($idDrivesReady, '')
GUICtrlSetData($idDrivesNotReady, '')
$aDrives = DriveGetDrive('ALL')
For $i = 1 To $aDrives[0]
If DriveStatus($aDrives[$i]) = 'READY' Then
$sDrivesReady &= '|' & StringUpper($aDrives[$i])
$sTmp = DriveGetLabel($aDrives[$i])
If $sTmp <> '' Then $sDrivesReady &= ' (' & $sTmp & ') '
Else
$sDrivesNotReady &= '|' & StringUpper($aDrives[$i])
EndIf
Next
GUICtrlSetData($idDrivesReady, StringTrimLeft($sDrivesReady, 1), StringRegExpReplace($sDrivesReady, '\|(.+?)\|.*', '$1'))
GUICtrlSetData($idDrivesNotReady, StringTrimLeft($sDrivesNotReady, 1), StringRegExpReplace($sDrivesNotReady, '\|(.+?)\|.*', '$1'))
EndFunc ;==>_ReadDrives -
Kannst Du die Anwendung über RUN starten?
Dann hättest Du die PID und damit kann man Title und Handle bekommen:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <Array.au3>
$PID = Run('cmd.exe')
ConsoleWrite('PID: ' & $PID & @CR)
Sleep(100)
$aTitleHandle = _PID2WinTitleHandle($PID)
;~ _ArrayDisplay($title)
ConsoleWrite('Title: ' & $aTitleHandle[0][0] & @CR)
ConsoleWrite('Handle: ' & $aTitleHandle[0][1] & @CR)
WinClose($aTitleHandle[0][1])Func _PID2WinTitleHandle($PID)
[/autoit]
Local $aTH[1][2], $aList = WinList()
For $i = 1 To $aList[0][0]
If $PID = WinGetProcess($aList[$i][1]) Then
$aTH[UBound($aTH) - 1][0] = $aList[$i][0]
$aTH[UBound($aTH) - 1][1] = $aList[$i][1]
ReDim $aTH[UBound($aTH) + 1][2]
EndIf
Next
If UBound($aTH) > 1 Then ReDim $aTH[UBound($aTH) - 1][2]
Return $aTH
EndFunc ;==>_PID2WinTitleHandle -
Demnach muss das Fenster wohl irgendwie über das Handle angesteuert werden..
Und wo ist das Problem?
[autoit]
Die WinXXX-Befehle lassen sich doch auch mit dem Handle anstelle des Titels nutzen:WinActivate($handle)
[/autoit]
funktioniert doch...
Wobei man folgendes beachten sollte:ZitatWhen you use a window handle for the title parameter then the text parameter is completely ignored.
-
Bevor ich den Thread als "gelöst" kennzeichne, würde ich noch gerne mehr über die "uxtheme.dll" wissen. Speziell eben über das ändern des WIndows-Stiles unter Windows 7 ultimate 64-Bit.
Ist es nun möglich ein Windows XP-Fenster unter Windows 7 ultimate anzuzeigen mithilfe dieser DLL? Und wenn ja, wie?
Wenn Du damit den klassischen Stil meinst. Das geht so:Spoiler anzeigen
[autoit]
[/autoit] [autoit][/autoit] [autoit]
#include <SliderConstants.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>Global $hGui = GUICreate('Klassische Progressbar', 420, 280, -1, -1)
[/autoit] [autoit][/autoit] [autoit]DllCall('uxtheme.dll', 'none', 'SetThemeAppProperties', 'int', 0) ; auf den klassischen Style umschalten
[/autoit] [autoit][/autoit] [autoit]
Global $hProgress1 = GUICtrlCreateProgress(15, 20, 384, 20, $PBS_SMOOTH) ; obere Progressbar erstellen
GUICtrlSetColor(-1, 0x22FF22)
GUICtrlSetBkColor(-1, 0xEEEEEE)
GUICtrlCreateLabel('|', 18, 40, 20, 16) ; Anzeige von 0%
GUICtrlCreateLabel('0%', 11, 56, 25, 16, $SS_CENTER)
GUICtrlCreateLabel('|', 396, 40, 20, 16) ; Anzeige von 100%
GUICtrlCreateLabel('100%', 389, 56, 25, 16, $SS_CENTER)Global $hLabel1 = GUICtrlCreateLabel('0%', 190, 23, 30, 14, $SS_CENTER) ; Prozentanzeige innerhalb der Progressbar
[/autoit] [autoit][/autoit] [autoit]
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; Transparenter Hintergrund für das LabelGlobal $hProgress2 = GUICtrlCreateProgress(15, 160, 384, 20, $PBS_SMOOTH) ; untere Progressbar erstellen
[/autoit] [autoit][/autoit] [autoit]
GUICtrlSetColor(-1, 0xC83131)
GUICtrlSetBkColor(-1, 0xEEEEEE)For $i = 0 To 100 Step 10 ; die Anzeige für die Prozentwerte der unteren Progressbar erstellen
[/autoit] [autoit][/autoit] [autoit]
GUICtrlCreateLabel('|', 16 + $i * 3.8, 180, 20, 16)
GUICtrlCreateLabel($i & '%', 9 + $i * 3.8, 196, 25, 16, $SS_CENTER)
NextGlobal $hSlider = GUICtrlCreateSlider(5, 130, 404, 28, BitOR($TBS_TOOLTIPS, $TBS_AUTOTICKS))
[/autoit] [autoit][/autoit] [autoit]
GUICtrlSetData(-1, 33) ; Sliderwert auf 33% setzen (als Beispiel)Global $hClose = GUICtrlCreateButton('Close', 180, 240, 60, 24)
[/autoit] [autoit][/autoit] [autoit]
DllCall('uxtheme.dll', 'none', 'SetThemeAppProperties', 'int', 7) ; zurück zum Standard-WindowsstyleGUISetState(@SW_SHOW)
[/autoit] [autoit][/autoit] [autoit]Global $iAddend = 1 ; globale Variable (dient als Summand für _SetProgress)
[/autoit] [autoit][/autoit] [autoit]
AdlibRegister('_SetProgress', 50)While True
[/autoit] [autoit][/autoit] [autoit]
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $hClose
AdlibUnRegister()
Exit
EndSwitch
WEndFunc _SetProgress()
[/autoit]
Local $iPercent = GUICtrlRead($hProgress1) ; Prozentwert der oberen Progressbar auslesen
If $iPercent = 100 Or $iPercent = 0 Then $iAddend = -$iAddend ; wenn 100 oder Null, dann den Summand negieren
GUICtrlSetData($hProgress1, $iPercent + $iAddend) ; neuen Wert der oberen Progressbar schreiben
GUICtrlSetData($hLabel1, $iPercent + $iAddend & '%') ; neuen Wert für das Label schreiben
GUICtrlSetData($hProgress2, GUICtrlRead($hSlider)) ; und den Wert vom Slider in die untere Progressbar schreiben
EndFunc ;==>_SetProgress -
[Posting wiederhergestellt]
-
Das Beispiel funktioniert prima. Sowohl als Script, als auch compiliert. Vielen Dank, m-obi!
Endlich mal ein NamedPipe-Script, das fehlerfrei läuft.
-
Habe ich schonmal gemacht: Interprozesskommunikation
-
Ich habe jetzt noch einen Vollbildmodus hinzugefügt. Neue Version in Post#1.
-
Neues Update. Siehe Post#1.
-
UEZ: Ja, das mit dem Switch hatte ich auch schon bemerkt. Ist auch schon geändert. _ShowStatus() selbst ist gar nicht so das Problem. _CheckButtons() hatte so lange gedauert. Dafür habe ich jetzt aber schon eine Lösung:
[autoit]GUISetState(@SW_LOCK, $hGui)
[/autoit]
[autoit]
an den Anfang undGUISetState(@SW_UNLOCK, $hGui)
[/autoit]
ans Ende der Funktion und schon ist die Funktion gut 7mal so schnell.
Danke, für den Hinweis!HassanMullah: Stimmt, ein Löschen-Button wäre ganz brauchbar. Es ist ja noch Platz! Das ist schnell gemacht.

-
Ich habe Deine Funktion jetzt mal (abgewandelt) übernommen. Die ist doch deutlich schneller (vorher: 192 ms, jetzt 2 ms). Vielen Dank, UEZ!

Neue Version in Post#1.
-
Es gibt ein Update (Post #1). Man kann jetzt die Hintergrundfarbe verändern.