Leaderboard
Popular Content
Showing content with the highest reputation on 05/22/2021 in all areas
-
Block keyboard input without admin rights
Professor_Bernd reacted to JockoDundee for a topic
Yikes! I’d say stop now while you’re ahead Although I briefly considered a Intralingual Compensatory Delay, I ultimately rejected an ICD on the basis of excessive and gratuitous novelty. Rather the delay compensates for a lack of actionable knowledge; by reaching ever so slightly into the time domain; and using the datapoint gained as my heuristical talisman, if you will. Plainly speaking what this means is that whenever the Param window becomes the fg window, it wastes no time in remapping most keystrokes, globally, to its own handler. Which works great until the window loses focus! So then it says “who did I lose focus to?” If the new fg window is neither the param window nor the edit window, then it hastily removes its own handler to get out if the way. Otherwise, based on the theory that if the reason we lost focus was because the F5 was pressed and the log stole it, that the focus will be restored by VB in a few milliseconds. If after a few milliseconds this doesn’t happen, we hastily remove the handler, assuming that the focus was actually changed by a click to the edit window. Hope that makes more sense to you than it does to me1 point -
Pass parameter to a running process
argumentum reacted to jugador for a topic
@Subz Before posting I try using INI and that’s work. Due to lack of coding knowledge I thought it’s possible to pass parameter to a running application using Run & StdinWrite function. working code using INI as bridge.... parent #include <GUIConstantsEx.au3> #include <constants.au3> Global $FName = 'Child.exe' Global $Exepath = @ScriptDir & '\' & $FName Global $__INIPath = @ScriptDir & "\IniFlag.ini" Global $pid __gui1() Func __gui1() Local $hGUI = GUICreate("Gui 1", 180, 150, 100, 100) Local $idButton1 = GUICtrlCreateButton("Start", 10, 10, 80, 30) Local $idButton2 = GUICtrlCreateButton("Stop", 10, 50, 80, 30) Local $idLabel = GUICtrlCreateLabel('', 10, 90, 80, 50 ) Local $o_String GUICtrlSetState($idButton2, $GUI_DISABLE) GUISetState(@SW_SHOW, $hGUI) Local $aMsg While 1 $aMsg = GUIGetMsg(1) Switch $aMsg[1] Case $hGUI Switch $aMsg[0] Case $GUI_EVENT_CLOSE ExitLoop Case $idButton1 GUICtrlSetState($idButton1, $GUI_DISABLE) GUICtrlSetState($idButton2, $GUI_ENABLE) GUICtrlSetData($idLabel, 'process start') IniWrite($__INIPath, "Flag_Param", "Child_flag", "False") $o_String = '' $pid = Run($Exepath, '', '', $STDIN_CHILD + $STDOUT_CHILD) Case $idButton2 GUICtrlSetState($idButton1, $GUI_ENABLE) GUICtrlSetState($idButton2, $GUI_DISABLE) GUICtrlSetData($idLabel, 'process stop') IniWrite($__INIPath, "Flag_Param", "Child_flag", "True") ProcessWait($FName) $o_String = StdoutRead($pid) ConsoleWrite( $o_String & @CRLF ) EndSwitch EndSwitch WEnd GUIDelete($hGUI) EndFunc Child ;~~~~ Child Global $bflag = False __Example() Func __Example() Local $__INIPath = @ScriptDir & "\IniFlag.ini" Local $o_String Local $i = 0 While 1 $o_String = IniRead($__INIPath, "Flag_Param", "Child_flag", "False") If StringInStr($o_String, "True") Then __Flag() If $bflag = True Then __Terminate() ConsoleWrite( $i & @CRLF ) $i = $i + 1 Sleep(250) WEnd EndFunc ;==>__Example Func __Flag() ConsoleWrite( ' ' & $bflag & @CRLF ) $bflag = True ConsoleWrite( ' ' & $bflag & @CRLF ) EndFunc ;==> __Flag() Func __Terminate() ConsoleWrite( ' The End ' & @CRLF ) Exit EndFunc ;==> __Terminate() @argumentum I haven’t look into your udf but I will try to make it work using your udf or _WM_COPYDATA.1 point -
Block keyboard input without admin rights
Professor_Bernd reacted to JockoDundee for a topic
Ok, lets go with this one, with slightly improved odds: RunParamsDialog.au31 point -
Pass parameter to a running process
jugador reacted to argumentum for a topic
..could also get familiar with IPC technics. ( example: https://www.autoitscript.com/forum/topic/193277-ipc-udf-via-filemapping-20180404/ )1 point -
You could use an external flag for example registry or file, the child keeps watching for this flag and and once changed deletes or modifies the flag back to the default. Hope that makes sense1 point
-
Copy all files of a folder without overwriting existing ones
Subz reacted to Earthshine for a topic
@Professor_Bernd Use this code: #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> $result = 0 Example() Func Example() Local $sFilePath ; Creates the source folder. ; Should copy all files from the source folder to the destination folder without overwriting existing files. ;~ FileCopy("d:\xSlog\*.*", "d:\MyDestDir\*.*", $FC_NOOVERWRITE + $FC_CREATEPATH) Run("robocopy d:\xSlog d:\MyDestDir\ /r:0 /z", @ScriptDir) ; Display the temporary directory. EndFunc ;==>Example That does what you want exactly. If you ALSO want to pick up subdirectories and their files, do this: #include <FileConstants.au3> #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> $result = 0 Example() Func Example() Local $sFilePath ; Creates the source folder. ; Should copy all files from the source folder to the destination folder without overwriting existing files. ;~ FileCopy("d:\xSlog\*.*", "d:\MyDestDir\*.*", $FC_NOOVERWRITE + $FC_CREATEPATH) Run("robocopy d:\xSlog d:\MyDestDir\ /s /e /r:0 /z", @ScriptDir) ; Display the temporary directory. EndFunc ;==>Example Just make sure to substitute YOUR input and output directories in the code. I used mine as a test because it had lots of files and subfolders.1 point -
Copy all files of a folder without overwriting existing ones
Professor_Bernd reacted to Earthshine for a topic
ok i repeated your test, i did the same steps. I see it now. in Temp everything was working fine but when I use your code and add 3 .txt files they don't get created on the target dir after re-running the script. Maybe open a ticket for support. For now use @Musashi's code and check out those links he provided.1 point -
Copy all files of a folder without overwriting existing ones
Professor_Bernd reacted to Musashi for a topic
This is true (at least for my older AutoIt version 3.3.14.0). The following post by Melba23 explains the problem : https://www.autoitscript.com/forum/topic/176952-filecopy-works-only-with-overwrite-solved/?do=findComment&comment=1270166 Excerpt :1 point -
Incremental search in owner and custom drawn ListViews
Norm73 reacted to pixelsearch for a topic
Hi LarsJ I tried to use the Custom draw for incremental search but it didn't work fine, could you please help ? The only thing that "works" in the script below (named "2k") is this : * Please type . or .$ in the Search field, then hover over rows and you'll see the correct matching 1st (or last) character with cyan background in Col 0. Nothing appears if the rows aren't hovered over. * Then change the search column (right-click on a new header or use the Combo) and the cyan background never appears in any searched column (it should appear on 1st or last character, no matter the searched column, as RegEx search is "." or ".$") I checked the 4 values of the rectangle etc... and added some commented ConsoleWrite's during Case $NM_CUSTOMDRAW. Values seem correct, maybe hdc isn't correct when applied to Cols 1+ ? I didn't use at all "clrTextBk" or "clrText". Their value is constantly 0xFF000000 ($CLR_DEFAULT) and if we're able to see a cyan background on matched characters while hovering over Col 0, then it should be ok. Also, as soon as I tried to use "clrTextBk" during a test, then the whole subitem got its background colored. Finally, as the Owner draw script ("2i") worked fine in a precedent post , then we don't really need the Custom draw way (especially it's "extremely message intensive" as you indicated) , but I was just curious to see if it was doable or not. Thanks if you got any idea on how to make Case $NM_CUSTOMDRAW work correctly in the script : #include <ComboConstants.au3> #include <EditConstants.au3> #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include "RandomArray.au3" ; LarsJ Opt("MustDeclareVars", 1) Global $g_iRows = 1000, $g_iCols = 6, $g_iLeftLV = 10, $g_iTopLV = 40, $g_hGui, $g_hListView, $g_hHeader, $g_hEdit Global $g_aCols = ["Strings", "Integers", "Floats", "Dates", "Times", "R/C"], $g_aWidths = [230, 61, 124, 70, 60, 60] Global $g_idListView, $g_idMarker, $g_idComboCol, $g_idComboColDummy, $g_idEditDummy Global $g_sSearch, $g_iSearchCol, $g_iSortDir, $g_iSearch = $g_iRows Global $g_aArray, $g_aSubArray, $g_tDefaultIndex, $g_tIndex = DllStructCreate("uint arr[" & $g_iRows & "]") Global $g_aIndex[$g_iCols], $g_aIndexTemp[$g_iCols] ; VarGetType's : $g_aIndex => "Array", $g_aIndex[0] => "String" Example() Func Example() ; Generate array & one index _Generate_All($g_aArray) $g_aSubArray = $g_aArray $g_tDefaultIndex = $g_tIndex ; Create GUI $g_hGui = GUICreate("Virtual ListView + Sort + Incremental search + CustomDraw (2k)", 630 + 20, 788 + 30 + 20) ; Create Edit control (search) + dummy control Local $idEdit = GUICtrlCreateEdit("", 120, 10, 305, 20, BitXOR($GUI_SS_DEFAULT_EDIT, $WS_HSCROLL, $WS_VSCROLL)) $g_hEdit = GUICtrlGetHandle($idEdit) $g_idEditDummy = GUICtrlCreateDummy() ; Create ComboBox control (how to search : RegEx or Normal ?) Local $idSearchHow = GUICtrlCreateCombo("RegEx search", 11, 9, 100, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST)) Local $sSearchHow = "RegEx search", $sSearchHowPrev = $sSearchHow ; default way of searching (changeable) GUICtrlSetData($idSearchHow, "Normal search", $sSearchHow) ; Create ComboBox control (column where to search) + dummy control GUICtrlCreateLabel("Col", 429, 10, 20, 20, BitOR($SS_CENTERIMAGE, $SS_CENTER)) $g_idComboCol = GUICtrlCreateCombo("0", 452, 9, 41, 20, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_DROPDOWNLIST)) $g_iSearchCol = 0 ; default column where to search (changeable) Local $iSearchColPrev = $g_iSearchCol For $i = 1 To $g_iCols - 1 GUICtrlSetData($g_idComboCol, $i & "|", $g_iSearchCol) Next $g_idComboColDummy = GUICtrlCreateDummy() ; Create Label control (number of matching results) Local $idResult = GUICtrlCreateLabel(" " & $g_iRows & " rows (no pattern)", 501, 10, 135, 20, BitOR($SS_CENTERIMAGE, $SS_SUNKEN)) ; Create ListView $g_idListView = GUICtrlCreateListView("", $g_iLeftLV, $g_iTopLV, 630, 788, BitOr($GUI_SS_DEFAULT_LISTVIEW, $LVS_OWNERDATA), $WS_EX_CLIENTEDGE) _GUICtrlListView_SetExtendedListViewStyle($g_idListView, BitOr($LVS_EX_DOUBLEBUFFER, $LVS_EX_FULLROWSELECT)) $g_hListView = GUICtrlGetHandle($g_idListView) $g_hHeader = _GUICtrlListView_GetHeader($g_idListView) For $i = 0 To $g_iCols - 1 _GUICtrlListView_AddColumn($g_idListView, $g_aCols[$i], $g_aWidths[$i]) Next ; Create Marker (an orange line placed above the header of the column being searched) $g_idMarker = GUICtrlCreateLabel("", 0, 0) GUICtrlSetBkColor(-1, 0xFFA060) ; orange _MoveMarker($g_iSearchCol) _GUICtrlListView_SetSelectedColumn($g_idListView, $g_iSearchCol) ; Sorting information $g_iSortDir = 0x0400 ; $HDF_SORTUP Local $iSortCol = -1, $iSortColPrev = -1 GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iRows, 0) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $g_idComboCol, $g_idComboColDummy, $idSearchHow $g_iSearchCol = GUICtrlRead($g_idComboCol) $sSearchHow = GUICtrlRead($idSearchHow) Select Case $g_iSearchCol <> $iSearchColPrev _MoveMarker($g_iSearchCol) ; Search column will be selected below, after ContinueCase $iSearchColPrev = $g_iSearchCol Case $sSearchHow <> $sSearchHowPrev $sSearchHowPrev = $sSearchHow Case Else ; no change in both Combo controls (same search column, same search way) ContinueLoop EndSelect ContinueCase Case $g_idEditDummy _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortCol, $HDF_STRING) $g_sSearch = GUICtrlRead($idEdit) $g_tIndex = $g_tDefaultIndex If $g_sSearch = "" Then ; Empty search string, display all rows $g_aSubArray = $g_aArray $g_iSearch = $g_iRows Else ; Find rows matching the search string $g_iSearch = 0 If $sSearchHow = "RegEx search" Then For $i = 0 To $g_iRows - 1 ; duplicated For... Next for speed If StringRegExp($g_aArray[$i][$g_iSearchCol], "(?i)" & $g_sSearch) Then For $j = 0 To $g_iCols - 1 $g_aSubArray[$g_iSearch][$j] = $g_aArray[$i][$j] Next $g_iSearch += 1 EndIf Next Else ; "Normal search" For $i = 0 To $g_iRows - 1 ; duplicated For... Next for speed If StringInStr($g_aArray[$i][$g_iSearchCol], $g_sSearch) Then For $j = 0 To $g_iCols - 1 $g_aSubArray[$g_iSearch][$j] = $g_aArray[$i][$j] Next $g_iSearch += 1 EndIf Next EndIf ; Delete eventual temporary subindexes For $i = 0 To $g_iCols - 1 If VarGetType($g_aIndexTemp[$i]) = "DLLStruct" Then $g_aIndexTemp[$i] = "" ; "String" Next EndIf GUICtrlSetData($idResult, " " & $g_iSearch & ($g_sSearch = "" ? " rows (no pattern)" : " matching rows")) ;------ ; _GUICtrlListView_SetSelectedColumn($g_hListView, $g_iSearchCol) ; depending on search, crashes script when placed here ; _GUICtrlListView_SetSelectedColumn($g_idListView, $g_iSearchCol) ; strange behavior here ; GUICtrlSendMsg($g_idListView, $LVM_SETSELECTEDCOLUMN, $g_iSearchCol, 0) ; strange behavior here ;------ GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) _GUICtrlListView_SetSelectedColumn($g_hListView, $g_iSearchCol) ; seems ok here (after $LVM_SETITEMCOUNT) Case $g_idListView ; Sort $iSortCol = GUICtrlGetState($g_idListView) If $iSortCol <> $iSortColPrev Then _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortColPrev, $HDF_STRING) EndIf ; Set $g_tIndex + eventual update of $g_aIndexTemp[$iSortCol] OR $g_aIndex[$iSortCol] If GUICtrlRead($idEdit) Then _UpdateIndex($g_aIndexTemp, $iSortCol) Else _UpdateIndex($g_aIndex, $iSortCol) EndIf $g_iSortDir = (($iSortCol = $iSortColPrev) ? ($g_iSortDir = $HDF_SORTUP ? $HDF_SORTDOWN : $HDF_SORTUP) : ($HDF_SORTUP)) _GUICtrlHeader_SetItemFormat($g_hHeader, $iSortCol, $HDF_STRING + $g_iSortDir) GUICtrlSendMsg($g_idListView, $LVM_SETSELECTEDCOLUMN, $iSortCol, 0) GUICtrlSendMsg($g_idListView, $LVM_SETITEMCOUNT, $g_iSearch, 0) $iSortColPrev = $iSortCol Case $GUI_EVENT_RESTORE ; needed, or Marker goes back in 0, 0 after Restore (why ?) _MoveMarker($g_iSearchCol) EndSwitch WEnd ; Cleanup GUIDelete($g_hGui) EndFunc ;==>Example ;======================================================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam) Switch HWnd(DllStructGetData($tNMHDR, "hWndFrom")) Case $g_hListView Switch DllStructGetData($tNMHDR, "Code") Case $NM_CUSTOMDRAW Local $tCustDraw = DllStructCreate($tagNMLVCUSTOMDRAW, $lParam) Local $iDrawStage = DllStructGetData($tCustDraw, "dwDrawStage") If $iDrawStage = $CDDS_PREPAINT Then Return $CDRF_NOTIFYITEMDRAW If $iDrawStage = $CDDS_ITEMPREPAINT Then Return $CDRF_NOTIFYSUBITEMDRAW Local $iItem = DllStructGetData($tCustDraw, "dwItemSpec") Local $iSubItem = DllStructGetData($tCustDraw, "iSubItem") ;~ ConsoleWrite("0x" & Hex($tCustDraw.clrText, 8) & " 0x" & Hex($tCustDraw.clrTextBk, 8) & @lf) ; both 0xFF000000 ($CLR_DEFAULT) If ($iSubItem = $g_iSearchCol) And $g_sSearch Then Local Static $tRect = DllStructCreate( $tagRECT ), $pRect = DllStructGetPtr( $tRect ), $tSize = DllStructCreate( $tagSIZE ) Local Static $hBrushYellow = _WinAPI_CreateSolidBrush( 0x00FFFF ), $hBrushCyan = _WinAPI_CreateSolidBrush( 0xFFFF00 ) ; Yellow and cyan, BGR Local $hDC = DllStructGetData( $tCustDraw, "hDC" ) ;~ ConsoleWrite("$hDC = " & $hDC & @lf) If $g_iSortDir = 0x0400 Then ; 0x0400 = $HDF_SORTUP Local $sItemText = $g_aSubArray[$g_tIndex.arr($iItem + 1)][$iSubItem] Else Local $sItemText = $g_aSubArray[$g_tIndex.arr($g_iSearch - $iItem)][$iSubItem] EndIf ;~ ConsoleWrite("$sItemText = " & $sItemText & @lf) Local $sMatch = StringRegExp( $sItemText, "(?i)" & $g_sSearch, 1 ), $extended = @extended, $iLen = StringLen( $sMatch[0] ) ; Subitem rectangle DllStructSetData( $tRect, 2, $g_iSearchCol ) ; Top DllStructSetData( $tRect, 1, $LVIR_BOUNDS ) ; Left GUICtrlSendMsg( $g_idListView, $LVM_GETSUBITEMRECT, $iItem, $pRect ) DllStructSetData( $tRect, 1, DllStructGetData( $tRect, 1 ) + 6 ) ; Left margin ;~ DllStructSetData( $tRect, 2, DllStructGetData( $tRect, 2 ) + 2 ) ; Top margin ;~ ConsoleWrite("Top = " & $tRect.Top & " " & "Bottom = " & $tRect.Bottom & " " & _ ;~ "Left = " & $tRect.Left & " " & "Right = " & $tRect.Right & @lf) ; Rectangle for matching substring DllCall( "gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sItemText, "int", $extended - $iLen - 1, "struct*", $tSize ) ; _WinAPI_GetTextExtentPoint32 DllStructSetData( $tRect, "Left", DllStructGetData( $tRect, "Left" ) + DllStructGetData( $tSize, "X" ) ) DllCall( "gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sMatch[0], "int", $iLen, "struct*", $tSize ) ; _WinAPI_GetTextExtentPoint32 DllStructSetData( $tRect, "Right", DllStructGetData( $tRect, "Left" ) + DllStructGetData( $tSize, "X" ) ) ;~ ConsoleWrite("Top = " & $tRect.Top & " " & "Bottom = " & $tRect.Bottom & " " & _ ;~ "Left = " & $tRect.Left & " " & "Right = " & $tRect.Right & @lf) ; Fill rectangle with cyan background color DllCall( "user32.dll", "int", "FillRect", "handle", $hDC, "struct*", $tRect, "handle", $hBrushCyan) ; _WinAPI_FillRect ; Draw matching substring in rectangle ; DllCall( "gdi32.dll", "int", "SetTextColor", "handle", $hDC, "int", 0x000000 ) ; _WinAPI_SetTextColor DllCall( "gdi32.dll", "int", "SetBkColor", "handle", $hDC, "int", 0xFFFF00 ) ; _WinAPI_SetBkColor (cyan) DllCall( "user32.dll", "int", "DrawTextW", "handle", $hDC, "wstr", $sMatch[0], "int", $iLen, "struct*", $tRect, "uint", 0 ) ; _WinAPI_DrawText EndIf Return $CDRF_NEWFONT Case $LVN_GETDISPINFOW Local $tNMLVDISPINFO = DllStructCreate($tagNMLVDISPINFO, $lParam) Local Static $tText = DllStructCreate("wchar[50]"), $pText = DllStructGetPtr($tText) If $g_iSortDir = 0x0400 Then ; 0x0400 = $HDF_SORTUP DllStructSetData($tText, 1, $g_aSubArray[$g_tIndex.arr($tNMLVDISPINFO.Item + 1)][$tNMLVDISPINFO.SubItem]) Else DllStructSetData($tText, 1, $g_aSubArray[$g_tIndex.arr($g_iSearch - $tNMLVDISPINFO.Item)][$tNMLVDISPINFO.SubItem]) EndIf DllStructSetData($tNMLVDISPINFO, "Text", $pText) EndSwitch Case $g_hHeader Switch DllStructGetData($tNMHDR, "Code") Case $HDN_ENDTRACKW, $HDN_DIVIDERDBLCLICKW ; let's forget $HDN_TRACKW... _MoveMarker(GUICtrlRead($g_idComboCol)) Case $NM_RCLICK Local $aHit = _GUICtrlListView_SubItemHitTest($g_hListView) ; $aHit[1] : 0-based index of the LV subitem... i.e. the column in our case (may be -1 if right click on empty part of header) If $aHit[1] > - 1 Then ; valid column GUICtrlSetData($g_idComboCol, $aHit[1]) GUICtrlSendToDummy($g_idComboColDummy) EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;======================================================================== Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local $hWndFrom = $lParam Local $iCode = BitShift($wParam, 16) ; High word Switch $hWndFrom Case $g_hEdit Switch $iCode Case $EN_CHANGE GUICtrlSendToDummy($g_idEditDummy) EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND ;======================================================================== Func _Generate_All(ByRef $g_aArray) ConsoleWrite("$g_iRows = " & $g_iRows & " $g_iCols = " & $g_iCols & @CRLF) Local $hTimer = TimerInit() $g_aArray = FAS_Random2DArrayAu3($g_iRows, "sifdtr", "abcdefghijklmnopqrstuvwxyz") For $i = 0 To $g_iRows - 1 $g_tIndex.arr($i + 1) = $i Next ConsoleWrite("Generating array & one index = " & TimerDiff($hTimer) & @CRLF & @CRLF) EndFunc ;==>_Generate_All ;======================================================================== Func _SortArrayStruct(Const ByRef $aArray, $iCol, $iRows) Local $tIndex = DllStructCreate("uint arr[" & $iRows & "]") Local $pIndex = DllStructGetPtr($tIndex) Local Static $hDll = DllOpen("kernel32.dll") Local Static $hDllComp = DllOpen("shlwapi.dll") Local $lo, $hi, $mi, $r ; Sorting by one column For $i = 1 To $iRows - 1 $lo = 0 $hi = $i - 1 Do $mi = Int(($lo + $hi) / 2) $r = DllCall($hDllComp, 'int', 'StrCmpLogicalW', 'wstr', $aArray[$i][$iCol], 'wstr', $aArray[DllStructGetData($tIndex, 1, $mi + 1)][$iCol])[0] Switch $r Case -1 $hi = $mi - 1 Case 1 $lo = $mi + 1 Case 0 ExitLoop EndSwitch Until $lo > $hi DllCall($hDll, "none", "RtlMoveMemory", "struct*", $pIndex + ($mi + 1) * 4, "struct*", $pIndex + $mi * 4, "ulong_ptr", ($i - $mi) * 4) DllStructSetData($tIndex, 1, $i, $mi + 1 + ($lo = $mi + 1)) Next Return $tIndex EndFunc ;==>_SortArrayStruct ;======================================================================== Func _UpdateIndex(ByRef $aIndex, $iCol) If VarGetType($aIndex[$iCol]) = "DLLStruct" Then $g_tIndex = $aIndex[$iCol] Else $g_tIndex = _SortArrayStruct($g_aSubArray, $iCol, $g_iSearch) $aIndex[$iCol] = $g_tIndex ; "DLLStruct" (or "Int32" when no match found +++) EndIf EndFunc ;==>_UpdateIndex ;======================================================================== Func _MoveMarker($iCol) Local $aRect = _GUICtrlHeader_GetItemRect($g_hHeader, $iCol) ControlMove($g_hGui, "", $g_idMarker, $g_iLeftLV + $aRect[0], $g_iTopLV - 3, $aRect[2] - $aRect[0] + 1, 3) EndFunc ;==>_MoveMarker1 point