Jump to content

Sort arrow in _ArrayDisplay ?


Recommended Posts

Thanks guys for the test, which confirms the same behavior on all computers.

This lack of the sort arrow is probably annoying for many users because this little arrow shows at same time which column is sorted + if the sort is ascending or descending. For example have a look at this link where paulpmeier had to describe what he was doing in his initial pics ("first click", "second click") because the sort arrow didn't show in _ArrayDisplay

I found a couple of links, here and there (both from 2009) which lead us to the right direction, not counting the help file, topic _GUICtrlListView_SortItems (1st example) which shows it's possible to easily display a sort arrow when left clicking on the header column of a listview control.

So the question is : why doesn't it work in _ArrayDisplay ?
Melba23 could certainly answer to this question better than me, but meanwhile I'd like to share some thoughts with you.

This is what we read at line #555 in ArrayDisplayInternals.au3 (version 3.3.14.5)

; #DUPLICATED Functions to avoid big #include <GuiListView.au3># ================================================================
; Functions have been simplified (unicode inprocess) according to __ArrayDisplay_Share() needs

Now let's have a look at 2 concerned lines in ArrayDisplayInternals.au3
1) Line #448

__ArrayDisplay_RegisterSortCallBack($idListView, 2, True, "__ArrayDisplay_SortCallBack")

Let's replace it with its corresponding "original" line :

_GUICtrlListView_RegisterSortCallBack($idListView, 2, True)

2) Line #522

__ArrayDisplay_SortItems($idListView, GUICtrlGetState($idListView))

Let's replace it with its original line :

_GUICtrlListView_SortItems($idListView, GUICtrlGetState($idListView))

3) And of course, for this test, let's add at the beginning of ArrayDisplayInternals.au3 :

#include <GuiListView.au3>

Now the sort arrow appears when you run the little test script posted above and you should have a display corresponding to the image in 1st post

So it seems that there is a little "discrepancy" (?) between the #DUPLICATED Functions and the originals, which prevent the sort arrow to be displayed. As these functions are very similar, it shouldn't be too hard to compare both of them and finally allow everybody to display this important sort arrow in _ArrayDisplay, without including GuiListView.au3... of course ;)

 

Link to comment
Share on other sites

Found the issue :sweating:

Original ArrayDisplayInternals.au3 (version 3.3.14.5) lines #560 to #563 :

If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

;~  Local Const $LVM_GETHEADER = (0x1000 + 31) ; 0x101F
    Local $hHeader =  HWnd(GUICtrlSendMsg($hWnd, 0x101F, 0, 0))

Move line #560 just below the 2 others :

;~  Local Const $LVM_GETHEADER = (0x1000 + 31) ; 0x101F
    Local $hHeader =  HWnd(GUICtrlSendMsg($hWnd, 0x101F, 0, 0))

    If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd)

Now the sort arrow will be displayed when you sort on any column :)

Link to comment
Share on other sites

  • Moderators

pixelsearch,

Nice catch! In fact I believe that the whole If line is redundant as the function is only ever passed a ControlID - but I will let the Devs have the final word. So I suggest opening a Trac ticket so that the code can be modified for the next release.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

On 11/16/2020 at 10:51 AM, Melba23 said:

Nice catch! In fact I believe that the whole If line is redundant as the function is only ever passed a ControlID - but I will let the Devs have the final word.

That's right, and also because line #565 is useless in ArrayDisplayInternals.au3, where the array $__g_aArrayDisplay_SortInfo[] is a 1D array :

$__g_aArrayDisplay_SortInfo[1] = $hWnd ; Handle of listview

The corresponding "original" line of code is important in GuiListView.au3, where the array $__g_aListViewSortInfo[][] is a 2D array :

$__g_aListViewSortInfo[$iIndex][1] = $hWnd

