Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/15/2021 in all areas

  1. Nah, a simple thanks is well enough But if you feel the need to donate, there is a button up right for it...
    2 points
  2. During code troubleshooting, the data display functions _ArrayDisplay(), _DebugArrayDisplay() and _WinAPI_DisplayStruct() can be useful to provide a quick visual overview of the contents of arrays and DllStructs. However, these functions each have their own built-in message loop, which will block the code in the main script. In many cases the code in the main script cannot stand to be blocked in this way and will therefore fail. That is, the troubleshooting functions themselves cause an error. And that, of course, isn't an appropriate situation. This example shows how to execute the data display functions in their own processes, to avoid blocking the code in the main script. Other Examples Unblocking a Blocked Message Handler Unblocking a Blocked Message Handler is about several data display functions that mutually block each other, and how to get around this problem. But the example is not about how to avoid the main script from being blocked. In this new example, data display functions will not block each other nor will they block the main script. The IdeaThe main issue in running a data display function in its own process is passing data to the function. The idea is to use a system global ROT object to pass data from the main script to the data display function. The two major advantages of using a ROT object are that it's a very fast data passing method and that the method preserves data types. However, a ROT object can only be used to pass COM compatible data types. An array is such a COM compatible data type (an AutoIt array is not directly COM compatible, but internally it is stored as a safearray of variants that is COM compatible). A DllStruct isn't COM compatible (nor is it processed by internal COM conversions). To pass a DllStruct, we must first convert data to binary data, which is COM compatible. Once the binary data has been passed, it must again be converted back to a DllStruct. The technique is discussed in the DllStruct section of IPC Techniques through ROT Objects. The CodeThe code is implemented as a complete UDF, NonBlockingDataDisplay.au3. The essential code for creating ROT objects is contained in IRunningObjectTable.au3. AccVars.au3 as well as Variant.au3 and SafeArray.au3 contains code to convert a DllStruct to binary data. Two functions at bottom of the new UDF handles the details of DllStruct to binary conversion. RunArrayDisplay() is the UDF function to execute _ArrayDisplay() in a standalone process: Func RunArrayDisplay( _ $sPath, _ ; Path to Includes ended with "\" $aArray, _ $iFlags = 0, _ ; 0 -> 32 bit code, 1 -> 64 bit code $sTitle = "ArrayDisplay", _ $sHeader = Default ) ; Create data transfer object (ROT-object) Local $sDataTransferObject = "DataTransferObject" & ROT_CreateGUID() ROT_RegisterObject( Default, $sDataTransferObject ) ; Default => Object = Dictionary object Local $oDataTransferObject = ObjGet( $sDataTransferObject ) ; Dictionary object ; Add data to transfer object $oDataTransferObject.Add( "$aArray", $aArray ) $oDataTransferObject.Add( "$sTitle", $sTitle ) $oDataTransferObject.Add( "$sHeader", $sHeader ) ; Run _ArrayDisplay() in another process $g_aDataDisplayProgPids[$g_iDataDisplayProgPids] = BitAND( $iFlags, 1 ) _ ? Run( @AutoItExe & " /AutoIt3ExecuteScript " & $sPath & '"RunArrayDisplay64.au3" ' & $sDataTransferObject ) _ ; 64 bit code : Run( @AutoItExe & " /AutoIt3ExecuteScript " & $sPath & '"RunArrayDisplay32.au3" ' & $sDataTransferObject ) ; 32 bit code $g_iDataDisplayProgPids += 1 EndFunc The function executes Includes\RunArrayDisplay64.au3: #AutoIt3Wrapper_UseX64=Y #include <Array.au3> RunDataDisplay() Func RunDataDisplay() ; Get data transfer object Local $sDataTransferObject = $CmdLine[1] ; Get data from transfer object Local $oDataTransferObject = ObjGet( $sDataTransferObject ) Local $aArray = $oDataTransferObject.Item( "$aArray" ) Local $sTitle = $oDataTransferObject.Item( "$sTitle" ) Local $sHeader = $oDataTransferObject.Item( "$sHeader" ) ; Show array _ArrayDisplay( $aArray, $sTitle, "", 0, Default, $sHeader ) EndFunc Examples\RunArrayDisplay64.au3 is the example that demonstrates the use of RunArrayDisplay(). Run the example in SciTE with F5. #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include "..\Includes\NonBlockingDataDisplay.au3" Example() Func Example() ; Create array Local $aArray[1000][10] For $i = 0 To 1000 - 1 For $j = 0 To 9 $aArray[$i][$j] = $i & "/" & $j Next Next ; Display array RunArrayDisplay( "..\Includes\", $aArray, 1 ) ; 1 -> 64 bit code ; Modify array For $j = 0 To 9 $aArray[0][$j] = "Zero/" & $j Next ; Display array RunArrayDisplay( "..\Includes\", $aArray, 1, "ArrayDisplay 2", "C 0|C 1|C 2|C 3|C 4|C 5|C 6|C 7|C 8|C 9" ) ; The script isn't blocked While Sleep( 1000 ) ConsoleWrite( "The script isn't blocked" & @CRLF ) WEnd EndFunc ExamplesIn the Examples folder, there are three more examples. RunArrayDisplay32.au3 is a 32 bit version of RunArrayDisplay64.au3. RunDebugArrayDisplay64.au3 demonstrates the use of RunDebugArrayDisplay() in the UDF. A prerequisite for running the example is that you're using an AutoIt version that includes _DebugArrayDisplay(). The AutoIt version isn't checked in the code. RunDisplayStruct64.au3 demonstrates the use of RunDisplayStruct() in the UDF. The example is based on the example of _WinAPI_DisplayStruct() in the help file. 7z-fileThe 7z-file contains source code for UDFs and examples. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. NonBlockingDataDisplay.7z
    1 point
  3. jugador

    1D to 2D Array

    > 1D to 2D Array #include<array.au3> Local $o_Eg1[] = ['A','1','111','B','2','222','C','3','333','D','4' ] _ArrayDisplay( __1Dto2DArray($o_Eg1, 3) ) Local $o_Eg2[] = ['A','1','B','2','C','3','D','4','E','5' ] _ArrayDisplay( __1Dto2DArray($o_Eg2, 2) ) ; #FUNCTION# ============================================================================= ; Name...........: __1Dto2DArray ; ========================================================================================= Func __1Dto2DArray($0_Array, $0_mod = 2) If UBound($0_Array, 2) > 1 Then Return SetError(1) Local $o_Array[Ceiling(UBound($0_Array) / $0_mod)][$0_mod] For $i = 0 To UBound($0_Array) - 1 $o_Array[Floor($i / $0_mod)][Mod($i, $0_mod)] = $0_Array[$i] Next Return $o_Array EndFunc
    1 point
  4. water

    _ArrayColInsert

    Could you please be so kind and add some documentation to your example scripts? Why is your code better than the original function? Is it faster? Does it add functionality? Does it fix a bug? Unfortunately my cristal ball doesn't tell me
    1 point
  5. dmob

    1D to 2D Array

    Sweet, like a turbo StringSplit thanks for sharing.
    1 point
  6. Fwiw, there should be no runtime difference between For $i = 0 to 30 Switch $lable Case $tar[$i] To $top[$i] Guictrlsetstate($tab&$i+1, $gui_show) EndSwitch Next and For $i = 0 to 30 If $lable >= $tar[$i] And $label <= $top[$i] Then Guictrlsetstate($tab&$i+1, $gui_show) Next I was pointing this out not because I believe one is better than the other, but just so you didn’t have the impression that one works and one doesn’t. The choice between “If” and “Switch” is mainly a stylistic one.
    1 point
  7. dmob

    Array Column Delete

    @pixelsearch, always impressive how you dig deep to optimise code
    1 point
  8. 1 point
  9. try this... Local $iPID = Run('cmd /?', '', @SW_HIDE, 2); $STDOUT_CHILD If @error Or Not $iPID Then Exit Local $sStdOut = "" Do Sleep(10) $sStdOut &= StdoutRead($iPID) Until @error MsgBox(0, '', $sStdOut)
    1 point
×
×
  • Create New...