Leaderboard
Popular Content
Showing content with the highest reputation on 12/28/2017 in all areas
-
Version 5.1
8,855 downloads
Features: Create modern looking borderless and resizable GUIs with control buttons (Close,Maximize/Restore,Minimize, Fullscreen, Menu) True borderless, resizeable GUI with full support for aerosnap etc. Many color schemes/themes included. See MetroThemes.au3 for more details. 2 type of Windows 8/10 style buttons. Modern checkboxes, radios, toggles and progressbar. All buttons, checkboxes etc. have hover effects! Windows 10 style modern MsgBox. Windows 10/Android style menu that slides in from left.1 point -
https://www.autoitscript.com/autoit3/docs/intro/windowsadvanced.htm1 point
-
How to select the drop down menu in existing application using autoit?
Earthshine reacted to JLogan3o13 for a topic
WPR has a very robust command-line structure, which is fully documented with examples on MSDN. Why would you bother with trying to manipulate the GUI instead of just doin it through the command line parameters?1 point -
How to select the drop down menu in existing application using autoit?
Earthshine reacted to Jos for a topic
Look in the Helpfile for "GUI Reference" which explains how to create your own GUI within an AutoIt3 script. I am not going to code it for you. Jos1 point -
Compare two windows 10 installation Help [SOLVED]
Earthshine reacted to rootx for a topic
THX JLogan3o13, I found a very simple method to compare two systems configurations, msinfo32.exe than I used winmerge to save a patch file and notepad++ to extract only the diff from the Right SO, in my case was one service and a realtek drivers version!!!1 point -
[SOLVED] to DLLopen or not ( as in "to be or not to be")
Danyfirex reacted to argumentum for a topic
From the manual: "DllOpen: Opens a DLL file for use in DllCall." But I see everywhere in the distribution UDFs, no use of it for DllCall(). In the manual, the example is: Local $hDLL = DllOpen("user32.dll") DllCall($hDLL, "int", "MessageBox", "hwnd", 0, "str", "Some text", "str", "Some title", "int", 0) DllClose($hDLL) but what I actually see is the UDFs, is more along the lines of: ; Calling the MessageBox API directly. DllCall("user32.dll", "int", "MessageBox", _ "hwnd", 0, _ ; Handle to the parent window "str", "Some text", _ ; The text of the message box "str", "Some title", _ ; The title of the message box "int", 0) ; Flags for the message box. So, "to DllOpen or not to DllOpen, that is the question."1 point -
[SOLVED] to DLLopen or not ( as in "to be or not to be")
argumentum reacted to RTFC for a topic
I never had you pegged as a beginner, argumentum, and I reckon you posed an interesting, valid question (definitely not mere chat). Investigating and questioning(!) the source code is a good way of gaining a deeper understanding; I try to get a peek under the hood myself when I get the chance. So don't put yourself down, okay?1 point -
1 point
-
[SOLVED] to DLLopen or not ( as in "to be or not to be")
Danyfirex reacted to Earthshine for a topic
you missed the more important #2. He suggests closing handles you open. This is the best practice, now and forever, you can sing that like at church..... in unmanaged code, you had darned well better clean up after yourself. With .NET managed stuff, it does the garbage cleanup for you, but if you are allocating memory and resources, you should free it when you exit or don't need it anymore https://www.autoitscript.com/autoit3/docs/functions/DllClose.htm1 point -
3D Sinus Wave (GDI / GDI+)
jaberwacky reacted to UEZ for a topic
As requested by @Lakes here: GDI and GDI+ versions of 3D Sinus Wave. GDI ≠GDI+! GDI: ;coded by UEZ build 2017-01-18 #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 <GuiConstantsEx.au3> #include <WinAPIGdi.au3> #include <WindowsConstants.au3> Global $__f1, $__f2, $__f3, $__fY0, $__fZ0, $__fX1, $__fY1 Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit, $fZoom = 5.0 Global Const $iW = @DesktopWidth * 0.75, $iH = @DesktopHeight * 0.75, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ 3D Sinus Wave v1.1 coded by UEZ / FPS: " Global Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi, $fPi2 = ACos(-1) * 2 AutoItSetOption("GUIOnEventMode", 1) GDIPlus_3DSinusWave() AutoItSetOption("GUIOnEventMode", 0) Func GDIPlus_3DSinusWave() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH) ;, 0, 0, $WS_POPUP) GUISetState(@SW_SHOW, $hGUI) ;~ GUISetCursor(16, 1) ;create canvas elements Local Const $hDC = _WinAPI_GetDC($hGUI) Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC) Local Const $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI) Local Const $hPen = _WinAPI_GetStockObject($DC_PEN) Local Const $hPen_Old = _WinAPI_SelectObject($hGfxDC, $hPen) _WinAPI_SetStretchBltMode($hDC, $HALFTONE) $iFPS = 0 Local Const $fEuler = 2.7182818284 Local $fSpace = 6, $iPoints = 16, $fSpace2 = $fSpace / 2, $iPoints2 = $iPoints / 2 Local $fRotX = Random(-360, 360), $fRotY = Random(-360, 360), $fRotZ = Random(-360, 360), $fPower = 20.0 Local $fRx = Random(-1.5, 1,5), $fRy = Random(-1.5, 1,5), $fRz = Random(-1.5, 1,5) Local $c = 0, $t = 0, $aCoords[$iPoints ^ 2][3] Local $i, $j, $x, $y, $z, $x1, $y1, $z1, $x2, $y2, $z2, $x3, $y3, $z3, $fDistance, $r, $g, $b Local $hDLL_gdi32 = DllOpen("gdi32.dll") Local $tLOGBRUSH = DllStructCreate($tagLOGBRUSH) GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") AdlibRegister("CalcFPS", 1000) Do _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $WHITENESS) ;erase canvas background $c = 0 For $i = 0 To $iPoints - 1 For $j = 0 To $iPoints - 1 $aCoords[$c][0] = $fSpace * $i + $fSpace2 - $fSpace * $iPoints2 $aCoords[$c][1] = $fSpace * $j + $fSpace2 - $fSpace * $iPoints2 $fDistance = Dist(0, 0, $aCoords[$c][0], $aCoords[$c][1]) $aCoords[$c][2] = $fEuler ^ (-$fDistance / 50) * Sin(($fDistance / 10) - $t) * $fPower $c += 1 $t += 0.00075 Next Next For $i = 0 To $iPoints - 2 For $j = 0 To $iPoints - 2 $r = Int(0x80 + $aCoords[$j + $iPoints * $i][0] * 2) $g = Int(0x80 + $aCoords[$j + $iPoints * $i][1] * 2) $b = Int(0x80 + $aCoords[$j + $iPoints * $i][2] * 2) DllCall($hDLL_gdi32, "dword", "SetDCPenColor", "handle", $hGfxDC, "dword", BitShift($b, -16) + BitShift($g, -8) + $r) _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[$j + $iPoints * ($i + 1)][0], $aCoords[$j + $iPoints * ($i + 1)][1], $aCoords[$j + $iPoints * ($i + 1)][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($hDLL_gdi32, "bool", "MoveToEx", "handle", $hGfxDC, "int", $iWh + $x1 * $fZoom, "int", $iHh + $y1 * $fZoom, "ptr", 0) DllCall($hDLL_gdi32, "bool", "LineTo", "handle", $hGfxDC, "int", $iWh + $x2 * $fZoom, "int", $iHh + $y2 * $fZoom) _3Dto2D($aCoords[($j + 1) + $iPoints * $i][0], $aCoords[($j + 1) + $iPoints * $i][1], $aCoords[($j + 1) + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($hDLL_gdi32, "bool", "MoveToEx", "handle", $hGfxDC, "int", $iWh + $x1 * $fZoom, "int", $iHh + $y1 * $fZoom, "ptr", 0) DllCall($hDLL_gdi32, "bool", "LineTo", "handle", $hGfxDC, "int", $iWh + $x2 * $fZoom, "int", $iHh + $y2 * $fZoom) Next Next For $i = 0 To $iPoints - 2 $r = Int(0x80 + $aCoords[$j + $iPoints * $i][0] * 2) $g = Int(0x80 + $aCoords[$j + $iPoints * $i][1] * 2) $b = Int(0x80 + $aCoords[$j + $iPoints * $i][2] * 2) DllCall($hDLL_gdi32, "dword", "SetDCPenColor", "handle", $hGfxDC, "dword", BitShift($b, -16) + BitShift($g, -8) + $r) _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[$j + $iPoints * ($i + 1)][0], $aCoords[$j + $iPoints * ($i + 1)][1], $aCoords[$j + $iPoints * ($i + 1)][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($hDLL_gdi32, "bool", "MoveToEx", "handle", $hGfxDC, "int", $iWh + $x1 * $fZoom, "int", $iHh + $y1 * $fZoom, "ptr", 0) DllCall($hDLL_gdi32, "bool", "LineTo", "handle", $hGfxDC, "int", $iWh + $x2 * $fZoom, "int", $iHh + $y2 * $fZoom) Next For $j = 0 To $iPoints - 2 $r = Int(0x80 + $aCoords[$j + $iPoints * $i][0] * 2) $g = Int(0x80 + $aCoords[$j + $iPoints * $i][1] * 2) $b = Int(0x80 + $aCoords[$j + $iPoints * $i][2] * 2) DllCall($hDLL_gdi32, "dword", "SetDCPenColor", "handle", $hGfxDC, "dword", BitShift($b, -16) + BitShift($g, -8) + $r) _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[($j + 1) + $iPoints * $i][0], $aCoords[($j + 1) + $iPoints * $i][1], $aCoords[($j + 1) + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($hDLL_gdi32, "bool", "MoveToEx", "handle", $hGfxDC, "int", $iWh + $x1 * $fZoom, "int", $iHh + $y1 * $fZoom, "ptr", 0) DllCall($hDLL_gdi32, "bool", "LineTo", "handle", $hGfxDC, "int", $iWh + $x2 * $fZoom, "int", $iHh + $y2 * $fZoom) Next $fRotX += $fRx $fRotY += $fRy $fRotZ += $fRz _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $SRCCOPY) ;blit drawn bitmap to GUI $iFPS += 1 If $bExit Then ExitLoop Until Not Sleep(10) GUIRegisterMsg($WM_MOUSEWHEEL, "") AdlibUnRegister("CalcFPS") ;release resources _WinAPI_SelectObject($hGfxDC, $hPen_Old) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) GUIDelete($hGUI) DllClose($hDLL_gdi32) EndFunc ;==>GDIPlus_3DSinusWave Func WM_MOUSEWHEEL($hGUI, $iMsg, $wParam, $lParam) Local $wheel_Dir = _WinAPI_HiWord($wParam) If $wheel_Dir > 0 Then $fZoom += 0.25 $fZoom = $fZoom > 20 ? 20 : $fZoom Else $fZoom -= 0.25 $fZoom = $fZoom < 0.25 ? 0.25 : $fZoom EndIf Return "GUI_RUNDEFMSG" EndFunc ;==>WM_MOUSEWHEEL Func Dist($x1, $y1, $x2, $y2) Return Sqrt(($x1 - $x2) * ($x1 - $x2) + ($y1 - $y2) * ($y1 - $y2)) EndFunc ;==>Dist Func _3Dto2D($fX, $fY, $fZ, $fRotX, $fRotY, $fRotZ, ByRef $__fXPos, ByRef $__fYPos, ByRef $__fZPos) ;apply the x-axis rotation to transform coordinates ($fX, $fY, $fZ) into coordinates ($fX0, $fY0, $fZ0) $__f1 = $fRotX * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fY0 = $fY * $__f2 + $fZ * $__f3 $__fZ0 = $fZ * $__f2 - $fY * $__f3 ;apply the y-axis rotation to ($fX0, $__fY0, $fZ0) to obtain ($__fX1, $__fY1, $fZ1) $__f1 = $fRotY * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fX1 = $fX * $__f2 - $__fZ0 * $__f3 $__fY1 = $__fY0 ;~ $__fZ1 = $__fZ0 * $__f2 + $fX * $__f2 ;finally, apply the z-axis rotation to obtain the point ($fXPos, $fYPos) $__f1 = $fRotZ * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fXPos = $__fX1 * $__f2 + $__fY1 * $__f3 $__fYPos = $__fY1 * $__f2 - $__fX1 * $__f3 $__fZPos = $__fZ0 EndFunc ;==>_3Dto2D Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func CalcFPS() ;display FPS $iShowFPS = $iFPS $iFPS = 0 WinSetTitle($hGUI, "", $sTitle & $iShowFPS) EndFunc ;==>CalcFPS GDI+ ;coded by UEZ build 2017-01-17 #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 $__f1, $__f2, $__f3, $__fY0, $__fZ0, $__fX1, $__fY1 Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit Global Const $iW = @DesktopWidth * 0.75, $iH = @DesktopHeight * 0.75, $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ 3D Sinus Wave v1.0 coded by UEZ" Global Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi, $fPi2 = ACos(-1) * 2 AutoItSetOption("GUIOnEventMode", 1) GDIPlus_3DSinusWave() AutoItSetOption("GUIOnEventMode", 0) _GDIPlus_Shutdown() Func GDIPlus_3DSinusWave() $bExit = False $hGUI = GUICreate($sTitle, $iW, $iH) ;, 0, 0, $WS_POPUP) GUISetState(@SW_SHOW, $hGUI) ;~ GUISetCursor(16, 1) ;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_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) Local Const $hBrush_Clr = _GDIPlus_BrushCreateSolid(0xFFFFFFFF), _ $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xF0808080), _ $hFormat_FPS = _GDIPlus_StringFormatCreate(), _ $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _ $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _ $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 60, 16), _ $hPath = _GDIPlus_PathCreate(), _ $hPen = _GDIPlus_PenCreate(0xCF101010, 1.25) _GDIPlus_PenSetLineJoin($hPen, 2) ;~ _GDIPlus_PenSetDashCap($hPen, $GDIP_DASHCAPROUND) ;~ _GDIPlus_PenSetLineCap($hPen, 0x12, 0x12, 2) $iFPS = 0 Local $fEuler = 2.7182818284 Local $fSpace = 6, $iPoints = 16, $fSpace2 = $fSpace / 2, $iPoints2 = $iPoints / 2 Local $fRotX = Random(-360, 360), $fRotY = Random(-360, 360), $fRotZ = Random(-360, 360), $fZoom = 5.0, $fPower = 20.0 Local $fRx = Random(-1.5, 1,5), $fRy = Random(-1.5, 1,5), $fRz = Random(-1.5, 1,5) Local $c = 0, $t = 0, $aCoords[$iPoints ^ 2][3] Local $i, $j, $x, $y, $z, $x1, $y1, $z1, $x2, $y2, $z2, $x3, $y3, $z3, $fDistance, $r, $g, $b GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") AdlibRegister("CalcFPS", 1000) Do ;~ DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, _ ;~ "float", $iW, "float", $iH) ;erase canvas background _WinAPI_BitBlt($hDC_backbuffer, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $WHITENESS) $c = 0 For $i = 0 To $iPoints - 1 For $j = 0 To $iPoints - 1 $aCoords[$c][0] = ($fSpace * $i + $fSpace2 - $fSpace * $iPoints2) $aCoords[$c][1] = ($fSpace * $j + $fSpace2 - $fSpace * $iPoints2) $fDistance = Dist(0, 0, $aCoords[$c][0], $aCoords[$c][1]) $aCoords[$c][2] = $fEuler ^ (-$fDistance / 50) * Sin(($fDistance / 10) - $t) * $fPower $c += 1 $t += 0.00075 Next Next For $i = 0 To $iPoints - 2 For $j = 0 To $iPoints - 2 _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[$j + $iPoints * ($i + 1)][0], $aCoords[$j + $iPoints * ($i + 1)][1], $aCoords[$j + $iPoints * ($i + 1)][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hCanvas, "handle", $hPen, _ "float", $iWh + $x1 * $fZoom, "float", $iHh + $y1 * $fZoom, "float", $iWh + $x2 * $fZoom, "float", $iHh + $y2 * $fZoom) _3Dto2D($aCoords[($j + 1) + $iPoints * $i][0], $aCoords[($j + 1) + $iPoints * $i][1], $aCoords[($j + 1) + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hCanvas, "handle", $hPen, _ "float", $iWh + $x1 * $fZoom, "float", $iHh + $y1 * $fZoom, "float", $iWh + $x2 * $fZoom, "float", $iHh + $y2 * $fZoom) Next Next For $i = 0 To $iPoints - 2 _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[$j + $iPoints * ($i + 1)][0], $aCoords[$j + $iPoints * ($i + 1)][1], $aCoords[$j + $iPoints * ($i + 1)][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hCanvas, "handle", $hPen, _ "float", $iWh + $x1 * $fZoom, "float", $iHh + $y1 * $fZoom, "float", $iWh + $x2 * $fZoom, "float", $iHh + $y2 * $fZoom) Next For $j = 0 To $iPoints - 2 _3Dto2D($aCoords[$j + $iPoints * $i][0], $aCoords[$j + $iPoints * $i][1], $aCoords[$j + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x1, $y1, $z1) _3Dto2D($aCoords[($j + 1) + $iPoints * $i][0], $aCoords[($j + 1) + $iPoints * $i][1], $aCoords[($j + 1) + $iPoints * $i][2], $fRotX, $fRotY, $fRotZ, $x2, $y2, $z2) DllCall($__g_hGDIPDll, "int", "GdipDrawLine", "handle", $hCanvas, "handle", $hPen, _ "float", $iWh + $x1 * $fZoom, "float", $iHh + $y1 * $fZoom, "float", $iWh + $x2 * $fZoom, "float", $iHh + $y2 * $fZoom) Next $fRotX += $fRx $fRotY += $fRy $fRotZ += $fRz _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 Not Sleep(10) AdlibUnRegister("CalcFPS") ;release resources _GDIPlus_PenDispose($hPen) _GDIPlus_PathDispose($hPath) _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_3DSinusWave Func Dist($x1, $y1, $x2, $y2) Return Sqrt(($x1 - $x2) * ($x1 - $x2) + ($y1 - $y2) * ($y1 - $y2)) EndFunc ;==>Dist Func _3Dto2D($fX, $fY, $fZ, $fRotX, $fRotY, $fRotZ, ByRef $__fXPos, ByRef $__fYPos, ByRef $__fZPos) ;apply the x-axis rotation to transform coordinates ($fX, $fY, $fZ) into coordinates ($fX0, $fY0, $fZ0) $__f1 = $fRotX * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fY0 = $fY * $__f2 + $fZ * $__f3 $__fZ0 = $fZ * $__f2 - $fY * $__f3 ;apply the y-axis rotation to ($fX0, $__fY0, $fZ0) to obtain ($__fX1, $__fY1, $fZ1) $__f1 = $fRotY * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fX1 = $fX * $__f2 - $__fZ0 * $__f3 $__fY1 = $__fY0 ;~ $__fZ1 = $__fZ0 * $__f2 + $fX * $__f2 ;finally, apply the z-axis rotation to obtain the point ($fXPos, $fYPos) $__f1 = $fRotZ * $fRad $__f2 = Cos($__f1) $__f3 = Sin($__f1) $__fXPos = $__fX1 * $__f2 + $__fY1 * $__f3 $__fYPos = $__fY1 * $__f2 - $__fX1 * $__f3 $__fZPos = $__fZ0 EndFunc ;==>_3Dto2D Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func CalcFPS() ;display FPS $iShowFPS = $iFPS $iFPS = 0 EndFunc ;==>CalcFPS In the attached 7-Zip file you can find the compiled and also a FreeBasic version. -> DL: 3D Sinus Wave.7z Have fun.1 point -
It's a bit like FileWrite, where you can use the filename or a handle you open with FileOpen beforehand. If your call is a one-off then it's overkill to get a handle for it, call it, then close it again. But if you're going to be accessing the dll dozens or hundreds (millions?) of times in your code, it's faster to get a handle once and use that while you need the dll, then close it once. And of course, the UDFs are mostly single call affairs (GDI+ is an exception), so the only way to ensure the handle gets closed (no memory leak) is to open and close it directly per UDF call.1 point
-
Could everybody please do me a favor and stop posting till the OP is back and replies as we have now 19 reply posts! Jos1 point
-
I found an interesting RC4 implementation on Github that was available in PHP and Javascript in a compatible way. So I ported it to AutoIt keeping it compatible with the PHP/Javascript versions. The problem with RC4 is that most of the implementations are only based on the original spec, and not compatible to it. Therefore if you are developing something that must communicate between different platforms (for example, encrypt at the AutoIt side and decrypt at the PHP side), you're usually out of luck. But what about Crypt.au3? It uses Windows implementation, which is also not standard and therefore isn't compatible with the PHP/JS versions as well (with "compatible" I mean: "giving the same string and encryption key, you'll get the same output"). What about huge data/files? I'd suggest not to use this version for huge amounts of data since it's entirely AU3 based and may be slow for that. So why would I use this version? Because you are developing something that uses PHP, Javascript and/or AutoIt and they must speak the same language (I mean: they must produce the same outputs and be able to decrypt strings encrypted on a different programming language). But it's giving me unreadable outputs. Yeah RC4 does it. It's up to you to use Base64 or hex encoding if you really need it. Then why don't I use base64 directly? Base64 isn't meant to protect data. It's meant to make binary data easy and safe to store by converting it to readable characters. That's why it doesn't include password protection. Here's the code: Func rc4($sKey, $sStr) Local $s[256], $j = 0, $x, $res, $y, $i Local $uBound For $i = 0 To 255 $s[$i] = $i Next For $i = 0 To 255 $j = Mod(($j + $s[$i] + Asc(StringMid($sKey, Mod($i, StringLen($sKey))+1, 1))), 256) $x = $s[$i] $s[$i] = $s[$j] $s[$j] = $x Next $i = 0 $j = 0 For $y = 0 To StringLen($sStr)-1 $i = Mod(($i + 1), 256) $j = Mod(($j + $s[$i]), 256) $x = $s[$i] $s[$i] = $s[$j] $s[$j] = $x $res &= Chr(BitXOR(Asc(StringMid($sStr, $y+1, 1)), ($s[Mod(($s[$i] + $s[$j]), 256)]))) Next Return $res EndFunc Note that since rc4 is dual-way, doing rc4("same key here", "encrypted string") will get back your decrypted string (there's no need to a separated decrypt function).1 point
-
CompileIt - an experimental AutoIt-to-machine code compiler
shuaua reacted to scintilla4evr for a file
1 point -
Optimizing C# and VB code Index based sorting The examples in post 4 is an introduction to threading. The examples here shows how VB code can be optimized using multithreading. The examples are a continuation of the code in post 2 regarding index based sorting. Multithreaded sorting The idea is that if 4 threads are used to sort 100,000 rows, the first thread can sort the first 25,000 rows, the next thread can sort the next 25,000 rows, etc. It results in 4 indexes that finally can be combined into one big index. This is the code in Sort2DArrayOptEx.vb: Imports System Imports System.Threading Imports System.Collections Class SortArrayClass Dim aObjects, aCompare As Object(,) Dim iPartRows, iRestRows, iCmps As Integer Dim iThreads = 4, aIndex(iThreads)(), aRows(iThreads) As Integer Public Function Sort2DArray( aObjPar As Object(,), aCompPar As Object(,) ) As Integer() aObjects = aObjPar : aCompare = aCompPar Dim iRows As Integer = aObjects.GetUpperBound(1) + 1 iRestRows = iRows Mod iThreads : iPartRows = ( iRows - iRestRows ) / iThreads iCmps = aCompare.GetUpperBound(1) + 1 'Multithreaded index based sorting Dim th0 As New Thread( AddressOf Sort2DArraySub ) : th0.Start(0) Dim th1 As New Thread( AddressOf Sort2DArraySub ) : th1.Start(1) Dim th2 As New Thread( AddressOf Sort2DArraySub ) : th2.Start(2) Dim th3 As New Thread( AddressOf Sort2DArraySub ) : th3.Start(3) 'Main thread sleeps until sorting is done While aRows(0) = 0 Or aRows(1) = 0 Or aRows(2) = 0 Or aRows(3) = 0 Thread.Sleep(20) End While 'Combine four indexes into one Dim aIndexAll(iRows-1) As Integer Dim aIndexIdx(iThreads), iLeft, iRight, r, j As Integer For i As Integer = 0 To iRows - 1 iLeft = If( aIndexIdx(0) < aRows(0), 0, If( aIndexIdx(1) < aRows(1), 1, If( aIndexIdx(2) < aRows(2), 2, 3 ) ) ) iRight = iLeft While iRight < iThreads iRight += 1 Select iRight Case 1 iRight = If( aIndexIdx(1) < aRows(1), 1, If( aIndexIdx(2) < aRows(2), 2, If( aIndexIdx(3) < aRows(3), 3, iThreads ) ) ) Case 2 iRight = If( aIndexIdx(2) < aRows(2), 2, If( aIndexIdx(3) < aRows(3), 3, iThreads ) ) Case 3 iRight = If( aIndexIdx(3) < aRows(3), 3, iThreads ) End Select If iRight = iThreads Then Exit While r = 0 'Compare result (-1,0,1) j = 0 'Index in $aCompare array While r = 0 And j < iCmps r = If( aCompare(1,j), String.Compare( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))), aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))) ), If( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))) < aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))), -1, If( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))) > aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))), 1, 0 ) ) ) * aCompare(2,j) j += 1 End While Select r Case 1 iLeft = iRight Case 0 If aIndex(iLeft)(aIndexIdx(iLeft)) > aIndex(iRight)(aIndexIdx(iRight)) Then iLeft = iRight End Select End While aIndexAll(i) = aIndex(iLeft)(aIndexIdx(iLeft)) aIndexIdx(iLeft) += 1 Next Return aIndexAll End Function 'Multithreaded index based sorting Private Sub Sort2DArraySub( oThread As Object ) Dim iThread As Integer = CInt( oThread ) Dim iFirstRow As Integer = If( iThread < iRestRows, iPartRows * iThread + iThread, iPartRows * iThread + iRestRows ) Dim iLastRow As Integer = iFirstRow + If( iThread < iRestRows, iPartRows, iPartRows - 1 ) Dim iRows As Integer = iLastRow - iFirstRow + 1 Dim MyList As New Generic.List( Of Integer ) MyList.Capacity = iRows MyList.Add(iFirstRow) 'Sorting by multiple columns Dim lo, hi, mi, r, j As Integer For i As Integer = iFirstRow + 1 To iLastRow lo = iFirstRow hi = i - 1 Do r = 0 'Compare result (-1,0,1) j = 0 'Index in $aCompare array mi = ( lo + hi ) / 2 While r = 0 And j < iCmps r = If( aCompare(1,j), String.Compare( aObjects(aCompare(0,j),i), aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)) ), If( aObjects(aCompare(0,j),i) < aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)), -1, If( aObjects(aCompare(0,j),i) > aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)), 1, 0 ) ) ) * aCompare(2,j) j += 1 End While Select r Case -1 hi = mi - 1 Case 1 lo = mi + 1 Case 0 Exit Do End Select Loop Until lo > hi MyList.Insert( If(lo=mi+1,mi+1,mi)-iFirstRow, i ) Next aIndex(iThread) = MyList.ToArray() aRows(iThread) = iRows End Sub End Class In Runtimes.au3 the execution times for sorting arrays with different number of rows are measuered for pure AutoIt code, for optimized VB code and for multithreaded VB code. This is the results on my PC: Code executed as 32 bit code Code executed as 64 bit code ============================ ============================ $iRows = 100, 6 columns $iRows = 100, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 4.3340 Pure AutoIt code: 3.7655 Optimized VB code: 1.2553 Optimized VB code: 1.4281 Multithreaded VB code: 19.0067 Multithreaded VB code: 33.5323 $iRows = 500, 6 columns $iRows = 500, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 27.5916 Pure AutoIt code: 25.5753 Optimized VB code: 2.6330 Optimized VB code: 2.8050 Multithreaded VB code: 31.2496 Multithreaded VB code: 36.4108 $iRows = 1000, 6 columns $iRows = 1000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 106.4464 Pure AutoIt code: 90.3135 Optimized VB code: 35.7356 Optimized VB code: 27.4234 Multithreaded VB code: 64.3406 Multithreaded VB code: 57.4474 $iRows = 2000, 6 columns $iRows = 2000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 142.1940 Pure AutoIt code: 134.2208 Optimized VB code: 11.6813 Optimized VB code: 10.9643 Multithreaded VB code: 30.2622 Multithreaded VB code: 33.4628 $iRows = 5000, 6 columns $iRows = 5000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 401.1128 Pure AutoIt code: 365.6661 Optimized VB code: 38.3885 Optimized VB code: 31.2551 Multithreaded VB code: 79.6997 Multithreaded VB code: 89.7060 $iRows = 10000, 6 columns $iRows = 10000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 826.2889 Pure AutoIt code: 691.7514 Optimized VB code: 70.5041 Optimized VB code: 65.1964 Multithreaded VB code: 89.2076 Multithreaded VB code: 60.4300 $iRows = 20000, 6 columns $iRows = 20000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 1816.3940 Pure AutoIt code: 1517.2513 Optimized VB code: 183.4977 Optimized VB code: 151.7480 Multithreaded VB code: 150.1049 Multithreaded VB code: 135.3445 $iRows = 50000, 6 columns $iRows = 50000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 5386.5884 Pure AutoIt code: 4239.2327 Optimized VB code: 602.9203 Optimized VB code: 471.3676 Multithreaded VB code: 373.1342 Multithreaded VB code: 371.5393 $iRows = 100000, 6 columns $iRows = 100000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 12798.0606 Pure AutoIt code: 9489.1929 Optimized VB code: 1590.7280 Optimized VB code: 1273.4829 Multithreaded VB code: 800.1118 Multithreaded VB code: 684.8815 $iRows = 250000, 6 columns $iRows = 250000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 44781.3723 Pure AutoIt code: 27407.9705 Optimized VB code: 7217.6899 Optimized VB code: 5222.3106 Multithreaded VB code: 2330.1729 Multithreaded VB code: 1914.2506 $iRows = 500000, 6 columns $iRows = 500000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 128479.2462 Pure AutoIt code: 69438.5295 Optimized VB code: 25016.8543 Optimized VB code: 16692.2426 Multithreaded VB code: 5949.0161 Multithreaded VB code: 4565.7862 $iRows = 750000, 6 columns $iRows = 750000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 250176.5552 Pure AutoIt code: 107785.2414 Optimized VB code: 54193.4737 Optimized VB code: 35217.0613 Multithreaded VB code: 10827.3308 Multithreaded VB code: 8186.0242 $iRows = 1000000, 6 columns $iRows = 1000000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 408457.7649 Pure AutoIt code: 162282.8254 Optimized VB code: 96291.4960 Optimized VB code: 62412.9602 Multithreaded VB code: 17399.9110 Multithreaded VB code: 12690.8546 $iRows = 2000000, 6 columns $iRows = 2000000, 6 columns Sort array by columns 0, 1, 2 Sort array by columns 0, 1, 2 ----------------------------------- ----------------------------------- Pure AutoIt code: 1445235.5246 Pure AutoIt code: 498648.9821 Optimized VB code: 409872.8400 Optimized VB code: 282116.6518 Multithreaded VB code: 63527.4207 Multithreaded VB code: 51087.1290 Code is added to "Examples\5) Optimizing C# and VB code\1) Index based sorting\" in zip-file in bottom of first post. Implementing a progress bar Another advantage of performing the sorting in 4 worker threads is that the main thread can be released by the VB code and thereby making the AutoIt code responsive while the sorting is going on. This makes it possible to implement a progress bar in the AutoIt code. The code in Sort2DArrayOptEx2.vb is changed a little bit: Imports System Imports System.Threading Imports System.Collections Class SortArrayClass Dim aObjects, aCompare As Object(,) Dim iRows, iPartRows, iRestRows, iCmps As Integer Dim iThreads = 4, aIndex(iThreads)(), aRows(iThreads) As Integer Public Sub Sort2DArray( aObjPar As Object(,), aCompPar As Object(,) ) aObjects = aObjPar : aCompare = aCompPar : iRows = aObjects.GetUpperBound(1) + 1 iRestRows = iRows Mod iThreads : iPartRows = ( iRows - iRestRows ) / iThreads iCmps = aCompare.GetUpperBound(1) + 1 'Multithreaded index based sorting Dim th0 As New Thread( AddressOf Sort2DArraySub ) : th0.Start(0) Dim th1 As New Thread( AddressOf Sort2DArraySub ) : th1.Start(1) Dim th2 As New Thread( AddressOf Sort2DArraySub ) : th2.Start(2) Dim th3 As New Thread( AddressOf Sort2DArraySub ) : th3.Start(3) End Sub 'Multithreaded index based sorting Private Sub Sort2DArraySub( oThread As Object ) Dim iThread As Integer = CInt( oThread ) Dim iFirstRow As Integer = If( iThread < iRestRows, iPartRows * iThread + iThread, iPartRows * iThread + iRestRows ) Dim iLastRow As Integer = iFirstRow + If( iThread < iRestRows, iPartRows, iPartRows - 1 ) Dim iSubRows As Integer = iLastRow - iFirstRow + 1 Dim MyList As New Generic.List( Of Integer ) MyList.Capacity = iSubRows MyList.Add(iFirstRow) 'Sorting by multiple columns Dim lo, hi, mi, r, j As Integer For i As Integer = iFirstRow + 1 To iLastRow lo = iFirstRow hi = i - 1 Do r = 0 'Compare result (-1,0,1) j = 0 'Index in $aCompare array mi = ( lo + hi ) / 2 While r = 0 And j < iCmps r = If( aCompare(1,j), String.Compare( aObjects(aCompare(0,j),i), aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)) ), If( aObjects(aCompare(0,j),i) < aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)), -1, If( aObjects(aCompare(0,j),i) > aObjects(aCompare(0,j),MyList.Item(mi-iFirstRow)), 1, 0 ) ) ) * aCompare(2,j) j += 1 End While Select r Case -1 hi = mi - 1 Case 1 lo = mi + 1 Case 0 Exit Do End Select Loop Until lo > hi MyList.Insert( If(lo=mi+1,mi+1,mi)-iFirstRow, i ) If ( i - iFirstRow ) Mod 1000 = 0 Then aRows(iThread) = i - iFirstRow Next aIndex(iThread) = MyList.ToArray() aRows(iThread) = iSubRows End Sub Public Function Sort2DArrayGetCount() As Integer Return aRows(0) + aRows(1) + aRows(2) + aRows(3) End Function Public Function Sort2DArrayGetIndex() As Integer() 'Combine four indexes into one Dim aIndexAll(iRows-1) As Integer Dim aIndexIdx(iThreads), iLeft, iRight, r, j As Integer For i As Integer = 0 To iRows - 1 iLeft = If( aIndexIdx(0) < aRows(0), 0, If( aIndexIdx(1) < aRows(1), 1, If( aIndexIdx(2) < aRows(2), 2, 3 ) ) ) iRight = iLeft While iRight < iThreads iRight += 1 Select iRight Case 1 iRight = If( aIndexIdx(1) < aRows(1), 1, If( aIndexIdx(2) < aRows(2), 2, If( aIndexIdx(3) < aRows(3), 3, iThreads ) ) ) Case 2 iRight = If( aIndexIdx(2) < aRows(2), 2, If( aIndexIdx(3) < aRows(3), 3, iThreads ) ) Case 3 iRight = If( aIndexIdx(3) < aRows(3), 3, iThreads ) End Select If iRight = iThreads Then Exit While r = 0 'Compare result (-1,0,1) j = 0 'Index in $aCompare array While r = 0 And j < iCmps r = If( aCompare(1,j), String.Compare( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))), aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))) ), If( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))) < aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))), -1, If( aObjects(aCompare(0,j),aIndex(iLeft)(aIndexIdx(iLeft))) > aObjects(aCompare(0,j),aIndex(iRight)(aIndexIdx(iRight))), 1, 0 ) ) ) * aCompare(2,j) j += 1 End While Select r Case 1 iLeft = iRight Case 0 If aIndex(iLeft)(aIndexIdx(iLeft)) > aIndex(iRight)(aIndexIdx(iRight)) Then iLeft = iRight End Select End While aIndexAll(i) = aIndex(iLeft)(aIndexIdx(iLeft)) aIndexIdx(iLeft) += 1 Next Return aIndexAll End Function End Class In Progressbar.au3 the execution times are measuered for the new code. This is the results on my PC when the code is run as 64 bit code: 250,000 rows Generate array Array generated 782.829209100278 Start sorting ... Sorting started 1052.33601879453 Sorting finished 3112.24138122098 Get index ... Index received 628.809605602899 500,000 rows Generate array Array generated 1692.53510123118 Start sorting ... Sorting started 1736.08362238057 Sorting finished 5300.57901794125 Get index ... Index received 987.373807333858 750,000 rows Generate array Array generated 2701.3300790124 Start sorting ... Sorting started 2846.97747093829 Sorting finished 8147.51853411496 Get index ... Index received 1427.32770753222 1,000,000 rows Generate array Array generated 3671.26491871585 Start sorting ... Sorting started 3360.98083976994 Sorting finished 11515.8238123206 Get index ... Index received 1913.89753875819 2,000,000 rows Generate array Array generated 7789.33304890347 Start sorting ... Sorting started 6773.98630303971 Sorting finished 48250.9211649065 Get index ... Index received 3852.50335220913 Note the lines titled "Sorting started". These are the lines that measure the time it takes to execute this code: Public Sub Sort2DArray( aObjPar As Object(,), aCompPar As Object(,) ) aObjects = aObjPar : aCompare = aCompPar : iRows = aObjects.GetUpperBound(1) + 1 iRestRows = iRows Mod iThreads : iPartRows = ( iRows - iRestRows ) / iThreads iCmps = aCompare.GetUpperBound(1) + 1 'Multithreaded index based sorting Dim th0 As New Thread( AddressOf Sort2DArraySub ) : th0.Start(0) Dim th1 As New Thread( AddressOf Sort2DArraySub ) : th1.Start(1) Dim th2 As New Thread( AddressOf Sort2DArraySub ) : th2.Start(2) Dim th3 As New Thread( AddressOf Sort2DArraySub ) : th3.Start(3) End Sub Most of the time is spent by passing the array ($aArray) as a parameter from the AutoIt code to the VB method (in aObjPar). Code is added to "Examples\5) Optimizing C# and VB code\1) Index based sorting\" in zip-file in bottom of first post. Global array variable Post 2 is a UDF version of four examples about generating a 2D array of random data, sorting the array by one or more columns through an index, converting the 2D array to a 1D array in CSV format, and finally saving the 1D array as a CSV file. The code is stored in "Examples\3) UDF version of examples\" in zip-file in bottom of first post. I've added a new example, ExampleOpt2.au3, to the Examples folder, where the execution times and the total execution time for these 4 procedures are measured for an array with 250,000 rows. This is the results: Code executed as 32 bit code Code executed as 64 bit code ============================ ============================ 250000 rows 250000 rows Generate array: 995.724559926393 Generate array: 797.652719123923 Sort array: 7236.27375117504 Sort array: 5291.30258795446 Convert array: 1426.65439887983 Convert array: 1224.09933028633 Save array: 450.983570086659 Save array: 383.220670832949 Total time: 10109.6362800679 Total time: 7696.27530819767 At the bottom of the example above we saw that quite a lot of time is being used to transfer arrays between the AutoIt code and the VB code. One way to avoid the time used to transfer arrays between AutoIt code and VB code is to store the array ($aArray/aObjects) as a global variable in the VB code. This is implemented in "Examples\5) Optimizing C# and VB code\2) Global array variable\Includes\ArrayFuncsOpt.vb". There is also used a multithreaded version of the sorting code. And the two procedures to convert and save the array as a CSV file is combined into one procedure to avoid transfering the array of strings back and forth. This is the time measurement for the new code: Code executed as 32 bit code Code executed as 64 bit code ============================ ============================ 250000 rows 250000 rows Generate array: 696.800872597593 Generate array: 516.643380589801 Sort array: 1542.99252546023 Sort array: 1465.04082474547 Save array: 446.520844017085 Save array: 418.329314718878 Total time: 2686.31424207491 Total time: 2400.01352005415 Code in "Examples\5) Optimizing C# and VB code\2) Global array variable\" in zip-file in bottom of first post. Delete global variables To delete global variables used in the VB code simply delete the object. The objects are solely handled in Includes\ArrayFuncsOpt.au3 UDF (there are no objects directly in the user code). The $oArrayClass object which is an instance of the ArrayClass in the VB code is created in ArrayFuncsOptInit() in this way: Func ArrayFuncsOptInit( $bDelObj = False ) Static $oNetCode = 0, $oArrayClass = 0 If $bDelObj Then $oArrayClass = 0 $oArrayClass = DotNet_CreateObject( $oNetCode, "ArrayClass" ) Return EndIf If IsObj( $oArrayClass ) Then Return $oArrayClass ; Compile and load VB code, create ArrayClass object $oNetCode = DotNet_LoadVBcode( FileRead( "..\Includes\ArrayFuncsOpt.vb" ), "System.dll" ) $oArrayClass = DotNet_CreateObject( $oNetCode, "ArrayClass" ) Return $oArrayClass EndFunc And the object is deleted in ArrayFuncsDelObject() by calling ArrayFuncsOptInit() with the $bDelObj parameter set to True: Func ArrayFuncsDelObject() ArrayFuncsOptInit( True ) EndFunc When the old object is deleted, a new object is created. ArrayFuncsDelObject() is called in bottom of ExampleOpt2.au3. Similar procedures are used in the example with the progress bar above to delete the old object and create a new.1 point