MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / LV_Sort

Method LV_Sort

source/script_gui.cpp:10751–10847  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

10749
10750
10751void GuiType::LV_Sort(GuiControlType &aControl, int aColumnIndex, bool aSortOnlyIfEnabled, TCHAR aForceDirection)
10752// aForceDirection should be 'A' to force ascending, 'D' to force ascending, or '\0' to use the column's
10753// current default direction.
10754{
10755 if (aColumnIndex < 0 || aColumnIndex >= LV_MAX_COLUMNS) // Invalid (avoids array access violation).
10756 return;
10757 lv_attrib_type &lv_attrib = *aControl.union_lv_attrib;
10758 lv_col_type &col = lv_attrib.col[aColumnIndex];
10759
10760 int item_count = ListView_GetItemCount(aControl.hwnd);
10761 if ((col.sort_disabled && aSortOnlyIfEnabled) || item_count < 2) // This column cannot be sorted or doesn't need to be.
10762 return; // Below relies on having returned here when control is empty or contains 1 item.
10763
10764 // Init any lvs members that are needed by both LV_Int32Sort and the other sorting functions.
10765 // The new sort order is determined by the column's primary order unless the user clicked the current
10766 // sort-column, in which case the direction is reversed (unless the column is unidirectional):
10767 LV_SortType lvs;
10768 if (aForceDirection)
10769 lvs.sort_ascending = (aForceDirection == 'A');
10770 else
10771 lvs.sort_ascending = (aColumnIndex == lv_attrib.sorted_by_col && !col.unidirectional)
10772 ? !lv_attrib.is_now_sorted_ascending : !col.prefer_descending;
10773
10774 // Init those members needed for LVM_GETITEM if it turns out to be needed. This section
10775 // also serves to permanently init cchTextMax for use by the sorting functions too:
10776 lvs.lvi.pszText = lvs.buf1;
10777 lvs.lvi.cchTextMax = LV_TEXT_BUF_SIZE - 1; // Set default. Subtracts 1 because of that nagging doubt about size vs. length. Some MSDN examples subtract one, such as TabCtrl_GetItem()'s cchTextMax.
10778
10779 if (col.type == LV_COL_INTEGER)
10780 {
10781 // Testing indicates that the following approach is 25 times faster than the general-sort method.
10782 // Assign the 32-bit integer as the items lParam at this early stage rather than getting the text
10783 // and converting it to an integer for every call of the sort proc.
10784 for (lvs.lvi.lParam = 0, lvs.lvi.iItem = 0; lvs.lvi.iItem < item_count; ++lvs.lvi.iItem)
10785 {
10786 lvs.lvi.mask = LVIF_TEXT;
10787 lvs.lvi.iSubItem = aColumnIndex; // Which field to fetch (must be reset each time since it's set to 0 below).
10788 lvs.lvi.lParam = SendMessage(aControl.hwnd, LVM_GETITEM, 0, (LPARAM)&lvs.lvi)
10789 ? ATOI(lvs.lvi.pszText) : 0; // Must not refer to lvs.buf1 directly because MSDN says LVM_GETITEMTEXT might have changed pszText to point to some other string.
10790 lvs.lvi.mask = LVIF_PARAM;
10791 lvs.lvi.iSubItem = 0; // Indicate that an item vs. subitem is being operated on (subitems can't have an lParam).
10792 ListView_SetItem(aControl.hwnd, &lvs.lvi);
10793 }
10794 // Always use non-Ex() for this one because it's likely to perform best due to the lParam setup above.
10795 // The value of iSubItem is not reset to aColumnIndex because LV_Int32Sort() doesn't use it.
10796 SendMessage(aControl.hwnd, LVM_SORTITEMS, lvs.sort_ascending, (LPARAM)LV_Int32Sort); // Should always succeed since it uses non-Ex() version.
10797 }
10798 else // It's LV_COL_TEXT or LV_COL_FLOAT.
10799 {
10800 if (col.type == LV_COL_TEXT && col.case_sensitive == SCS_INSENSITIVE_LOGICAL) // SCS_INSENSITIVE_LOGICAL can be in effect even when type isn't LV_COL_TEXT because it allows a column to be later changed to TEXT and retain its "logical-sort" setting.
10801 {
10802 // v1.0.44.12: Support logical sorting, which treats numeric strings as true numbers like Windows XP
10803 // Explorer's sorting. This is done here rather than in LV_ModifyCol() because it seems more
10804 // maintainable/robust (plus LV_GeneralSort() relies on us to do this check).
10805 lvs.lvi.cchTextMax = lvs.lvi.cchTextMax/2 - 1; // Buffer can hold only half as many Unicode characters as non-Unicode (subtract 1 for the extra-wide NULL terminator).
10806 }
10807 // Since LVM_SORTITEMSEX requires comctl32.dll version 5.80+, the non-Ex version is used
10808 // whenever the EX version fails to work. One reason to strongly prefer the Ex version

Callers

nothing calls this directly

Calls 1

ATOIFunction · 0.85

Tested by

no test coverage detected