When a sort is registered in GuiListView.au3, using _GUICtrlListView_RegisterSortCallBack(), then a row is added to the 2D array, with the listview handle acting like an "index" to process the correct row later in different functions, i.e. __GUICtrlListView_Sort() and _GUICtrlListView_SortItems() and _GUICtrlListView_UnRegisterSortCallBack(), this last function removing a row from the 2D array, after having correctly  de-allocated the resource with the instruction DllCallbackFree

Which leads to another possible issue : why isn't the resource de-allocated in _ArrayDisplay ?

Please have a look at this script :

#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
    Local $aSortTest[2][3] = [["1a", "1b", "1c"], ["2a", "2b", "2c"]]

    Local $hGUI = GUICreate("Test", 200, 100, -1, 80, -1, $WS_EX_TOPMOST)
    Local $idButton = GUICtrlCreateButton("Click me", 60, 40, 80, 30)

    GUISetState(@SW_SHOW)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idButton
                GUISetState(@SW_DISABLE, $hGUI)
                ; _ArrayDisplay($aSortTest)
                _ArrayDisplay($__g_aArrayDisplay_SortInfo) ; global array in ArrayDisplayInternals.au3
                GUISetState(@SW_ENABLE, $hGUI)
        EndSwitch
    WEnd
    GUIDelete($hGUI)
EndFunc   ;==>Example

Each click on the test button will call ArrayDisplay, then you close the ArrayDisplay GUI and click on the test button again. After you do this 5 times, you'll end with this kind of display :

456138796_node-allocation.png.a870ead7858403a248c3dc3ccae6b7c3.png

This red-circled "5" means that DllCallbackRegister() has been called 5 times without de-allocating it.
But if we look at the help file, topic DllCallbackRegister, this is what we read :

When finished working with a callback, call the DllCallbackFree() function to close it.

AutoIt normally closes all files upon termination, but explicitly calling DllCallbackFree() is still a good idea.

In the precedent script, we're not terminating AutoIt because each ArrayDisplay call brings us back to our script.
To fix this potential issue, here is what could be done, by adding 2 lines (DllCallbackFree) in ArrayDisplayInternals.au3

Case $idExit_Script
                ; Clear up
                DllCallbackFree($__g_aArrayDisplay_SortInfo[2]) ; <=====================
                GUIDelete($hGUI)
                Exit
        EndSwitch
    WEnd

    ; Clear up
    DllCallbackFree($__g_aArrayDisplay_SortInfo[2]) ; <=====================
    GUIDelete($hGUI)
    Opt("GUICoordMode", $iCoordMode) ; Reset original Coord mode
    Opt("GUIOnEventMode", $iOnEventMode) ; Reset original GUI mode
;~  Opt("GUIDataSeparatorChar", $sCurr_Separator) ; Reset original separator

    Return 1
EndFunc   ;==>__ArrayDisplay_Share

Now we have a correct display & de-allocation, even after we click several times the button in the test script :

1220689259_withde-allocation.png.5ed7f0785a3c08db72052ff0236b7a73.png

2 remarks :
* Row 10 indicates a wrong header handle 0x00000000 in the 1st pic. Trac ticket #3791 fixes this issue in the 2nd pic.

* In the test script, if you uncomment the line ; _ArrayDisplay($aSortTest)
Then you'll notice that the value in Row2 is incremented 2 by 2 (1-3-5...) as there are now 2 ArrayDisplay processed in the script for each clic on the test button.

If you think this is a potential issue, please let me know so I'll open a trac ticket, suggesting to add the 2 DllCallbackFree() lines to ArrayDisplayInternals.au3

Link to comment
Share on other sites

  • Moderators

Pixelsearch,

That does look like a problem. But jpm modified the ArrayDisplayInternals code when we split the function into _ArrayDisplay and _DebugArrayDisplay versions. I suggest  you PM him and point him to this thread so he can make the call.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

pixelsearch,

Excellent news and thanks for your efforts in debugging.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

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...