The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jckl on April 27, 2007, 08:56:51 AM

Title: Listview sorting.
Post by: jckl on April 27, 2007, 08:56:51 AM
I am having trouble with sorting the size field of my listview. In the size i have commas which are causing the sorting to be wierd. It works to a point.

Here is how it would look if i sorted smallest to largest.

1,210,023
1,222,012
1,310,120
      240
      240
    1,120
    2,230
   19,300


I tried to strip the commas before converting ascii to base but that made it way off. I looked in the masm32 dir for examples and found one but it sorts this way aswell. The code i currently have in my app is the same as the example i found. the code for the size sorting is as follows.


         mov     lvi.iSubItem, 1
         INVOKE     SendMessage, hList, LVM_GETITEMTEXT, lParam1, addr lvi
         Invoke AsciiBase2, addr szBuff0

         mov     edi, eax
         INVOKE     SendMessage, hList, LVM_GETITEMTEXT, lParam2, addr lvi
         Invoke AsciiBase2, addr szBuff0       

         .if lParamSort == 3
               sub     edi, eax
               mov     eax, edi
         .else
               sub     eax, edi
         .endif


I used the asciibase from that example as well but had to rename it so it would not conflict with the asciibase function i already had.

The code to strip the commas is


cStrip PROC SRC:DWORD
   mov edi,SRC
   mov esi,edi
  toploop:
   lodsb
   cmp al,","
   jz @F
   stosb
  @@:
   test al,al
   jnz toploop
   ret
cStrip endp


I tried stripping the commas before and after the asciibase but it did not work either way. Like i said without the commas this works just fine.. I am not sure i fully understand how the sorting works or how to fix this. I tried to sort them the same way i sort the names but that also did not work.
Title: Re: Listview sorting.
Post by: Tedd on April 27, 2007, 09:58:29 AM
I'm not sure what mess you've got yourself into :lol but what you should be doing is:
- convert the number-strings into a number-values (ascii -> integer), ignoring the commas (or copy the string while removing them, then use a2d?)
- then compare these number-values (which can be held in registers)
- and return the appropriate value to indicate how the two given number-strings should be ordered relative to each other.
Title: Re: Listview sorting.
Post by: jckl on April 29, 2007, 04:54:41 AM
I tried what you said but my results came out wrong again. It sorted them but it didnt list them as if one number is larger than the others. It listed them based off each diggit for instance my result would look like the following.



    1,120
1,210,023
  121,100
1,222,012
1,310,120
   19,300
    2,230
      240
      240
Title: Re: Listview sorting.
Post by: hutch-- on April 29, 2007, 05:21:15 AM
If you want these types of number,


      t0  db "123",0
      t1  db "1234",0
      t2  db "12345",0
      t3  db "123456",0
      t4  db "987",0
      t5  db "9876",0
      t6  db "98765",0
      t7  db "987654",0
      t8  db "234",0
      t9  db "2345",0
      t10 db "23456",0
      t11 db "234567",0
      t12 db "876",0
      t13 db "8765",0
      t14 db "87654",0
      t15 db "876543",0
      t16 db "5647",0
      t17 db "564738",0
      t18 db "56473829",0
      t19 db "5647382910",0


sorted to be like,


123
1234
12345
123456
234
2345
23456
234567
5647
564738
56473829
5647382910
876
8765
87654
876543
987
9876
98765
987654


Try string sorting. These are done witrh the masm32 library sorts.
Title: Re: Listview sorting.
Post by: jckl on April 29, 2007, 08:47:09 AM
I want to sort smallest to largest and largest to smallest based on the user clicking the listview header. I know there is an example in the masm folder but it does not work with commas in the listview items and for some reason it still does not work when i strip the commas before the ascii2base
Title: Re: Listview sorting.
Post by: ic2 on April 29, 2007, 10:00:59 AM
jckl, your copy of Masm32 has Ewayne Listview Example in it.    Have you seen it.   He covered sorting too and it has some kind of BASE functions that may give you some ideas ...
Title: Re: Listview sorting.
Post by: jckl on April 29, 2007, 10:22:45 AM
correct his example is the one i went to and actually tried his code. It does not work if the numbers have commas as i display the commas.
Title: Re: Listview sorting.
Post by: zooba on April 29, 2007, 10:27:25 AM
I made this work in VB by creating two columns. One is displayed to the user (in my case in the local currency format), the other has a width of zero and has the number/value in a sortable format (for example, 00000000.00). Then when the user clicks on a column header, I checked if it was the currency one and if it was I'd set the sort column to the hidden one.

Worked fine unless the user dragged the hidden one open. Possibly there is a better way of doing the same thing, but this was good enough for my needs.

Cheers,

