Jump to content

Detect sorting order in a folder


Recommended Posts

I want to detect what sorting order is applied to a given path / active window. Alternatively get an array of the files in that sort order. I only know how to get the files in the regular way:

$folder = "C:\Test"
$files = _FileListToArray($folder, "*", 1)

$msg = ""
For $i = 1 To Ubound($files) - 1
    $msg = $msg & $files[$i] & @CRLF
Next
MsgBox(0, "", $msg)

For example: The path C:\Test is sorted after lowest file size first. How do I detect that?Li3EU.thumb.jpg.ff6fa6e52cc06d3afab8a0cbc4e7b162.jpg

Link to comment
Share on other sites

Please notice in the opening post above, the image has the "Storlek" column circled in red.  And just above the "k" in "Storlek" in the column header is an up-arrow character.  This "up-arrow" character means  that this column is sorted in ascending order.  Click on the column header again, and the down-arrow character means the column is sorted in descending order.

Link to comment
Share on other sites

You need a 2D array
One way could be to read the Explorer listview to a 2D array
Else you could build your own array: 1st column = file names, and other columns filled using FileGetTime, FileGetSize etc
Then you can sort this array using _ArraySort and the $iSubitem parameter

Link to comment
Share on other sites

Maybe something that can read the settings when sending ALT+V+O to a specific window as we know it explorer saves this settings for each and every window ..

Besides what is the reason for needing this to work specifically like that ? we keep wondering ..

Link to comment
Share on other sites

I don't fully understand what you mean... Do you mean that when I sort in a folder, that info is stored somewhere I can access? In that case where?

I'm not after how to get files or sort. I'm after detecting when a folder changes sort order, and what sort is applied. Sorry if I wasn't clear.

Link to comment
Share on other sites

This can be done with UI Automation code:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#AutoIt3Wrapper_UseX64=y ; If target application is running as 64 bit code

#include "UIA_Constants.au3" ; Can be copied from UIASpy Includes folder

Opt( "MustDeclareVars", 1 )

Example()

