Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/18/2017 in all areas

  1. Well said @czardas .
    1 point
  2. Natural sort is more flexible however, for a bespoke situation such as this, it could be considered overkill. I tend to strip away things I don't need once everything is working, so I quite often use a standard function with all the bells and whistles attached before making final adjustments. This approach can sometimes be useful when you are unsure of all the features you intend to implement: eventually you might want to keep the whistles and get rid of the bells. I don't think there is a right or wrong approach to this and the methods above are all valid.
    1 point
  3. You, Using my GUIExtender UDF allows you to do something like this quite easily: #include <GUIConstantsEx.au3> #include "GUIExtender.au3" Global $aLabel[6], $aColour[] = [0, 0xFF0000, 0x00FF00, 0xAAAAFF, 0xFFFF00, 0x00FFFF] $hGUI = GUICreate("Test", 2600, 500, 100, 100) For $i = 1 To 5 $aLabel[$i] = GUICtrlCreateLabel("Tab " & $i, 0, ($i * 100) - 100, 100, 100) GUICtrlSetBkColor(-1, $aColour[$i]) GUICtrlSetResizing(-1, $GUI_DOCKSIZE) Next _GUIExtender_Init($hGUI, 1) For $i = 1 To 5 $iSection = _GUIExtender_Section_Create($hGUI, (500 * $i) - 400, 500) GUICtrlCreateLabel("This is screen " & $iSection, (500 * $i) - 400, (100 * $i) - 100, 500, 100) GUICtrlSetBkColor(-1, $aColour[$i]) _GUIExtender_Section_Activate($hGUI, $iSection) Next _GUIExtender_Section_Create($hGUI, -99) $iCurrSection = 1 For $i = 2 To 5 _GUIExtender_Section_Action($hGUI, $i, 0) Next GUISetState() While 1 $imsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE Exit Case Else For $i = 1 To 5 If $iMsg = $aLabel[$i] And $i <> $iCurrSection Then _GUIExtender_Section_Action($hGUI, $iCurrSection, 0) _GUIExtender_Section_Action($hGUI, $i, 1) $iCurrSection = $i ExitLoop EndIf Next EndSwitch _GUIExtender_EventMonitor($hGUI, $iMsg) WEnd The UDF link is in my sig. M23
    1 point
  4. @czardas I have looked into natural sort but most of them only talk about a single number... not multiple digits in a single column! I will look into them anyway. Now I know what natural sort is . @Jos That's quick hack you have got there! . Never thought that it would be that simple @AspirinJunkie Your UDF looks very promising, I will give it a go . I will post back with the results which I finish playing around with the solutions. Thanks for post y'all! Much Appreciated!
    1 point
  5. Melba23

    I got this error

    Ruhon, Welcome to the AutoIt forum. Unfortunately you appear to have missed the Forum rules on your way in. Please read them now - particularly the bit about not discussing game automation - and then you will understand why you will get no further help and this thread will now be locked. See you soon with a legitimate question I hope. M23
    1 point
  6. Here is an option with some good old fashioned programming logic: #include <Array.au3> Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]] ReDim $aVersionsAndReleases[4][3] For $x = 0 To UBound($aVersionsAndReleases) - 1 $Version = StringSplit($aVersionsAndReleases[$x][0], ".") For $y = 1 To $Version[0] $aVersionsAndReleases[$x][2] &= StringRight("000000" & $Version[$y], 6) Next Next _ArraySort($aVersionsAndReleases, 1, 0, 0, 2) ConsoleWrite(_ArrayToString($aVersionsAndReleases, ' - ')) _ArrayDisplay($aVersionsAndReleases) Jos
    1 point
  7. Search for 'natural sort' algorithms. You'll find something.
    1 point
  8. I've written a sorting function for user defined sorting (see the UDF in attachment) . With this the solution should be something like this: #include "DynArray.au3" Local $aVersionsAndReleases[4][2] = [["0.2.8.9", "Release #1"], ["0.2.9.10", "Release #3"], ["0.2.9.11", "Release #4"], ["0.2.8.10", "Release #2"]] _ArraySortFlexible($aVersionsAndReleases, _MyCompare) _ArrayDisplay($aVersionsAndReleases) ; user defined comparison function for user-defined sorting Func _MyCompare(ByRef $A, ByRef $B) Local Static $h_DLL_Shlwapi = DllOpen("Shlwapi.dll") Return -DllCall($h_DLL_Shlwapi, "int", "StrCmpLogicalW", "wstr", $A[0], "wstr", $B[0])[0] EndFunc ;==>_MyCompare Edit: removed attached Dynarray.au3 because functions are now part of ArrayPlus-UDF.
    1 point
  9. LarsJ

    Accessing AutoIt Variables

    Real examples sqlite3_get_table sqlite3_get_table returns a 1D or 2D array of result data generated by executing a SQLite SELECT statement. sqlite3_get_table is not coded in SQLite.au3, but _SQLite_GetTable and _SQLite_GetTable2d implements similar functionality. Both _SQLite_GetTable and _SQLite_GetTable2d are based on a technique where the rows are extracted from a database and inserted in a 1D or 2D array one by one. If you extracts 1 GB of data from the database, the array will use 1 GB of memory when all rows are inserted. Because rows are both extracted from the database and inserted in the array one by one, you need pretty much code in the loops that handles the rows. _SQLite_GetTable and _SQLite_GetTable2d uses little memory, but are not very fast because of much code in the loops. sqlite3_get_table extracts all rows from the database at once and inserts the rows in a C-array. Then you have to copy the rows from the C-array to an AutoIt array. If you extracts 1 GB of data from the database, the C-array will use 1 GB of memory. When all rows are inserted in an AutoIt array this will also use 1 GB of memory. When all rows are copied, the C-array can be deleted. But you still need 2 GB of memory to be able to copy the rows. You don't need many code lines to copy data from a C-array to an AutoIt array. Code to copy data can be implemented in a tight and fast loop. sqlite3_get_table uses much memory, but is fast because of a simple loop. The fact that sqlite3_get_table uses much memory is the reason why it's not recommended to use the function. But you can use it if you know what you are doing. In this example sqlite3_get_table is implemented as an AutoIt function. Then the loop to copy data from the C-array to the AutoIt array is optimized with a few lines of C++ code. Installing SQLite Navigate to "Precompiled Binaries for Windows" section here and download the three zip files. Extract sqlite3.dll from sqlite-dll-win64-x64-3170000.zip and rename it to sqlite3_x64.dll Extract sqlite3.dll from sqlite-dll-win32-x86-3170000.zip Extract the 3 files in sqlite-tools-win32-x86-3170000.zip Copy all 5 files to C:\Windows\System32 Copy sqlite3.dll to C:\Windows\SysWOW64 CreateDBs.au3: Create databases The example is stored in Examples\Real examples\sqlite3_get_table folder in zip file in bottom of first post (goto top of second post and scroll up a little bit). The folder contains 7 AutoIt scripts. Run CreateDBs.au3 to create the databases. All databases, 5 in total, contains one table with 10 columns but a different number of rows. The name of a database indicates the number of rows when all rows are created. You can select databases in the GUI. You can set a smaller number of rows in the Stop field (double click). The Created field is updated for every 10,000 rows. You can cancel the creation at any time (checked for every 10,000 rows). You can continue the creation at a later time. It takes about 5 minutes to create all 5 databases and it uses about 140 MB of disk space. Running examples If you've created all tables with the maximum number of rows, the tables contains 10,000, 50,000, 100,000, 500,000 and 1,000,000 rows. For examples 1 - 4 it takes a long time to extract data from the last two tables. Because the examples displays the result array with _ArrayDisplayEx, you can exit an example by clicking the Exit Script button, when the array with 100,000 rows has been displayed. In this way you can skip the last two tables that takes long time. If you're using AutoIt 3.3.10, please read this post. Example1.au3: _SQLite_GetTable2d Example1 extracts data from the tables with _SQLite_GetTable2d: ;#AutoIt3Wrapper_UseX64=y #include <SQLite.au3> #include "..\..\..\Includes\ArrayDisplayEx.au3" Opt( "MustDeclareVars", 1 ) Example( "10000.db" ) Example( "50000.db" ) Example( "100000.db" ) Example( "500000.db" ) Example( "1000000.db" ) Func Example( $sDb ) If Not FileExists( $sDb ) Then Return _SQLite_Startup() _SQLite_Open( $sDb ) Local $hTimer = TimerInit() Local $aResult, $iRows, $iColumns Local $sSQL = "SELECT * FROM lvdata;" ConsoleWrite( "Db = " & $sDb & @CRLF ) _SQLite_GetTable2d( -1, $sSQL, $aResult, $iRows, $iColumns ) ConsoleWrite( "Time = " & TimerDiff( $hTimer ) & @CRLF ) ConsoleWrite( "Rows = " & $iRows & @CRLF & @CRLF ) _ArrayDisplayEx( $aResult ) _SQLite_Close() _SQLite_Shutdown() EndFunc Time measurements on my PC: 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time = 1867.58359001979 1478.42919526511 Rows = 10000 10000 Db = 50000.db 50000.db Time = 9387.16462453407 7352.46471634831 Rows = 50000 50000 Db = 100000.db 100000.db Time = 18718.1164395137 14667.2645397015 Rows = 100000 100000 Db = 500000.db 500000.db Time = 94108.9009941094 73874.0820654158 Rows = 500000 500000 Db = 1000000.db 1000000.db Time = 188802.773931406 147955.955762936 Rows = 1000000 1000000 Example2.au3: sqlite3_get_table In Example2 _SQLite_GetTable2d is replaced by _SQLite_GetTableEx which implements sqlite3_get_table: Func _SQLite_GetTableEx( $hDB, $sSQL, ByRef $aResult, ByRef $iRows, ByRef $iColumns, $iMaxChars = 256 ) ; Call sqlite3_get_table If __SQLite_hChk($hDB, 2) Then Return SetError(@error, 0, $SQLITE_MISUSE) If $iMaxChars = "" Or $iMaxChars < 1 Or $iMaxChars = Default Then $iMaxChars = 256 Local $tSQL8 = __SQLite_StringToUtf8Struct($sSQL) If @error Then Return SetError(3, @error, 0) Local $avRval = DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_get_table", _ "ptr", $hDB, _ ; An open database "struct*", $tSQL8, _ ; SQL to be executed "ptr*", 0, _ ; Results of the query "int*", 0, _ ; Number of result rows "int*", 0, _ ; Number of result columns "long*", 0) ; Error msg written here If @error Then Return SetError(1, @error, $SQLITE_MISUSE) ; DllCall error ; Copy data $iRows = $avRval[4] $iColumns = $avRval[5] Local $pResult = $avRval[3] Local $iPtrSize = @AutoItX64 ? 8 : 4 Local $tagChars = "char[" & $iMaxChars & "]" If $iColumns = 1 Then Dim $aResult[$iRows+1] ; Add one row for column names For $i = 0 To $iRows $aResult[$i] = DllStructGetData( DllStructCreate( $tagChars, DllStructGetData( DllStructCreate( "ptr", $pResult ), 1 ) ), 1 ) $pResult += $iPtrSize Next Else Dim $aResult[$iRows+1][$iColumns] ; Add one row for column names For $i = 0 To $iRows For $j = 0 To $iColumns - 1 $aResult[$i][$j] = DllStructGetData( DllStructCreate( $tagChars, DllStructGetData( DllStructCreate( "ptr", $pResult ), 1 ) ), 1 ) $pResult += $iPtrSize Next Next EndIf ; Cleanup DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_free_table", "ptr", $avRval[3]) If @error Then Return SetError(1, @error, $SQLITE_MISUSE) ; DllCall error EndFunc Note the loops to copy data from the C-array to the AutoIt array. There are two loops for 1D and 2D arrays. These loops are tight and fast loops: 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time = 483.665432687752 406.576381743318 Rows = 10000 10000 Db = 50000.db 50000.db Time = 2424.12387220034 2031.13843558957 Rows = 50000 50000 Db = 100000.db 100000.db Time = 4816.86633631272 3969.70711978683 Rows = 100000 100000 Db = 500000.db 500000.db Time = 24276.2591765753 20212.6546837174 Rows = 500000 500000 Db = 1000000.db 1000000.db Time = 48510.3322877481 40355.7039802608 Rows = 1000000 1000000 Example3.au3: General usage of the UDF Example3 shows the general usage of the UDF (AccessingVariables.au3). AccessVariables05 is called with the method function GetTableData and 5 parameters. Especially the code in SQLite_GetTableEx is reorganized to fit into the UDF. Full code in Example3.au3: ;#AutoIt3Wrapper_UseX64=y Global $g_hDll_SQLite = 0 ; AutoIt v3.3.10 Global $__g_hDll_SQLite = 0 ; AutoIt v3.3.12/14 #include <SQLite.au3> #include "..\..\..\Includes\AccessingVariables.au3" #include "..\..\..\Includes\AccVarsUtilities.au3" #include "..\..\..\Includes\ArrayDisplayEx.au3" Opt( "MustDeclareVars", 1 ) Example( "10000.db" ) Example( "50000.db" ) Example( "100000.db" ) Example( "500000.db" ) Example( "1000000.db" ) Func Example( $sDb ) If Not FileExists( $sDb ) Then Return _SQLite_Startup() If $g_hDll_SQLite Then $__g_hDll_SQLite = $g_hDll_SQLite _SQLite_Open( $sDb ) Local $hTimer = TimerInit() Local $pResult, $iRows, $iColumns Local $sSQL = "SELECT * FROM lvdata;" ConsoleWrite( "Db = " & $sDb & @CRLF ) Local $hTimer2 = TimerInit() _SQLite_GetTableEx( -1, $sSQL, $pResult, $iRows, $iColumns ) ConsoleWrite( "Time (SQLite) = " & TimerDiff( $hTimer2 ) & @CRLF ) $iRows += 1 ; Add one row for column names Local $aResult Local $iMaxChars = 10 AccessVariables05( GetTableData, $aResult, $pResult, $iRows, $iColumns, $iMaxChars ) _SQLite_FreeTable( $pResult ) ConsoleWrite( "Time (total) = " & TimerDiff( $hTimer ) & @CRLF & @CRLF ) _ArrayDisplayEx( $aResult ) _SQLite_Close() _SQLite_Shutdown() EndFunc Func GetTableData( $vaResult, $vpResult, $viRows, $viColumns, $viMaxChars ) ; Convert variants to AutoIt variables Local $pResult = Ptr( AccVars_VariantToVariable( $vpResult ) ) Local $iRows = AccVars_VariantToVariable( $viRows ) Local $iColumns = AccVars_VariantToVariable( $viColumns ) Local $iMaxChars = AccVars_VariantToVariable( $viMaxChars ) Local $iElements = $iRows * $iColumns ; Create SAFEARRAYBOUND structure for two dimensions Local $tSafeArrayBound = DllStructCreate( $tagSAFEARRAYBOUND & ( $iColumns > 1 ? $tagSAFEARRAYBOUND : "" ) ), $i = 0 If $iColumns > 1 Then DllStructSetData( $tSafeArrayBound, 1, $iColumns ) ; Dimension 2: Elements DllStructSetData( $tSafeArrayBound, 2, 0 ) ; Lower bound $i = 2 EndIf DllStructSetData( $tSafeArrayBound, $i+1, $iRows ) ; Dimension 1: Elements DllStructSetData( $tSafeArrayBound, $i+2, 0 ) ; Lower bound ; Create safearray of BSTRs with one or two dimensions Local $pSafeArray = SafeArrayCreate( $VT_BSTR, $iColumns > 1 ? 2 : 1, $tSafeArrayBound ) ; Pointer to data Local $pSafeArrayData SafeArrayAccessData( $pSafeArray, $pSafeArrayData ) ; Character buffer Local $tagChars = "char[" & $iMaxChars & "]" ; Pointer size Local $iPtrSize = @AutoItX64 ? 8 : 4 ; Fill safearray Local $hTimer = TimerInit() For $i = 0 To $iElements - 1 DllStructSetData( DllStructCreate( "ptr", $pSafeArrayData ), 1, SysAllocString( DllStructGetData( DllStructCreate( $tagChars, DllStructGetData( DllStructCreate( "ptr", $pResult ), 1 ) ), 1 ) ) ) $pSafeArrayData += $iPtrSize $pResult += $iPtrSize Next ConsoleWrite( "Time (loop) = " & TimerDiff( $hTimer ) & @CRLF ) SafeArrayUnaccessData( $pSafeArray ) ; --- Set $vaResult to match an array of basic strings --- ; Set vt element to $VT_ARRAY + $VT_BSTR Local $tvt = DllStructCreate( "word", $vaResult ) DllStructSetData( $tvt, 1, $VT_ARRAY + $VT_BSTR ) ; <<<< Not a proper AutoIt array >>>> ; This is an array of basic strings and not variants as a usual AutoIt array ; Set data element to safearray pointer Local $pData = $vaResult + 8 Local $tData = DllStructCreate( "ptr", $pData ) DllStructSetData( $tData, 1, $pSafeArray ) ; <<<< On function exit the safearray contained in a variant is converted to a native AutoIt array >>>> EndFunc Func _SQLite_GetTableEx( $hDB, $sSQL, ByRef $pResult, ByRef $iRows, ByRef $iColumns ) If __SQLite_hChk($hDB, 2) Then Return SetError(@error, 0, $SQLITE_MISUSE) Local $tSQL8 = __SQLite_StringToUtf8Struct($sSQL) If @error Then Return SetError(3, @error, 0) Local $avRval = DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_get_table", _ "ptr", $hDB, _ ; An open database "struct*", $tSQL8, _ ; SQL to be executed "ptr*", 0, _ ; Results of the query "int*", 0, _ ; Number of result rows "int*", 0, _ ; Number of result columns "long*", 0) ; Error msg written here If @error Then Return SetError(1, @error, $SQLITE_MISUSE) ; DllCall error $pResult = $avRval[3] $iRows = $avRval[4] $iColumns = $avRval[5] EndFunc Func _SQLite_FreeTable( $pTable ) DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_free_table", "ptr", $pTable) If @error Then Return SetError(1, @error, $SQLITE_MISUSE) ; DllCall error EndFunc The purpose of the UDF is to be able to use a safearray instead of a native AutoIt array. A safearray can be accessed by a function coded in assembler, C, C++, C# or FreeBasic which a native AutoIt array can't. In Example3 data is copied from the C-array to a safearray with pure AutoIt code. In first place the loop to fill the safearray uses much more time than the loops in Example2. When data is copied, the safearray is converted to a native AutoIt array, and the C-array is deleted. Time measurements: 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time (SQLite) = 23.1510956480495 15.8646911922054 Time (loop) = 1259.64312687043 996.176992582274 Time (total) = 1332.95543768019 1052.21221334371 Db = 50000.db 50000.db Time (SQLite) = 114.037493676343 76.4651352473028 Time (loop) = 6349.05395873402 5002.66300074637 Time (total) = 6711.25392094445 5282.21047901322 Db = 100000.db 100000.db Time (SQLite) = 173.200050312207 134.708718363014 Time (loop) = 12620.353116337 10034.0305563544 Time (total) = 13289.4445210948 10571.7439330294 Db = 500000.db 500000.db Time (SQLite) = 860.637402471615 672.991986063297 Time (loop) = 64303.8053870632 52010.5345339555 Time (total) = 67677.4638436421 54740.0105611307 Db = 1000000.db 1000000.db Time (SQLite) = 1712.64277058465 1333.27875456231 Time (loop) = 143114.724853732 119586.97418064 Time (total) = 149859.375441548 125065.107209883 Example4.au3: Simplified usage of the UDF Because only one safearray and one AutoIt array is involved, we can use AccVars_SafeArrayToArray in AccVarsUtilities.au3 to perform the conversion. We don't need to use one of the AccessVariablesXY functions and we don't need to implement a method function or handle variants: ;#AutoIt3Wrapper_UseX64=y Global $g_hDll_SQLite = 0 ; AutoIt v3.3.10 Global $__g_hDll_SQLite = 0 ; AutoIt v3.3.12/14 #include <SQLite.au3> #include "..\..\..\Includes\AccVarsUtilities.au3" #include "..\..\..\Includes\ArrayDisplayEx.au3" Opt( "MustDeclareVars", 1 ) Example( "10000.db" ) Example( "50000.db" ) Example( "100000.db" ) Example( "500000.db" ) Example( "1000000.db" ) Func Example( $sDb ) If Not FileExists( $sDb ) Then Return _SQLite_Startup() If $g_hDll_SQLite Then $__g_hDll_SQLite = $g_hDll_SQLite _SQLite_Open( $sDb ) Local $hTimer = TimerInit() Local $pResult, $iRows, $iColumns Local $sSQL = "SELECT * FROM lvdata;" ConsoleWrite( "Db = " & $sDb & @CRLF ) Local $hTimer2 = TimerInit() _SQLite_GetTableEx( -1, $sSQL, $pResult, $iRows, $iColumns ) ConsoleWrite( "Time (SQLite) = " & TimerDiff( $hTimer2 ) & @CRLF ) $iRows += 1 ; Add one row for column names ; Create SAFEARRAYBOUND structure for two dimensions Local $tSafeArrayBound = DllStructCreate( $tagSAFEARRAYBOUND & ( $iColumns > 1 ? $tagSAFEARRAYBOUND : "" ) ), $i = 0 If $iColumns > 1 Then DllStructSetData( $tSafeArrayBound, 1, $iColumns ) ; Dimension 2: Elements DllStructSetData( $tSafeArrayBound, 2, 0 ) ; Lower bound $i = 2 EndIf DllStructSetData( $tSafeArrayBound, $i+1, $iRows ) ; Dimension 1: Elements DllStructSetData( $tSafeArrayBound, $i+2, 0 ) ; Lower bound ; Create safearray of BSTRs with one or two dimensions Local $pSafeArray = SafeArrayCreate( $VT_BSTR, $iColumns > 1 ? 2 : 1, $tSafeArrayBound ) ; Pointer to data Local $pSafeArrayData SafeArrayAccessData( $pSafeArray, $pSafeArrayData ) ; Character buffer Local $iMaxChars = 10 Local $tagChars = "char[" & $iMaxChars & "]" ; Pointer size Local $iPtrSize = @AutoItX64 ? 8 : 4 ; Fill safearray Local $pResult0 = $pResult Local $hTimer3 = TimerInit() For $i = 0 To $iRows * $iColumns - 1 DllStructSetData( DllStructCreate( "ptr", $pSafeArrayData ), 1, SysAllocString( DllStructGetData( DllStructCreate( $tagChars, DllStructGetData( DllStructCreate( "ptr", $pResult ), 1 ) ), 1 ) ) ) $pSafeArrayData += $iPtrSize $pResult += $iPtrSize Next ConsoleWrite( "Time (loop) = " & TimerDiff( $hTimer3 ) & @CRLF ) SafeArrayUnaccessData( $pSafeArray ) _SQLite_FreeTable( $pResult0 ) ; AutoIt array Local $aResult AccVars_SafeArrayToArray( $pSafeArray, $aResult ) ConsoleWrite( "Time (total) = " & TimerDiff( $hTimer ) & @CRLF & @CRLF ) _ArrayDisplayEx( $aResult ) _SQLite_Close() _SQLite_Shutdown() EndFunc 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time (SQLite) = 17.4150607486656 14.1043180396414 Time (loop) = 1324.75255315058 1029.05446850528 Time (total) = 1391.56528036588 1083.47476715366 Db = 50000.db 50000.db Time (SQLite) = 95.3244555559804 82.5873772878063 Time (loop) = 6532.85558900468 5074.77180809772 Time (total) = 6874.98857170404 5363.29347697801 Db = 100000.db 100000.db Time (SQLite) = 171.70619887396 137.223220524278 Time (loop) = 13226.8659429023 10330.4403814197 Time (total) = 13889.9586697408 10871.0854969522 Db = 500000.db 500000.db Time (SQLite) = 854.537047349439 683.296291801936 Time (loop) = 67230.8330161115 53188.3987142682 Time (total) = 70543.9902123918 55966.6529250066 Db = 1000000.db 1000000.db Time (SQLite) = 1713.11098440709 1361.08095887974 Time (loop) = 151801.206107725 123302.690816526 Time (total) = 158540.361416743 128827.087527172 Example5.au3: C++ code In Example5 the loop to copy data from the C-array to the safearray is replaced by C++ code. This is the loop in Example4: ; Fill safearray Local $pResult0 = $pResult Local $hTimer3 = TimerInit() For $i = 0 To $iRows * $iColumns - 1 DllStructSetData( DllStructCreate( "ptr", $pSafeArrayData ), 1, SysAllocString( DllStructGetData( DllStructCreate( $tagChars, DllStructGetData( DllStructCreate( "ptr", $pResult ), 1 ) ), 1 ) ) ) $pSafeArrayData += $iPtrSize $pResult += $iPtrSize Next ConsoleWrite( "Time (loop) = " & TimerDiff( $hTimer3 ) & @CRLF ) In Example5 the loop is replaced by a DllCall: ; Fill safearray Local $hTimer3 = TimerInit() Local $hGetTableDll = DllOpen( @AutoItX64 ? "GetTable_x64.dll" : "GetTable.dll" ) DllCall( $hGetTableDll, "int:cdecl", "GetTable", "int", $iRows * $iColumns, "ptr", $pResult, "ptr", $pSafeArrayData, "int", 256 ) ConsoleWrite( "Time (loop) = " & TimerDiff( $hTimer3 ) & @CRLF ) DllClose( $hGetTableDll ) The Dll-files (8 and 9 KB) are included in the zip-file. And this is the C++ code: #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <OleAuto.h> extern "C" __declspec(dllexport) int __cdecl GetTable( int iElements, char **pResult, BSTR *pSafeArrayData, int iMaxChars ) { int iCharSize; BSTR sBuffer; for ( int i = 0; i < iElements; i++ ) { iCharSize = MultiByteToWideChar( CP_UTF8, 0, pResult[i], -1, NULL, 0 ); if ( iCharSize > iMaxChars ) { iCharSize = iMaxChars; } sBuffer = SysAllocStringLen( NULL, iCharSize ); MultiByteToWideChar( CP_UTF8, 0, pResult[i], -1, sBuffer, iCharSize ); pSafeArrayData[i] = sBuffer; } return 0; } It's not much code but it makes a big difference. At this point we can really see some performance improvements: 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time (SQLite) = 17.879859753638 13.0433770827516 Time (loop) = 14.2736909526912 10.4447857519625 Time (total) = 91.6964756674335 65.9479816314499 Db = 50000.db 50000.db Time (SQLite) = 84.786660638378 79.0254340589442 Time (loop) = 63.1917572018103 45.9053071102778 Time (total) = 400.493344503398 331.284103048275 Db = 100000.db 100000.db Time (SQLite) = 179.167608586765 134.67712087162 Time (loop) = 133.477003851899 91.1557027167192 Time (total) = 812.997001369663 628.453799373235 Db = 500000.db 500000.db Time (SQLite) = 877.786144244536 677.600973834568 Time (loop) = 593.045083620342 441.694591827236 Time (total) = 3930.40734165769 3169.40903933015 Db = 1000000.db 1000000.db Time (SQLite) = 1709.34257301543 1340.73765641414 Time (loop) = 1177.70597022203 887.914832692828 Time (total) = 7898.99402933472 6350.2593604695 Example6.au3: Safearray only SafeArrayDisplay was introduced in the previous post. The old version was only able to handle integers ($VT_I4). The new version can also handle strings ($VT_BSTR). We can replace _ArrayDisplayEx with SafeArrayDisplay, and we don't need to convert the safearray to a native AutoIt array. This halves the total execution time: 32 bit 64 bit ------ ------ Db = 10000.db 10000.db Time (SQLite) = 17.3684525471736 20.9012069874957 Time (loop) = 14.0346094688457 19.0544895236322 Time (total) = 36.3534062047047 44.0450149155818 Db = 50000.db 50000.db Time (SQLite) = 104.392450455003 79.7554221353439 Time (loop) = 62.9584934597501 47.4223525396382 Time (total) = 191.106722871593 146.179073416577 Db = 100000.db 100000.db Time (SQLite) = 203.835110791966 158.260029786838 Time (loop) = 120.158807728621 93.6750619450983 Time (total) = 370.362151655785 289.398301441027 Db = 500000.db 500000.db Time (SQLite) = 895.89982181088 728.70761913627 Time (loop) = 587.891118469169 441.994344046843 Time (total) = 1716.73969317784 1362.86419063576 Db = 1000000.db 1000000.db Time (SQLite) = 1780.12814545906 1427.71566645834 Time (loop) = 1186.23090118482 878.533031475645 Time (total) = 3438.9228534195 2694.91928298826 Note that the UDF (AccessingVariables.au3) is not included in Example6. The UDF is used for conversions between AutoIt arrays and safearrays. Since there are no conversions the UDF is not used.
    1 point
  10. water

    Select statement error

    Use "==" for a case sensitive comparison. https://www.autoitscript.com/autoit3/docs/intro/lang_operators.htm
    1 point
  11. Since monoceres has released I searched for a way to map the 2D image of the earth to a 3D sphere with rotation. Here the result (after 9 years of research ^^) as a non realistic physical animation: ==> Due to the fact that AutoIt / GDI+ are not that fast I couldn't add a moon animation additionally. Thanks to one of Eukalyptus' code to pointing me to the right direction. U rock man. Source code extract only - not working because of missing binary data (images): ;coded by UEZ build 2017-03-18 #pragma compile(x64, false) #pragma compile(Icon, "c:\Program Files (x86)\AutoIt3\Icons\au3.ico") #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe /rm #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3" #include <GDIPlus.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit Global Const $iW = 800, $iW2 = ($iW - 100) / 2, $iH = 500, $fRad = ACos(-1) / 180, $sTitle = "GDI+ Rotating Earth v1.7 coded by UEZ 2017" AutoItSetOption("GUIOnEventMode", 1) GDIPlus_RotatingEarth() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_RotatingEarth() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH) GUISetState(@SW_SHOW, $hGUI) ;create canvas elements Local Const $hDC = _WinAPI_GetDC($hGUI) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) _GDIPlus_GraphicsSetInterpolationMode($hCanvas, $GDIP_INTERPOLATIONMODE_NEARESTNEIGHBOR) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HALF) Local Const $hBrush_Clr = _GDIPlus_BrushCreateSolid(0xFF000000), _ $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xFFF0F0F0), _ $hFormat_FPS = _GDIPlus_StringFormatCreate(), _ $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _ $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _ $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 60, 16), _ $hImage_Earth = _GDIPlus_BitmapCreateFromMemory(_Earth()), _ $hImage_Galaxy = _GDIPlus_BitmapCreateFromMemory(_Galaxy()), _ $hImage_Clouds = _GDIPlus_BitmapCreateFromMemory(_Clouds()), _ $hImage_Moon = _GDIPlus_BitmapCreateFromMemory(_Moon()), _ $hImage_USSE = _GDIPlus_BitmapCreateFromMemory(_USSE()), _ $hMatrix = _GDIPlus_MatrixCreate(), $hMatrix2 = _GDIPlus_MatrixCreate(), _ $hPath = _GDIPlus_PathCreate(), $hPath2 = _GDIPlus_PathCreate(), _ $hPen = _GDIPlus_PenCreate(0xC0FFFFFF, 1) _GDIPlus_ImageRotateFlip($hImage_USSE, 4) Local $aDim = _GDIPlus_ImageGetDimension($hImage_Earth) Local $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage_Earth) _GDIPlus_GraphicsDrawStringEx($hGfx, "Coded by UEZ 2017 ^^", $hFont_FPS, _GDIPlus_RectFCreate(0, $aDim[1] / 2 - 4, 120, 12), $hFormat_FPS, $hBrush_FPS) _GDIPlus_ImageDispose($hGfx) Local Const $hTexture_Earth = _GDIPlus_TextureCreate($hImage_Earth), $hTexture_Clouds = _GDIPlus_TextureCreate($hImage_Clouds) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "ptr", $hTexture_Earth, "float", -200, "float", 0, "long", 0) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "ptr", $hTexture_Clouds, "float", -100, "float", 0, "long", 0) Local $iDiameter = $aDim[0] < $aDim[1] ? $aDim[0] : $aDim[1], _ $fDiameter2 = $iDiameter / 2, _ $fDX = ($iW - $iDiameter) / 2, $fDY = ($iH - $iDiameter) / 2 _GDIPlus_PathAddEllipse($hPath, $fDX - 1, $fDY - 1, $iDiameter + 2, $iDiameter + 2) Local Const $hBrush = _GDIPlus_PathBrushCreateFromPath($hPath) _GDIPlus_PathBrushSetCenterColor($hBrush, 0x02000008) _GDIPlus_PathBrushSetCenterPoint($hBrush, $fDX + $fDiameter2 + 1, $fDY + $fDiameter2 + 1) _GDIPlus_PathBrushSetSurroundColor($hBrush, 0xF8000000) _GDIPlus_PathBrushSetGammaCorrection($hBrush, 1) _GDIPlus_PathBrushSetFocusScales($hBrush, 0.50, 0.50) _GDIPlus_PathAddEllipse($hPath2, -1, -1, 201, 201) Local Const $hBrush2 = _GDIPlus_PathBrushCreateFromPath($hPath2) _GDIPlus_PathBrushSetCenterColor($hBrush2, 0x0800000) _GDIPlus_PathBrushSetCenterPoint($hBrush2, 100, 100) _GDIPlus_PathBrushSetSurroundColor($hBrush2, 0xFF000000) _GDIPlus_PathBrushSetGammaCorrection($hBrush2, 1) _GDIPlus_PathBrushSetFocusScales($hBrush2, 0.50, 0.50) $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage_Moon) _GDIPlus_GraphicsFillEllipse($hGfx, -1, -1, 201, 201, $hBrush2) _GDIPlus_ImageDispose($hGfx) $iFPS = 0 GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") AdlibRegister("CalcFPS", 1000) Local $fTimer1, $fTimer2, $fScale, $fTmp, $fX, $fSin, $fZ, $fS, $zz, $z = 90, $iStep = 4 ;the higher $iStep is the faster the animation but lower the quality. Local $fPosX, $fPosY, $fSize, $fSpeed, $aMeteor[4] = [0, 10 + Random() * ($iH - 20), 5 + Random() * 10, 5 + Random() * 10] $fPosX = $iW + 60 $fPosY = Random() * ($iH - 100) + 50 $fSize = 0.5 + Random() * 2 $fSpeed = Random() * 3 + 1 $fTimer1 = TimerInit() $fTimer2 = TimerInit() Do DllCall($__g_hGDIPDll, "int", "GdipDrawImageRect", "handle", $hCanvas, "handle", $hImage_Galaxy, "float", 0, "float", 0, _ "float", $iW, "float", $iH) DllCall($__g_hGDIPDll, "int", "GdipSetSmoothingMode", "handle", $hCanvas, "int", 4) If TimerDiff($fTimer1) > 10000 Then DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hCanvas, "handle", $hPen, "float", $aMeteor[0], "float", $aMeteor[1], _ "float", $aMeteor[0] + $aMeteor[2] * 3, "float", $aMeteor[1] + $aMeteor[3] * 3) $aMeteor[0] += $aMeteor[2] $aMeteor[1] += $aMeteor[3] If BitOR($aMeteor[0] > $iW, $aMeteor[1] > $iH, $aMeteor[0] < 0, $aMeteor[1] < 0) Then $aMeteor[0] = 0 $aMeteor[1] = Random() * ($iH * 0.75) $aMeteor[2] = 8 + Random() * 12 $aMeteor[3] = 7 + Random() * 10 $fTimer1 = TimerInit() EndIf EndIf If TimerDiff($fTimer2) > 30000 Then DllCall($__g_hGDIPDll, "int", "GdipDrawImageRect", "handle", $hCanvas, "handle", $hImage_USSE, "float", $fPosX, "float", $fPosY, _ "float", 50 * $fSize, "float", 12 * $fSize) $fPosX -= $fSpeed If $fPosX < -100 Then $fPosX = $iW + 30 $fPosY = Random() * ($iH - 100) + 50 $fSize = Random() * 2 $fSpeed = Random() * 3 + 1 $fTimer2 = TimerInit() EndIf EndIf $zz = $z * $fRad $fX = $iW2 - Cos($zz) * 345 $z -= 0.5 $fZ = Sin($zz) $fS = 100 - $fZ * 50 DllCall($__g_hGDIPDll, "int", "GdipSetSmoothingMode", "handle", $hCanvas, "int", 1) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "ptr", $hTexture_Earth, "float", 0.75, "float", 0, "long", 0) DllCall($__g_hGDIPDll, "int", "GdipTranslateTextureTransform", "ptr", $hTexture_Clouds, "float", 1.25, "float", 0, "long", 0) If $fZ > 0 Then _GDIPlus_GraphicsDrawImageRect($hCanvas, $hImage_Moon, $fX, 110, $fS, $fS) For $i = 1 To $fDiameter2 Step $iStep $fScale = 1 + $i / $fDiameter2 DllCall($__g_hGDIPDll, "int", "GdipSetMatrixElements", "handle", $hMatrix, "float", 1.0, "float", 0.0, "float", 0.0, "float", 1.0, "float", 0.0, "float", 0.0) DllCall($__g_hGDIPDll, "int", "GdipTranslateMatrix", "handle", $hMatrix, "float", $fDX + $fDiameter2, "float", $fDY + $fDiameter2, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipScaleMatrix", "handle", $hMatrix, "float", $fScale, "float", $fScale, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipTranslateMatrix", "handle", $hMatrix, "float", -$fDiameter2, "float", -$fDiameter2, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipSetWorldTransform", "handle", $hCanvas, "handle", $hMatrix) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hCanvas, "handle", $hTexture_Earth, _ "float", $i, "float", $i, "float", $iDiameter -2 * $i, "float", $iDiameter - 2 * $i) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hCanvas, "handle", $hTexture_Clouds, _ "float", $i, "float", $i, "float", $iDiameter -2 * $i, "float", $iDiameter - 2 * $i) Next _GDIPlus_MatrixSetElements($hMatrix) _GDIPlus_GraphicsSetTransform($hCanvas, $hMatrix) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", $fDX, "float", $fDY, "float", $iDiameter, "float", $iDiameter) Else For $i = 1 To $fDiameter2 Step $iStep $fScale = 1 + $i / $fDiameter2 DllCall($__g_hGDIPDll, "int", "GdipSetMatrixElements", "handle", $hMatrix, "float", 1.0, "float", 0.0, "float", 0.0, "float", 1.0, "float", 0.0, "float", 0.0) DllCall($__g_hGDIPDll, "int", "GdipTranslateMatrix", "handle", $hMatrix, "float", $fDX + $fDiameter2, "float", $fDY + $fDiameter2, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipScaleMatrix", "handle", $hMatrix, "float", $fScale, "float", $fScale, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipTranslateMatrix", "handle", $hMatrix, "float", -$fDiameter2, "float", -$fDiameter2, "int", 0) DllCall($__g_hGDIPDll, "int", "GdipSetWorldTransform", "handle", $hCanvas, "handle", $hMatrix) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hCanvas, "handle", $hTexture_Earth, _ "float", $i, "float", $i, "float", $iDiameter - 2 * $i, "float", $iDiameter - 2 * $i) DllCall($__g_hGDIPDll, "int", "GdipFillEllipse", "handle", $hCanvas, "handle", $hTexture_Clouds, _ "float", $i, "float", $i, "float", $iDiameter - 2 * $i, "float", $iDiameter - 2 * $i) Next _GDIPlus_MatrixSetElements($hMatrix) _GDIPlus_GraphicsSetTransform($hCanvas, $hMatrix) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", $fDX, "float", $fDY, "float", $iDiameter, "float", $iDiameter) _GDIPlus_GraphicsDrawImageRect($hCanvas, $hImage_Moon, $fX, 110, $fS, $fS) EndIf _GDIPlus_GraphicsDrawStringEx($hCanvas, "FPS: " & $iShowFPS, $hFont_FPS, $tLayout_FPS, $hFormat_FPS, $hBrush_FPS) ;draw background message text _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI $iFPS += 1 If $bExit Then ExitLoop Until False ;Not Sleep(10) AdlibUnRegister("CalcFPS") ;release resources _GDIPlus_PenDispose($hPen) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush2) _GDIPlus_PathDispose($hPath) _GDIPlus_PathDispose($hPath2) _GDIPlus_MatrixDispose($hMatrix) _GDIPlus_MatrixDispose($hMatrix2) _GDIPlus_ImageDispose($hImage_Earth) _GDIPlus_ImageDispose($hImage_Galaxy) _GDIPlus_ImageDispose($hImage_Clouds) _GDIPlus_ImageDispose($hImage_Moon) _GDIPlus_ImageDispose($hImage_USSE) _GDIPlus_BrushDispose($hTexture_Earth) _GDIPlus_BrushDispose($hTexture_Clouds) _GDIPlus_FontDispose($hFont_FPS) _GDIPlus_FontFamilyDispose($hFamily_FPS) _GDIPlus_StringFormatDispose($hFormat_FPS) _GDIPlus_BrushDispose($hBrush_Clr) _GDIPlus_BrushDispose($hBrush_FPS) _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI, $hDC) GUIDelete($hGUI) EndFunc ;==>GDIPlus_RotatingEarth Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func CalcFPS() ;display FPS $iShowFPS = $iFPS $iFPS = 0 EndFunc ;==>CalcFPS ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2016-12-01 ... Download: Rotating Earth v1.7.au3 In line 92 you can modify the $iStep variable -> the higher $iStep is the faster the animation & lower the quality. So long...
    1 point
  12. Melba23

    screenshot region

    hendrikhe, Here are 2 fairly old scripts from my Snippets folder - I have posted them before several times. The first marks a red rectangle, while the second creates a transparent rectangle, the contents of which are stored in a file and then displayed: Please ask if you have any questions. M23
    1 point
  13. spudw2k

    Finding values on excel

    Not to discount Subz's solution, but you may also want to check out the _Excel_RangeFind method in the Excel UDF. It uses the Excel COM find method, which in theory should be more efficient. There are a few examples using it in the help file. Might not make much of a difference depending on your use case(s), but if you are dealing with a very large spreadsheet I would expect it to have better performance. Still...props to @Subz for providing a concise solution.
    1 point
  14. Subz

    Finding values on excel

    Simple Example: #include <Array.au3> #include <Excel.au3> Local $sWorkbook = @ScriptDir & "\Excel.xlsx" Local $oExcel =_Excel_Open(False) Local $oWorkbook = _Excel_BookOpen($oExcel, $sWorkbook, True) Local $aWorkbook = _Excel_RangeRead($oWorkbook, Default) _ArrayDisplay($aWorkbook) MsgBox(0, "ID", "ID#: " & _SearchExcel("COn", "Brianna")) Func _SearchExcel($sCType, $sPS) For $i = 1 To UBound($aWorkbook) - 1 If $aWorkbook[$i][2] = $sCType And $aWorkbook[$i][3] = $sPS Then Return $aWorkbook[$i][0] Next Return 0 EndFunc
    1 point
  15. I got some free time and traslated the C++ code to AutoIt. I've attached a sample. AutoIt Code ;~ #AutoIt3Wrapper_UseX64=y Global Const $S_OK = 0 ;I'm lazy for that you'll see ptr type in most of interfaces parameters... :P #Region Interfaces Global Const $sTagCLRMetaHost = "GetRuntime hresult(wstr;struct*;ptr);" & _ "GetVersionFromFile hresult(ptr;ptr;ptr);" & _ "EnumerateInstalledRuntimes hresult(ptr)" & _ "EnumerateLoadedRuntimes hresult(ptr;ptr)" & _ "RequestRuntimeLoadedNotification hresult(ptr,ptr,ptr)" & _ "QueryLegacyV2RuntimeBinding hresult(ptr;ptr)" & _ "ExitProcess hresult(int)" Global Const $sTagCLRRuntimeInfo = "GetVersionString hresult(ptr;ptr);" & _ "GetRuntimeDirectory hresult(ptr;ptr);" & _ "IsLoaded hresult(ptr;ptr);" & _ "LoadErrorString hresult(ptr;ptr;ptr;ptr);" & _ "LoadLibrary hresult(ptr;ptr);" & _ "GetProcAddress hresult(ptr;ptr);" & _ "GetInterface hresult(ptr;ptr;ptr);" & _ "IsLoadable hresult(Bool*);" & _ "SetDefaultStartupFlags hresult(ptr;ptr);" & _ "GetDefaultStartupFlags hresult(ptr;ptr;ptr);" & _ "BindAsLegacyV2Runtime hresult();" & _ "IsStarted hresult(ptr;ptr);" Global Const $sTagRuntimeHost = "Start hresult();Stop hresult();SetHostControl hresult(ptr);GetCLRControl hresult(ptr);" & _ "UnloadAppDomain hresult(ptr;ptr);ExecuteInAppDomain hresult(ptr;ptr;ptr);GetCurrentAppDomainId hresult(ptr);" & _ "ExecuteApplication hresult(ptr;ptr;ptr;ptr;ptr;ptr);" & _ "ExecuteInDefaultAppDomain hresult(wstr;wstr;wstr;wstr;ptr*);" #EndRegion Interfaces #Region CLSID & IID Global Const $sCLSID_CLRMetaHost = "{9280188d-0e8e-4867-b30c-7fa83884e8de}" Global Const $sIID_ICLRMetaHost = "{d332db9e-b9b3-4125-8207-a14884f53216}" Global Const $sIID_ICLRRuntimeInfo = "{BD39D1D2-BA2F-486a-89B0-B4B0CB466891}" Global Const $sCLSID_CLRRuntimeHost = "{90F1A06E-7712-4762-86B5-7A5EBA6BDB02}" Global Const $sIID_ICLRRuntimeHost = "{90F1A06C-7712-4762-86B5-7A5EBA6BDB02}" Global $tCLSID_CLRMetaHost = _WinAPI_CLSIDFromString($sCLSID_CLRMetaHost) Global $tIID_ICLRMetaHost = _WinAPI_CLSIDFromString($sIID_ICLRMetaHost) Global $tIID_ICLRRuntimeInfo = _WinAPI_CLSIDFromString($sIID_ICLRRuntimeInfo) Global $tCLSID_CLRRuntimeHost = _WinAPI_CLSIDFromString($sCLSID_CLRRuntimeHost) Global $tIID_ICLRRuntimeHost = _WinAPI_CLSIDFromString($sIID_ICLRRuntimeHost) #EndRegion CLSID & IID Local $hMSCorEE = DllOpen("MSCorEE.DLL") ;get ClrHost Local $aRet = DllCall($hMSCorEE, "long", "CLRCreateInstance", "struct*", $tCLSID_CLRMetaHost, _ "struct*", $tIID_ICLRMetaHost, "ptr*", 0) If $aRet[0] = $S_OK Then Local $pClrHost = $aRet[3] Local $oClrHost = ObjCreateInterface($pClrHost, $sIID_ICLRMetaHost, $sTagCLRMetaHost) ConsoleWrite(">oClrHost: " & IsObj($oClrHost) & @CRLF) Local $sNETFrameworkVersion = "v4.0.30319" Local $tRunInfo = DllStructCreate("ptr") $oClrHost.GetRuntime($sNETFrameworkVersion, $tIID_ICLRRuntimeInfo, DllStructGetPtr($tRunInfo)) Local $pRunInfo = DllStructGetData($tRunInfo, 1) ConsoleWrite(">pRunInfo: " & $pRunInfo & @CRLF) Local $oRunInfo = ObjCreateInterface($pRunInfo, $sIID_ICLRRuntimeInfo, $sTagCLRRuntimeInfo) ConsoleWrite(">oRunInfo: " & IsObj($oRunInfo) & @CRLF) Local $isIsLoadable = 0 $oRunInfo.IsLoadable($isIsLoadable) ConsoleWrite(">IsLoadable: " & $isIsLoadable & @CRLF) If $isIsLoadable Then Local $tRuntimeHost = DllStructCreate("ptr") $oRunInfo.GetInterface(DllStructGetPtr($tCLSID_CLRRuntimeHost), DllStructGetPtr($tIID_ICLRRuntimeHost), DllStructGetPtr($tRuntimeHost)) Local $pRuntimeHost = DllStructGetData($tRuntimeHost, 1) ConsoleWrite(">pRuntimeHost: " & $pRuntimeHost & @CRLF) Local $oRuntimeHost = ObjCreateInterface($pRuntimeHost, $sIID_ICLRRuntimeHost, $sTagRuntimeHost) ConsoleWrite(">oRuntimeHost" & IsObj($oRuntimeHost) & @CRLF) Local $iRet = 0 $oRuntimeHost.Start() $oRuntimeHost.ExecuteInDefaultAppDomain(@ScriptDir & "\C#Library.dll", "ClassLibraryDemo.ClassDemo", "NetMsgBox", "AutoIt Rocks!!! " & @CRLF & "Danyfirex does too lol!!!", $iRet) ConsoleWrite(">Ret: " & $iRet & @CRLF) EndIf EndIf DllClose($hMSCorEE) ;free Func _WinAPI_CLSIDFromString($sGUID) $tGUID = DllStructCreate('ulong Data1;ushort Data2;ushort Data3;byte Data4[8]') $iRet = DllCall('ole32.dll', 'uint', 'CLSIDFromString', 'wstr', $sGUID, 'ptr', DllStructGetPtr($tGUID)) If (@error) Or ($iRet[0]) Then Return SetError(@error, @extended, 0) EndIf Return $tGUID EndFunc ;==>_WinAPI_CLSIDFromString Super libary source code using System.Windows.Forms; namespace ClassLibraryDemo { public class ClassDemo { public static int NetMsgBox(string message) { MessageBox.Show(message); return 1; } } } Demo CLRAutoIt.zip Saludos
    1 point
  16. Update 8/5/2011: I've updated the _NaturalCompare function. Foremost, it will cope with very long strings of numbers without overflowing. I've also added an implementation of _ArraySort that takes a custom sorting function, and implemented _ArrayNaturalSort in this way. This is a different algorithm than the other I found on the board. To me, it seems more efficient. _NaturalCompare ; #FUNCTION# ==================================================================================================================== ; Name...........: _NaturalCompare ; Description ...: Compare two strings using Natural (Alphabetical) sorting. ; Syntax.........: _NaturalCompare($s1, $s2[, $iCase = 0]) ; Parameters ....: $s1, $s2 - Strings to compare ; $iCase - [Optional] Case sensitive or insensitive comparison ; |0 - Case insensitive (default) ; |1 - Case sensitive ; Return values .: Success - One of the following: ; |0 - Strings are equal ; |-1 - $s1 comes before $s2 ; |1 - $s1 goes after $s2 ; Failure - Returns -2 and Sets @Error: ; |1 - $s1 or $s2 is not a string ; |2 - $iCase is invalid ; Author ........: Erik Pilsits ; Modified.......: ; Remarks .......: Original algorithm by Dave Koelle ; Related .......: StringCompare ; Link ..........: http://www.davekoelle.com/alphanum.html ; Example .......: Yes ; =============================================================================================================================== Func _NaturalCompare($s1, $s2, $iCase = 0) ; check params If (Not IsString($s1)) Then $s1 = String($s1) If (Not IsString($s2)) Then $s2 = String($s2) ; check case, set default If $iCase <> 0 And $iCase <> 1 Then $iCase = 0 Local $n = 0 Local $s1chunk, $s2chunk Local $idx, $i1chunk, $i2chunk Local $s1temp, $s2temp While $n = 0 ; get next chunk ; STRING 1 $s1chunk = StringRegExp($s1, "^(\d+|\D+)", 1) If @error Then $s1chunk = "" Else $s1chunk = $s1chunk[0] EndIf ; STRING 2 $s2chunk = StringRegExp($s2, "^(\d+|\D+)", 1) If @error Then $s2chunk = "" Else $s2chunk = $s2chunk[0] EndIf ; ran out of chunks, strings are the same, return 0 If $s1chunk = "" And $s2chunk = "" Then Return 0 ; remove chunks from strings $s1 = StringMid($s1, StringLen($s1chunk) + 1) $s2 = StringMid($s2, StringLen($s2chunk) + 1) Select ; Case 1: both chunks contain letters Case (Not StringIsDigit($s1chunk)) And (Not StringIsDigit($s2chunk)) $n = StringCompare($s1chunk, $s2chunk, $iCase) ; Case 2: both chunks contain numbers Case StringIsDigit($s1chunk) And StringIsDigit($s2chunk) ; strip leading 0's $s1temp = $s1chunk $s2temp = $s2chunk $s1chunk = StringRegExpReplace($s1chunk, "^0*", "") $s2chunk = StringRegExpReplace($s2chunk, "^0*", "") ; record number of stripped 0's $s1temp = StringLen($s1temp) - StringLen($s1chunk) $s2temp = StringLen($s2temp) - StringLen($s2chunk) ; first check if one string is longer than the other, meaning a bigger number If StringLen($s1chunk) > StringLen($s2chunk) Then Return 1 ElseIf StringLen($s1chunk) < StringLen($s2chunk) Then Return -1 EndIf ; strings are equal length ; compare 8 digits at a time, starting from the left, to avoid overflow $idx = 1 While 1 $i1chunk = Int(StringMid($s1chunk, $idx, 8)) $i2chunk = Int(StringMid($s2chunk, $idx, 8)) ; check for end of string If $i1chunk = "" And $i2chunk = "" Then ; check number of leading 0's removed, if any - windows sorts more leading 0's above fewer leading 0's, ie 00001 < 0001 < 001 If $s1temp > $s2temp Then Return -1 ElseIf $s1temp < $s2temp Then Return 1 Else ; numbers are equal ExitLoop EndIf EndIf ; valid numbers, so compare If $i1chunk > $i2chunk Then Return 1 ElseIf $i1chunk < $i2chunk Then Return -1 EndIf ; chunks are equal, get next chunk of digits $idx += 8 WEnd ; Case 3: one chunk has letters, the other has numbers; or one is empty Case Else ; if we get here, this should be the last and deciding test, so return the result Return StringCompare($s1chunk, $s2chunk, $iCase) EndSelect WEnd Return $n EndFunc Example: #include "_NaturalCompare.au3" ConsoleWrite("StringCompare:" & @CRLF) ConsoleWrite(StringCompare("abC10", "abc2") & @CRLF) ConsoleWrite(StringCompare("abC10", "abc2", 1) & @CRLF) ConsoleWrite("_NaturalCompare:" & @CRLF) ConsoleWrite(_NaturalCompare("abC10", "abc2") & @CRLF) ConsoleWrite(_NaturalCompare("abC10", "abc2", 1) & @CRLF) Here's an implementation of array sorting that uses a custom sorting function: _ArrayNaturalSort #include-once #include <_NaturalCompare.au3> #include <_ArrayCustomSort.au3> ; #FUNCTION# ==================================================================================================================== ; Name...........: _ArrayNaturalSort ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms. ; Syntax.........: _ArrayNaturalSort(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; Parameters ....: $avArray - Array to sort ; $iDescending - [optional] If set to 1, sort descendingly ; $iStart - [optional] Index of array to start sorting at ; $iEnd - [optional] Index of array to stop sorting at ; $iSubItem - [optional] Sub-index to sort on in 2D arrays ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $iSubItem is greater than subitem count ; |4 - $avArray has too many dimensions ; |5 - Invalid sort function ; Author ........: Erik Pilsits ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; No ; =============================================================================================================================== Func _ArrayNaturalSort(ByRef $avArray, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0) Return _ArrayCustomSort($avArray, "_NaturalCompare", $iDescending, $iStart, $iEnd, $iSubItem) EndFunc ;==>_ArrayNaturalSort And the custom sorting function: _ArrayCustomSort #include-once #include <Array.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ArrayCustomSort ; Description ...: Sort a 1D or 2D array on a specific index using the quicksort/insertionsort algorithms, based on a custom sorting function. ; Syntax ........: _ArrayCustomSort(Byref $avArray, $sSortFunc[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; Parameters ....: $avArray - [in/out] Array to sort ; $sSortFunc - Name of custom sorting function. See Remarks for usage. ; $iDescending - [optional] If set to 1, sort descendingly ; $iStart - [optional] Index of array to start sorting at ; $iEnd - [optional] Index of array to stop sorting at ; $iSubItem - [optional] Sub-index to sort on in 2D arrays ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - $avArray is not an array ; |2 - $iStart is greater than $iEnd ; |3 - $iSubItem is greater than subitem count ; |4 - $avArray has too many dimensions ; |5 - Invalid sort function ; Author ........: Erik Pilsits ; Modified ......: Erik Pilsits - removed IsNumber testing, LazyCoder - added $iSubItem option, Tylo - implemented stable QuickSort algo, Jos van der Zande - changed logic to correctly Sort arrays with mixed Values and Strings, Ultima - major optimization, code cleanup, removed $i_Dim parameter ; Remarks .......: Sorting function is called with two array elements as arguments. The function should return ; 0 if they are equal, ; -1 if element one comes before element two, ; 1 if element one comes after element two. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _ArrayCustomSort(ByRef $avArray, $sSortFunc, $iDescending = 0, $iStart = 0, $iEnd = 0, $iSubItem = 0) If Not IsArray($avArray) Then Return SetError(1, 0, 0) If Not IsString($sSortFunc) Then Return SetError(5, 0, 0) Local $iUBound = UBound($avArray) - 1 ; Bounds checking If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound If $iStart < 0 Then $iStart = 0 If $iStart > $iEnd Then Return SetError(2, 0, 0) ; Sort Switch UBound($avArray, 0) Case 1 __ArrayCustomQuickSort1D($avArray, $sSortFunc, $iStart, $iEnd) If $iDescending Then _ArrayReverse($avArray, $iStart, $iEnd) Case 2 Local $iSubMax = UBound($avArray, 2) - 1 If $iSubItem > $iSubMax Then Return SetError(3, 0, 0) If $iDescending Then $iDescending = -1 Else $iDescending = 1 EndIf __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iDescending, $iStart, $iEnd, $iSubItem, $iSubMax) Case Else Return SetError(4, 0, 0) EndSwitch Return 1 EndFunc ;==>_ArrayCustomSort ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: __ArrayCustomQuickSort1D ; Description ...: Helper function for sorting 1D arrays ; Syntax.........: __ArrayCustomQuickSort1D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStart, ByRef $iEnd) ; Parameters ....: $avArray - Array to sort ; $sSortFunc - Name of sorting function. ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: Erik Pilsits - removed IsNumber testing ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func __ArrayCustomQuickSort1D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStart, ByRef $iEnd) If $iEnd <= $iStart Then Return Local $vTmp ; InsertionSort (faster for smaller segments) If ($iEnd - $iStart) < 15 Then Local $i, $j For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] For $j = $i - 1 To $iStart Step -1 If (Call($sSortFunc, $vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next $avArray[$j + 1] = $vTmp Next Return EndIf ; QuickSort Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)] Do While (Call($sSortFunc, $avArray[$L], $vPivot) < 0) $L += 1 WEnd While (Call($sSortFunc, $avArray[$R], $vPivot) > 0) $R -= 1 WEnd ; Swap If $L <= $R Then $vTmp = $avArray[$L] $avArray[$L] = $avArray[$R] $avArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R __ArrayCustomQuickSort1D($avArray, $sSortFunc, $iStart, $R) __ArrayCustomQuickSort1D($avArray, $sSortFunc, $L, $iEnd) EndFunc ;==>__ArrayCustomQuickSort1D ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: __ArrayCustomQuickSort2D ; Description ...: Helper function for sorting 2D arrays ; Syntax.........: __ArrayCustomQuickSort2D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) ; Parameters ....: $avArray - Array to sort ; $iStep - Step size (should be 1 to sort ascending, -1 to sort descending!) ; $iStart - Index of array to start sorting at ; $iEnd - Index of array to stop sorting at ; $iSubItem - Sub-index to sort on in 2D arrays ; $iSubMax - Maximum sub-index that array has ; Return values .: None ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: Erik Pilsits - removed IsNumber testing ; Remarks .......: For Internal Use Only ; Related .......: ; Link ..........; ; Example .......; ; =============================================================================================================================== Func __ArrayCustomQuickSort2D(ByRef $avArray, ByRef $sSortFunc, ByRef $iStep, ByRef $iStart, ByRef $iEnd, ByRef $iSubItem, ByRef $iSubMax) If $iEnd <= $iStart Then Return ; QuickSort Local $i, $vTmp, $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)][$iSubItem] Do While ($iStep * Call($sSortFunc, $avArray[$L][$iSubItem], $vPivot) < 0) $L += 1 WEnd While ($iStep * Call($sSortFunc, $avArray[$R][$iSubItem], $vPivot) > 0) $R -= 1 WEnd ; Swap If $L <= $R Then For $i = 0 To $iSubMax $vTmp = $avArray[$L][$i] $avArray[$L][$i] = $avArray[$R][$i] $avArray[$R][$i] = $vTmp Next $L += 1 $R -= 1 EndIf Until $L > $R __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iStep, $iStart, $R, $iSubItem, $iSubMax) __ArrayCustomQuickSort2D($avArray, $sSortFunc, $iStep, $L, $iEnd, $iSubItem, $iSubMax) EndFunc ;==>__ArrayCustomQuickSort2D Example: #include "_ArrayNaturalSort.au3" Global $a[1], $array[10] = ["image1.jpg", "image2.jpg", "image3.jpg", "image10.jpg", "image11.jpg", _ "image12.jpg", "image20.jpg", "image21.jpg", "image22.jpg", "image23.jpg"] $a = $array _ArraySort($a) _ArrayDisplay($a, "_ArraySort") $a = $array _ArrayNaturalSort($a) _ArrayDisplay($a, "_ArrayNaturalSort")
    1 point
×
×
  • Create New...