Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/16/2018 in all areas

  1. As the WebDriver UDF - Help & Support thread has grown too big, I started a new one. The prior thread can be found here.
    1 point
  2. [New Release] - 06 April 2019 Added: Error-checking for sensible column numbers in the $aSortData array, with an additional error status. ------------------------------------------------------------------------------------------------------------------------ While answering a recent question about sorting a ListView on several columns, I developed this function to sort a 2D array on several columns and I though I might give it a wider audience. Here is the function: #include-once ;#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 ; #INCLUDES# ========================================================================================================= #include <Array.au3> ; =============================================================================================================================== ; #INDEX# ======================================================================================================================= ; Title .........: ArrayMultiColSort ; AutoIt Version : v3.3.8.1 or higher ; Language ......: English ; Description ...: Sorts 2D arrays on several columns ; Note ..........: ; Author(s) .....: Melba23 ; Remarks .......: ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _ArrayMultiColSort : Sort 2D arrays on several columns ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#================================================================================================= ; __AMCS_SortChunk : Sorts array section ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayMultiColSort ; Description ...: Sort 2D arrays on several columns ; Syntax.........: _ArrayMultiColSort(ByRef $aArray, $aSortData[, $iStart = 0[, $iEnd = 0]]) ; Parameters ....: $aArray - The 2D array to be sorted ; $aSortData - 2D array holding details of the sort format ; Format: [Column to be sorted, Sort order] ; Sort order can be either numeric (0/1 = ascending/descending) or a ordered string of items ; Any elements not matched in string are left unsorted after all sorted elements ; $iStart - Element of array at which sort starts (default = 0) ; $iEnd - Element of array at which sort endd (default = 0 - converted to end of array) ; Requirement(s).: v3.3.8.1 or higher ; Return values .: Success: No error ; Failure: @error set as follows ; @error = 1 with @extended set as follows (all refer to $sIn_Date): ; 1 = Array to be sorted not 2D ; 2 = Sort data array not 2D ; 3 = More data rows in $aSortData than columns in $aArray ; 4 = Start beyond end of array ; 5 = Start beyond End ; @error = 2 with @extended set as follows: ; 1 = Invalid string parameter in $aSortData ; 2 = Invalid sort direction parameter in $aSortData ; 3 = Invalid column index in $aSortData ; Author ........: Melba23 ; Remarks .......: Columns can be sorted in any order ; Example .......; Yes ; =============================================================================================================================== Func _ArrayMultiColSort(ByRef $aArray, $aSortData, $iStart = 0, $iEnd = 0) ; Errorchecking ; 2D array to be sorted If UBound($aArray, 2) = 0 Then Return SetError(1, 1, "") EndIf ; 2D sort data If UBound($aSortData, 2) <> 2 Then Return SetError(1, 2, "") EndIf If UBound($aSortData) > UBound($aArray) Then Return SetError(1, 3) EndIf For $i = 0 To UBound($aSortData) - 1 If $aSortData[$i][0] < 0 Or $aSortData[$i][0] > UBound($aArray, 2) -1 Then Return SetError(2, 3, "") EndIf Next ; Start element If $iStart < 0 Then $iStart = 0 EndIf If $iStart >= UBound($aArray) - 1 Then Return SetError(1, 4, "") EndIf ; End element If $iEnd <= 0 Or $iEnd >= UBound($aArray) - 1 Then $iEnd = UBound($aArray) - 1 EndIf ; Sanity check If $iEnd <= $iStart Then Return SetError(1, 5, "") EndIf Local $iCurrCol, $iChunk_Start, $iMatchCol ; Sort first column __AMCS_SortChunk($aArray, $aSortData, 0, $aSortData[0][0], $iStart, $iEnd) If @error Then Return SetError(2, @extended, "") EndIf ; Now sort within other columns For $iSortData_Row = 1 To UBound($aSortData) - 1 ; Determine column to sort $iCurrCol = $aSortData[$iSortData_Row][0] ; Create arrays to hold data from previous columns Local $aBaseValue[$iSortData_Row] ; Set base values For $i = 0 To $iSortData_Row - 1 $aBaseValue[$i] = $aArray[$iStart][$aSortData[$i][0]] Next ; Set start of this chunk $iChunk_Start = $iStart ; Now work down through array For $iRow = $iStart + 1 To $iEnd ; Match each column For $k = 0 To $iSortData_Row - 1 $iMatchCol = $aSortData[$k][0] ; See if value in each has changed If $aArray[$iRow][$iMatchCol] <> $aBaseValue[$k] Then ; If so and row has advanced If $iChunk_Start < $iRow - 1 Then ; Sort this chunk __AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1) If @error Then Return SetError(2, @extended, "") EndIf EndIf ; Set new base value $aBaseValue[$k] = $aArray[$iRow][$iMatchCol] ; Set new chunk start $iChunk_Start = $iRow EndIf Next Next ; Sort final section If $iChunk_Start < $iRow - 1 Then __AMCS_SortChunk($aArray, $aSortData, $iSortData_Row, $iCurrCol, $iChunk_Start, $iRow - 1) If @error Then Return SetError(2, @extended, "") EndIf EndIf Next EndFunc ;==>_ArrayMultiColSort ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __AMCS_SortChunk ; Description ...: Sorts array section ; Author ........: Melba23 ; Remarks .......: ; =============================================================================================================================== Func __AMCS_SortChunk(ByRef $aArray, $aSortData, $iRow, $iColumn, $iChunkStart, $iChunkEnd) Local $aSortOrder ; Set default sort direction Local $iSortDirn = 1 ; Need to prefix elements? If IsString($aSortData[$iRow][1]) Then ; Split elements $aSortOrder = StringSplit($aSortData[$iRow][1], ",") If @error Then Return SetError(1, 1, "") EndIf ; Add prefix to each element For $i = $iChunkStart To $iChunkEnd For $j = 1 To $aSortOrder[0] If $aArray[$i][$iColumn] = $aSortOrder[$j] Then $aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn] ExitLoop EndIf Next ; Deal with anything that does not match If $j > $aSortOrder[0] Then $aArray[$i][$iColumn] = StringFormat("%02i-", $j) & $aArray[$i][$iColumn] EndIf Next Else Switch $aSortData[$iRow][1] Case 0, 1 ; Set required sort direction if no list If $aSortData[$iRow][1] Then $iSortDirn = -1 Else $iSortDirn = 1 EndIf Case Else Return SetError(1, 2, "") EndSwitch EndIf ; Sort the chunk Local $iSubMax = UBound($aArray, 2) - 1 __ArrayQuickSort2D($aArray, $iSortDirn, $iChunkStart, $iChunkEnd, $iColumn, $iSubMax) ; Remove any prefixes If IsString($aSortData[$iRow][1]) Then For $i = $iChunkStart To $iChunkEnd $aArray[$i][$iColumn] = StringTrimLeft($aArray[$i][$iColumn], 3) Next EndIf EndFunc ;==>__AMCS_SortChunk And here is an example to show it working: #include "ArrayMultiColSort.au3" #include <String.au3> ; Only used to fill array ; Create and display array Global $aArray[100][4] For $i = 0 To 99 $aArray[$i][0] = _StringRepeat(Chr(Random(65, 68, 1)), 5) $aArray[$i][1] = _StringRepeat(Chr(Random(74, 77, 1)), 5) $aArray[$i][2] = _StringRepeat(Chr(Random(80, 83, 1)), 5) $aArray[$i][3] = _StringRepeat(Chr(Random(87, 90, 1)), 5) Next _ArrayDisplay($aArray, "Unsorted") ; Copy arrays for separate examples below $aArray_1 = $aArray $aArray_2 = $aArray ; This sorts columns in ascending order - probably the most common requirement ; Sort requirement: ; Col 0 = Decending ; Col 1 = Ascending ; Col 2 = Required order of elements (note not alphabetic PQRS nor reverse SRQP) ; Col 3 = Ascending Global $aSortData[][] = [ _ [0, 1], _ [1, 0], _ [2, "SSSSS,QQQQQ,PPPPP,RRRRR"], _ [3, 0]] ; Sort and display array _ArrayMultiColSort($aArray_1, $aSortData) ; Display any errors encountered If @error Then ConsoleWrite("Oops: " & @error & " - " & @extended & @CRLF) _ArrayDisplay($aArray_1, "Sorted in order 0-1-2-3") ; But the UDF can sort columns in any order ; Sort requirement: ; Col 2 = Decending ; Col 0 = Ascending Global $aSortData[][] = [ _ [2, 1], _ [0, 0]] ; Sort and display array _ArrayMultiColSort($aArray_2, $aSortData) ; Display any errors encountered If @error Then ConsoleWrite("Oops: " & @error & " - " & @extended & @CRLF) _ArrayDisplay($aArray_2, "Sorted in order 2-0") And here are both in zip form: ArrayMultiColSort.zip As usual all comments welcome. M23
    1 point
  3. 2018-Sep-16, Changelog v5 > v6 Updated codebase to AutoIt v3.3.14.5 Source and Executable are available at http://www.funk.eu Enjoy and Best Regards
    1 point
  4. @KaFu Great, thanks! An update after two years! I was actually very inspired by your program. I researched many months about a similar solution for linux, in the end I even decided to write my own tool... after many months of (trying to) learning a bunch of languages and failing, I finally made myself a similar tool which can hide windows using C. It should work on any linux computer which uses the X display server, it is called mapmywindows and it is open source. I started working on it in March this year, but it was just a proof of concept until recently (a few days ago) I implemented full keyboard shortcut support and ability to hide multiple windows. Quite a coincidence Sorry for taking over your thread, I got excited. Thank you for the work and inspiring me P.S Also sorry for stealing the name... LOL
    1 point
  5. 2018-Sep-16, Changelog v2 > v3 Fixed some tray icons not display on Win10 Updated codebase to AutoIt v3.3.14.5 Source and Executable are available at http://www.funk.eu Best Regards
    1 point
  6. Hey, I was just kidding. I am not in this place to make money, just to have some sort of fun without commitments.
    1 point
  7. Something sounds wrong in that statement or the "a" would need to change to "many 6 packs"
    1 point
  8. put this in a batch file and run as admin taskkill /f /im explorer.exe cd /d %userprofile%\AppData\Local del IconCache.db /a start explorer.exe that deletes the cache, and rebuilds when explorer starts. I've seen this since Windows 95, LOL. seriously. they can't seem to get around this happening sometimes. I see it all the time on all OSs that I test our products on, even a few customers have called in about it.
    1 point
  9. Have removed Run, I have renamed the variables to make them more understandable: $sAppFilePath = Full Path to .\app.exe $sAppFolderPath = Full Path without \app.exe #include <GUIConstantsEx.au3> #include <GuiEdit.au3> #include <MsgBoxConstants.au3> #include <WinAPIShPath.au3> Global $sIniPath = @ScriptDir & "\app.ini" Global $sAppFilePath = IniRead($sIniPath, "App", "App", "N/A") Global $sAppFolderPath = _WinAPI_PathRemoveFileSpec($sAppFilePath) If FileExists($sAppFilePath) = 0 Then _FileSelect() Example() Func Example() Local $hGUI = GUICreate("Example", 365, 30) Local $idFilePath = GUICtrlCreateInput($sAppFilePath, 5, 5, 250, 21) _GUICtrlEdit_SetCueBanner($idFilePath, "<FilePath>\App.exe") Local $idBrowse = GUICtrlCreateButton("Browse", 260, 5, 100, 21) GUICtrlSetState($idBrowse, $GUI_FOCUS) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idBrowse _FileSelect() GUICtrlSetData($idFilePath, $sAppFilePath) EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example Func _FileSelect() Local $sFolderPath = _WinAPI_PathRemoveFileSpec(IniRead($sIniPath, "App", "App", "")) $sAppFilePath = FileOpenDialog("Select App Path", $sFolderPath, "Notepad.exe(Notepad.exe)") If @error Then MsgBox($MB_SYSTEMMODAL, "", "No File was selected.") $sAppFilePath = "" $sAppFolderPath = "" Else $sAppFolderPath = _WinAPI_PathRemoveFileSpec($sAppFilePath) IniWrite($sIniPath, "App", "App", $sAppFilePath) EndIf MsgBox(64, "App File/Folder Path(s)", "App File Path : " & $sAppFilePath & @CRLF & "App Folder Path : " & $sAppFolderPath) EndFunc ;==>_FileSelect
    1 point
  10. I was working on this a while back, wanted to make it a UDF but never put the time to write it to standards. I used it for quite a few things however. #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Test GUI", 618, 276, 192, 124) $Label1 = GUICtrlCreateLabel("Test GUI", 168, 24, 47, 17) $Button1 = GUICtrlCreateButton("Toggle Validation", 290, 24, 110, 40) $Input1 = GUICtrlCreateInput("Max 10 Characters", 40, 72, 553, 21) $Input2 = GUICtrlCreateInput("Numb3rs 0nly", 40, 97, 553, 21) $Edit1 = GUICtrlCreateEdit("Max 10 Chars Numbers Only + Auto Line Break", 40, 120, 553, 105) GUISetState(@SW_SHOW) $iToggle = 1 While 1 Sleep(10) If Mod($iToggle, 2) = 0 Then ;Example 1 Limit to 10 Characters _GUIRegExValidate($Input1, "(.{10})(.)", "$1") ;Example 2 Can only type numbers _GUIRegExValidate($Input2, "[^\d]", "") ;Example 3 Combind More Than One On Same Input limit to 10 characters, limit to numbers only, line break @ 10 characters to new line _GUIRegExValidate($Edit1, "(.{10})(.)", "$1" & @CRLF) _GUIRegExValidate($Edit1, "[^\d\r\n]", "") EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 $iToggle = $iToggle + 1 EndSwitch WEnd Func _GUIRegExValidate($sInputLabel, $sRegExCapture, $sRegExReplace) $Step1Read = GUICtrlRead($sInputLabel) $Step2Validate = StringRegExpReplace($Step1Read, $sRegExCapture, $sRegExReplace) If @Extended = 0 Then Return GUICtrlSetData($sInputLabel, $Step2Validate) EndFunc Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam) _GUIRegExValidate($Edit1, "(.{20})(.)", "$1") EndFunc
    1 point
  11. This should work to do it dynamically #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <EditConstants.au3> Opt("GUIOnEventMode", 1) $hGUI = GUICreate("Test", 232, 90) $Label = GUICtrlCreateLabel("Enter MAC address", 22, 8, 163, 17) $input = GUICtrlCreateInput("", 22, 30, 165, 24) GUICtrlSetLimit(-1, 17) GUICtrlSetFont(-1, 12) GUISetState() GUIRegisterMsg($WM_COMMAND, '_WM_COMMAND') GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit") While 1 Sleep(10) WEnd Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam) Local $id = BitAND($wParam, 0x0000FFFF) Local $code = BitShift($wParam, 16) If $id = $input AND $code = $EN_UPDATE Then Local $content = GUICtrlRead($input) Local $len = StringLen($content) Local $char = StringRight($content, 1) Local $mod = Mod($len, 3) If not (( ($mod = 1 or $mod = 2) and StringRegExp($char, '[[:xdigit:]]') ) OR _ ($mod = 0 and $char = "-")) Then GUICtrlSetData($input, StringTrimRight($content, 1)) EndIf Return $GUI_RUNDEFMSG EndFunc Func _Exit() Exit EndFunc
    1 point
  12. mLipok, with the new version your example could be modified as follows (three regexes) #include <GUIConstants.au3> #include <RestrictEdit.au3) #include <MsgBoxConstants.au3> #cs [0]|m121/12, [1]|1231/12, [2]|p1/12, [3]|2/13, [4]|s1/14, [5]|o121/10 #ce _Main() Func _Main() #cs Pattern in text that should follow the first character can be any of 'm' 'p' 's' 'o' 'n' or a no. of digits followed by a "/" and then followed by two digits. Then if comma again the above pattern is expected otherwise, if EOL the pattern is satisfied. #ce ;our main GUI GUICreate("Restrict Edit | Phoenix XL", 200, 70) GUICtrlCreateLabel("Test", 10, 10, 200, 30) GUICtrlCreateInput("", 10, 30, 180, 20) ;subclass the control and set the SRE restriction. _Restrict_Edit(GUICtrlGetHandle(-1), SRE_Array, "InCorrect Syntax.") If @error Then MsgBox($MB_ICONERROR, "Error Code: " & @error, "Extended: " & @extended) GUISetState() Do Sleep(10) Until GUIGetMsg() = $GUI_EVENT_CLOSE ;unsubclass the control _Restrict_Edit(GUICtrlGetHandle(-1)) EndFunc ;==>_Main Func SRE_Array($hEdit, $s_CurrentText) ;return an non-array non zero to block processing ;return zero to block restriction Local $aPatterns[3][2] = [ _ ["(^|(?<=/\d{2}),)[mpson]?\d*(/|$)", True], _ ;here True signifies +ve match, the string should match the pattern ["((\D)\2|/\d{3}|/\d?\D|/\d{2}[^,]|(?<=\D)/)", False], _ ;here False signifies -ve match, the string should NOT match the pattern ["[^mpson\d,/]", False]] ;Lets decode the above patterns #cs First Pattern +ve match 1st Capturing group (^|(?<=/\d{2}),) : by start of string or comma( that too should be preceeded by a slash and two digits [look-behind assertion]) [mpson]? : if present should be preceeded by 1st capturing group. \d* : any no. of digits 2nd Capturing group ((/|$) : Either the end of the string, or a slash If the above pattern is not satisfied, processing is blocked. Second Pattern -ve match 1st Capturing group ((\D)\2|/\d{3}|/\d?\D|/\d{2}[^,]) : consists of five different patterns nested. When either of the three is satisfied the pattern is matched 1st NestedPattern (\D)\2 : second capturing group, the first char is any non-digit, the second char is the same non-digit 2nd NestedPattern /\d{3} : after slash three digits are present. 3rd NestedPattern /\d?\D : after slash a non-digit is there or after slash a digit and then a non digit is present 4th NestedPattern /\d{2}[^,] : after slash two digits and anything other than comma is present. 5th NestedPattern (?<=\D)/ : slash preceeded by any non-digit If the above pattern is satisfied, processing is blocked. Third Pattern -ve match [^mpson\d,/] : match anything other than m p s o n digit , / if the above is satisfied, processing is blocked #ce ;You can also block processing using this function. ;Say you don't want characters to exceed 20 then If StringLen($s_CurrentText) > 20 Then Return 1 Return $aPatterns EndFunc ;==>SRE_Array Though the straight away method is more simple and better conceptualized with nested conditionals, it modifies as follows #include <GUIConstants.au3> #include <RestrictEdit.au3> #include <MsgBoxConstants.au3> #cs [0]|m121/12, [1]|1231/12, [2]|p1/12, [3]|2/13, [4]|s1/14, [5]|o121/10 #ce _Main() Func _Main() #cs Pattern in text that should follow the first character can be any of 'm' 'p' 's' 'o' 'n' or a no. of digits followed by a "/" and then followed by two digits. Then if comma again the above pattern is expected otherwise, if EOL the pattern is satisfied. #ce ;our main GUI GUICreate("Restrict Edit | Phoenix XL", 200, 70) GUICtrlCreateLabel("Test", 10, 10, 200, 30) GUICtrlCreateInput("", 10, 30, 180, 20) ;subclass the control and set the SRE restriction. _Restrict_Edit(GUICtrlGetHandle(-1), SRE_Array, "InCorrect Syntax.") If @error Then MsgBox($MB_ICONERROR, "Error Code: " & @error, "Extended: " & @extended) GUISetState() Do Sleep(10) Until GUIGetMsg() = $GUI_EVENT_CLOSE ;unsubclass the control _Restrict_Edit(GUICtrlGetHandle(-1)) EndFunc ;==>_Main Func SRE_Array($hEdit, $s_CurrentText) ;return an non-array non zero to block processing ;return zero to block restriction Local $aPatterns[1][2] = [ ["^([mpson]?(?(?=\d+)\d+(?(?=/)/(?(?=\d)\d{0,2}(,|$)|$)|$)|$))*$", True]] Return $aPatterns EndFunc ;==>SRE_Array Regards Phoenix XL
    1 point
×
×
  • Create New...