Func Example()
  ; Create UI Automation object
  Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtag_IUIAutomation )
  If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF )
  ConsoleWrite( "$oUIAutomation OK" & @CRLF )

  ; Get Desktop element
  Local $pDesktop, $oDesktop
  $oUIAutomation.GetRootElement( $pDesktop )
  $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement )
  If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF )
  ConsoleWrite( "$oDesktop OK" & @CRLF )

  ; --- Find window/control ---

  ConsoleWrite( "--- Find window/control ---" & @CRLF )

  Local $pCondition0
  $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "CabinetWClass", $pCondition0 )
  If Not $pCondition0 Then Return ConsoleWrite( "$pCondition0 ERR" & @CRLF )
  ConsoleWrite( "$pCondition0 OK" & @CRLF )

  Local $pWindow1, $oWindow1
  $oDesktop.FindFirst( $TreeScope_Children, $pCondition0, $pWindow1 )
  $oWindow1 = ObjCreateInterface( $pWindow1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement )
  If Not IsObj( $oWindow1 ) Then Return ConsoleWrite( "$oWindow1 ERR" & @CRLF )
  ConsoleWrite( "$oWindow1 OK" & @CRLF )

  ; --- Find window/control ---

  ConsoleWrite( "--- Find window/control ---" & @CRLF )

  Local $pCondition1
  $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_HeaderControlTypeId, $pCondition1 )
  If Not $pCondition1 Then Return ConsoleWrite( "$pCondition1 ERR" & @CRLF )
  ConsoleWrite( "$pCondition1 OK" & @CRLF )

  Local $pHeader1, $oHeader1
  $oWindow1.FindFirst( $TreeScope_Descendants, $pCondition1, $pHeader1 )
  $oHeader1 = ObjCreateInterface( $pHeader1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement )
  If Not IsObj( $oHeader1 ) Then Return ConsoleWrite( "$oHeader1 ERR" & @CRLF )
  ConsoleWrite( "$oHeader1 OK" & @CRLF )

  ; --- Find window/control ---

  ConsoleWrite( "--- Find window/control ---" & @CRLF )

  Local $pCondition2
  $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "UIColumnHeader", $pCondition2 )
  If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF )
  ConsoleWrite( "$pCondition2 OK" & @CRLF )

  Local $pSplitButton1, $oSplitButton1
  $oWindow1.FindFirst( $TreeScope_Descendants, $pCondition2, $pSplitButton1 )
  $oSplitButton1 = ObjCreateInterface( $pSplitButton1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement )
  If Not IsObj( $oSplitButton1 ) Then Return ConsoleWrite( "$oSplitButton1 ERR" & @CRLF )
  ConsoleWrite( "$oSplitButton1 OK" & @CRLF )

  ; --- $oUIElement methods ---

  ConsoleWrite( "--- $oUIElement methods ---" & @CRLF )

  ;$oSplitButton1.FindAll(long,ptr,ptr*)
  ;ConsoleWrite( "$oSplitButton1.FindAll()" & @CRLF )
  Local $pElements
  $oHeader1.FindAll( $TreeScope_Descendants, $pCondition2, $pElements )
  ConsoleWrite( "$oHeader1.FindAll()" & @CRLF )

  ; --- Code Snippets ---

  ConsoleWrite( "--- Code Snippets ---" & @CRLF )

  Local $oUIElementArray1, $iLength1 ; $pElements is a pointer to an UI Automation element array
  $oUIElementArray1 = ObjCreateInterFace( $pElements, $sIID_IUIAutomationElementArray, $dtag_IUIAutomationElementArray )
  $oUIElementArray1.Length( $iLength1 )
  If Not $iLength1 Then Return ConsoleWrite( "$iLength1 = 0 ERR" & @CRLF )
  ConsoleWrite( "$iLength1 = " & $iLength1 & @CRLF )

  ; --- Code Snippets ---

  ConsoleWrite( "--- Code Snippets ---" & @CRLF )

  Local $pElement1, $oElement1
  Local $sClassName1, $iControlType1, $sName1, $sItemStatus1, $sLocalizedControlType1
  For $i = 0 To $iLength1 - 1
    $oUIElementArray1.GetElement( $i, $pElement1 )
    $oElement1 = ObjCreateInterface( $pElement1, $sIID_IUIAutomationElement, $dtag_IUIAutomationElement )
    $oElement1.GetCurrentPropertyValue( $UIA_ClassNamePropertyId, $sClassName1 )
    ConsoleWrite( "$sClassName1 = " & $sClassName1 & @CRLF )
    $oElement1.GetCurrentPropertyValue( $UIA_ControlTypePropertyId, $iControlType1 )
    ConsoleWrite( "$iControlType1 = " & $iControlType1 & @CRLF )
    $oElement1.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName1 )
    ConsoleWrite( "$sName1 = " & $sName1 & @CRLF )
    $oElement1.GetCurrentPropertyValue( $UIA_ItemStatusPropertyId, $sItemStatus1 )
    ConsoleWrite( "$sItemStatus1 = " & $sItemStatus1 & @CRLF )
    $oElement1.GetCurrentPropertyValue( $UIA_LocalizedControlTypePropertyId, $sLocalizedControlType1 )
    ConsoleWrite( "$sLocalizedControlType1 = " & $sLocalizedControlType1 & @CRLF )
  Next

  #cs
  ; --- Element Properties ---

  ConsoleWrite( "--- Element Properties ---" & @CRLF )

  Local $sClassName1
  $oSplitButton.GetCurrentPropertyValue( $UIA_ClassNamePropertyId, $sClassName1 )
  ConsoleWrite( "$sClassName1 = " & $sClassName1 & @CRLF )
  Local $iControlType1
  $oSplitButton.GetCurrentPropertyValue( $UIA_ControlTypePropertyId, $iControlType1 )
  ConsoleWrite( "$iControlType1 = " & $iControlType1 & @CRLF )
  Local $sName1
  $oSplitButton.GetCurrentPropertyValue( $UIA_NamePropertyId, $sName1 )
  ConsoleWrite( "$sName1 = " & $sName1 & @CRLF )
  Local $sItemStatus1
  $oSplitButton.GetCurrentPropertyValue( $UIA_ItemStatusPropertyId, $sItemStatus1 )
  ConsoleWrite( "$sItemStatus1 = " & $sItemStatus1 & @CRLF )
  Local $sLocalizedControlType1
  $oSplitButton.GetCurrentPropertyValue( $UIA_LocalizedControlTypePropertyId, $sLocalizedControlType1 )
  ConsoleWrite( "$sLocalizedControlType1 = " & $sLocalizedControlType1 & @CRLF )
  #ce
EndFunc

Output:

$oUIAutomation OK
$oDesktop OK
--- Find window/control ---
$pCondition0 OK
$oWindow1 OK
--- Find window/control ---
$pCondition1 OK
$oHeader1 OK
--- Find window/control ---
$pCondition2 OK
$oSplitButton1 OK
--- $oUIElement methods ---
$oHeader1.FindAll()
--- Code Snippets ---
$iLength1 = 4
--- Code Snippets ---
$sClassName1 = UIColumnHeader
$iControlType1 = 50031
$sName1 = Name
$sItemStatus1 = Sorted (Ascending) ; <<<<<<<<
$sLocalizedControlType1 = split button
$sClassName1 = UIColumnHeader
$iControlType1 = 50031
$sName1 = Date modified
$sItemStatus1 = 
$sLocalizedControlType1 = split button
$sClassName1 = UIColumnHeader
$iControlType1 = 50031
$sName1 = Type
$sItemStatus1 = 
$sLocalizedControlType1 = split button
$sClassName1 = UIColumnHeader
$iControlType1 = 50031
$sName1 = Size
$sItemStatus1 = 
$sLocalizedControlType1 = split button

 

Link to comment
Share on other sites

Thanks LarsJ! It's a shame this only works in folders with details view, obviously. If you have the time to write something that can handle any folder view, I'd be very grateful. Anyway, thanks for the code and time you put in to this! Your work is amazing. 🙂

Link to comment
Share on other sites

With UIA code, you can generally automate functions that a user can perform manually. I don't think it's possible to obtain the sort column in all views with UIA code. But it can be done with $oIFolderView2.GetSortColumns().

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...