Zooba :U
Title: Re: Listview sorting.
Post by: MichaelW on April 29, 2007, 10:35:53 AM
jckl,

I'm still not sure what sort of results you are expecting. Assuming the strings are of a uniform length, and right justified with leading spaces, a string sort will put the strings in order alphabetically and numerically, without any need to eliminate the commas or convert to a number.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      sarr dd s1,s2,s3,s4,s5,s6,s7,s8,s9
      s1   db "    1,120",0
      s2   db "1,210,023",0
      s3   db "  121,100",0
      s4   db "1,222,012",0
      s5   db "1,310,120",0
      s6   db "   19,300",0
      s7   db "    2,230",0
      s8   db "      240",0
      s9   db "      240",0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    print "smallest to largest",13,10
    invoke assort, ADDR sarr, 9, 0
    xor ebx, ebx
    .WHILE ebx < 9
      mov eax, [sarr+ebx*4]
      print eax,13,10
      inc ebx
    .ENDW

    print "largest to smallest",13,10
    invoke dssort, ADDR sarr, 9, 0
    xor ebx, ebx
    .WHILE ebx < 9
      mov eax, [sarr+ebx*4]
      print eax,13,10
      inc ebx
    .ENDW

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


smallest to largest
      240
      240
    1,120
    2,230
   19,300
  121,100
1,210,023
1,222,012
1,310,120
largest to smallest
1,310,120
1,222,012
1,210,023
  121,100
   19,300
    2,230
    1,120
      240
      240
Title: Re: Listview sorting.
Post by: jckl on April 29, 2007, 10:44:42 AM
Those are the results i am looking for. Now to try and get that to work with my listview
Title: Re: Listview sorting.
Post by: zooba on April 29, 2007, 09:31:32 PM
I think that the strings haven't been right justified, that will have been the column setting in the list-view.

Right justifying with spaces won't look nice in a proportional font, though if the column format is still right-justified it may not be noticeable.

Cheers,

Zooba :U
Title: Re: Listview sorting.
Post by: jckl on April 29, 2007, 09:49:22 PM

    invoke SendMessage,hList, LVM_INSERTCOLUMN, 0, addr lvc
    or lvc.imask,LVCF_TEXT+LVCF_FMT
    mov lvc.fmt,LVCFMT_RIGHT
    mov lvc.pszText,offset Heading2
    mov lvc.lx,75


My column is right justifyed. Like i siad i can get it to sort the numbers if there is no comma but with the comma it causes the sorting to be wrong.
Title: Re: Listview sorting.
Post by: zooba on April 30, 2007, 08:58:44 AM
The comma should not be causing any problem with sorting since it appears in the same location in each number. The problem is either converting the string up to the first comma into a number, or treating numbers as strings.

The solution to the first one is not to stop converting when you hit a comma. If you're using a library function to do the conversion you'll probably need to modify it or find another one.

The solution to the second one is to make sure that each string is the same length by padding the start of it with spaces, as MichaelW has assumed is going on here already. Simply setting LVCFMT_RIGHT doesn't do this. When all strings are the same length with padding at the start the commas are irrelevant, since they will all be at the same offsets into each string. Two things to make sure of are that you select a field width which will be bigger than all the numbers you display and you select a padding character that sorts lower than a number (I've never come across a system where a space won't work for this).

Cheers,

Zooba :U
Title: Re: Listview sorting.
Post by: sinsi on April 30, 2007, 09:19:54 AM
When you add an item to the listview, can't you use LVITEM.lParam to store the value?
Quote
lParam
Value specific to the item. If you use the LVM_SORTITEMS message, the list-view control passes this value to the application-defined comparison function. You can also use the LVM_FINDITEM message to search a list-view control for an item with a specified lParam value.
The only trouble I can see here is if your value is more than 32 bits.
Title: Re: Listview sorting.
Post by: zooba on April 30, 2007, 09:26:23 AM
Much better solution, go with that.

If your numbers are bigger than 32-bits, use it as a 32-bit float or a pointer to a 64-bit integer/float, depending on what's appropriate.

Cheers,

Zooba :U
Title: Re: Listview sorting.
Post by: jckl on April 30, 2007, 09:33:56 PM
ok i understand what you mean to pad the string with zeros and it makes sense to me now why it does not work when i compare as a string. I will give both the ideas a try and i think the lParam idea is better since i wont have to worry about files that may be larger than my padding allows.
Title: Re: Listview sorting.
Post by: jckl on April 30, 2007, 10:36:57 PM
well i couldnt figure out how to get the lParam option to work but i wrote a function that adds "0"s to the beginning and then i use my function to strip the commas and compare them as a string and it works perfect now. Thanks for the help as always :D