1. Sorting and listviews
- Posted by Tony Steward <figjam at nlc.net.au> Jul 13, 2001
- 378 views
Hi All, Two things. Firstly is it possible to use your own sort routine when you click a column header in a listview. Secondly has anyone written a sort routine they would like to share. My problem is as follows: N1-1-1 N1-1-10 N1-1-2 N1-1-3 This is a typical numbering system used in master key systems and I would rather have them display in a listview as follows: N1-1-1 N1-1-2 N1-1-3 N1-1-10 The default sort routine looks very unprofessional, and as I use the lists to set the order of reports it is even more un professional. Thanks Tony Steward Come Visit Me At www.locksdownunder.com
2. Re: Sorting and listviews
- Posted by euman at bellsouth.net Jul 13, 2001
- 406 views
-- tagNMHDR NMHDR_hwndFrom = 0, NMHDR_idFrom = 4, NMHDR_code = 8, SIZEOF_NMHDR = 12 elsif iMsg = WM_NOTIFY then -- call_back iMsg = peek4s(lParam + NMHDR_code) if iMsg = LVN_COLUMNCLICK then -- could run a sort routine here elsif iMsg = NM_CLICK then end if return 0 Look into the Microsoft Platform SDK for listview LVN_COLUMNCLICK is the iMsg returned by the listview control when a header button is clicked. NM_CLICK is in the data area of the listview. I looked at Matts code in Win32lib and it isnt set up like this but this should give you an idea as where to start looking. I just finished writting my wrapper to the listview in streamlined API and it was really fun because the SDK is kindof confuseing. set your trace at WM_NOTIFY under LVN_COLUMNCLICK also, there is a flag that tells Windows to autosort the LV but am not sure where that is in win32lib but you'll need to remove this. look below for a very simple listview wrapper thats incomplete compared to win32lib but does the job I modified it some to show you how it might work. constant LVS_REPORT = 1, LVS_SHOWSELALWAYS = 8, LVIF_TEXT = 1, LVCF_FMT = 1, LVCF_WIDTH = 2, LVCF_TEXT = 4, LVCF_SUBITEM = 8, LVCF_ORDER = 20, LVCFMT_LEFT = 0, LVM_INSERTCOLUMN = 4123, LVS_SHAREIMAGELISTS = 40, LVM_SETITEM = 4102, LVM_INSERTITEM = 4103, LVM_SETBKCOLOR = 4097, LVM_SETTEXTBKCOLOR = 4134, LVM_SETTEXTCOLOR = 4132, LVM_SETEXTENDEDLISTVIEWSTYLE = 4150, LVS_EX_GRIDLINES = 1, LVS_EX_TRACKSELECT = 8, LVS_EX_HEADERDRAGDROP = 10, LVS_EX_FULLROWSELECT = 20, LVS_EX_ONECLICKACTIVATE = 40 constant lvcol_mask = 0, lvcol_fmt = 4, lvcol_cx = 8, lvcol_pszText = 12, lvcol_cchTextMax = 16, lvcol_iSubItem = 20, lvcol_iOrder = 24, sizeof_lvcol = 28 constant lvitem_mask = 0, lvitem_iItem = 4, lvitem_iSubItem = 8, lvitem_state = 12, lvitem_stateMask = 16, lvitem_pszText = 20, lvitem_cchTextMax = 24, lvitem_iImage = 28, lvitem_lParam = 32, lvitem_iIdent = 36, sizeof_lvitem = 40 global constant LVN_COLUMNCLICK = -108, NM_CLICK = -2 sequence data data = {{"Ringo","Starr"}, {"George","Harrison"}, {"Paul","McCartney"}, {"John","Lennon"} } procedure ListView_Column(atom id, atom lvcol, sequence text, integer item, integer width ) atom itxt, junk itxt = allocate_string(text) poke4( lvcol + lvcol_cx, width) poke4( lvcol + lvcol_pszText, itxt ) poke4( lvcol + lvcol_iSubItem, item ) junk = c_func(SendMessage,{id, LVM_INSERTCOLUMN, 0, lvcol}) end procedure global atom ListView1, lvcol global procedure MakeListView(atom hwnd, atom hInst, integer x1, integer y1, integer x2, integer y2) atom szName, szName2, item, seq, lvMask object junk lvMask = or_all({LVS_EX_FULLROWSELECT,LVS_EX_HEADERDRAGDROP,LVS_EX_GRIDLINES,LVS_EX_ONECL ICKACTIVATE, LVS_EX_TRACKSELECT }) szName = allocate_string("SysListView32") szName2 = allocate_string("ListView1") ListView1 = c_func(CreateWindow,{WS_EX_CLIENTEDGE, szName, szName2, or_all({WS_CHILD, WS_TABSTOP, WS_VISIBLE, #241, WS_BORDER, LVS_REPORT --LVS_SHOWSELALWAYS }), x1, y1, x2, y2, hwnd, 0, hInst, NULL}) free(szName) free(szName) junk = c_func(SendMessage,{ListView1, LVM_SETEXTENDEDLISTVIEWSTYLE, lvMask, lvMask}) junk = c_func(SendMessage,{ListView1,LVM_SETBKCOLOR, 0, 16744576}) junk = c_func(SendMessage,{ListView1,LVM_SETTEXTBKCOLOR, 0, 16744576}) junk = c_func(SendMessage,{ListView1,LVM_SETTEXTCOLOR, 0, 16777088}) junk = c_func(SendMessage,{ListView1,WM_SETREDRAW,0,0}) lvcol = allocate_struct(sizeof_lvcol) poke4( lvcol + lvcol_mask, or_all({LVCF_FMT, LVCF_SUBITEM, LVCF_TEXT, LVCF_WIDTH})) poke4( lvcol + lvcol_fmt, LVCFMT_LEFT) ListView_Column(ListView1, lvcol, "7", 7, 33 ) ListView_Column(ListView1, lvcol, "6", 6, 33 ) ListView_Column(ListView1, lvcol, "5", 5, 33 ) ListView_Column(ListView1, lvcol, "4", 4, 33 ) ListView_Column(ListView1, lvcol, "3", 3, 33 ) ListView_Column(ListView1, lvcol, "2", 2, 33 ) ListView_Column(ListView1, lvcol, "1", 1, 98 ) ListView_Column(ListView1, lvcol, "Date", 0, 100 ) item = allocate_struct(sizeof_lvitem) poke4( item + lvitem_mask, LVIF_TEXT ) for i = 1 to length(data) do seq = allocate_string(data[i][1]) poke4( item + lvitem_pszText, seq) poke4( item + lvitem_iItem,0) poke4( item + lvitem_iSubItem, 0) junk = c_func(SendMessage,{ListView1, LVM_INSERTITEM, 0, item }) seq = allocate_string(data[i][2]) poke4( item + lvitem_pszText, seq) poke4( item + lvitem_iItem,0) poke4( item + lvitem_iSubItem, 1) junk = c_func(SendMessage,{ListView1, LVM_SETITEM, 0, item }) -- etc....etc end for free(seq) junk = c_func(SendMessage,{ListView1,WM_SETFONT,c_func(GetStockObject,{DEFAULT_GUI_FONT }),0}) junk = c_func(SendMessage,{ListView1,WM_SETREDRAW,1,0}) end procedure Hope this helps some! Euman euman at bellsouth.net > > Hi All, > Two things. > Firstly is it possible to use your own sort routine when you click a column > header in a listview. > > Secondly has anyone written a sort routine they would like to share. My > problem is as follows: > N1-1-1 > N1-1-10 > N1-1-2 > N1-1-3 > > This is a typical numbering system used in master key systems and I would > rather have them display in a listview as follows: > N1-1-1 > N1-1-2 > N1-1-3 > N1-1-10 > > The default sort routine looks very unprofessional, and as I use the lists > to set the order of reports it is even more un professional. > > Thanks > Tony Steward > > Come Visit Me At www.locksdownunder.com
3. Re: Sorting and listviews
- Posted by Derek Parnell <ddparnell at bigpond.com> Jul 13, 2001
- 371 views
----- Original Message ----- From: "Tony Steward" <figjam at nlc.net.au> To: "EUforum" <EUforum at topica.com> Subject: Sorting and listviews > Two things. > Firstly is it possible to use your own sort routine when you click a column > header in a listview. Hi Tony, if you make the changes I've got below to win32lib.ew, you will be able to use your own sort routine. You need to replace the existing function called "lvSortitems" in the library with the code below... ---Start New Code--------- global integer lvSortRoutine function local_lvsortrtn(integer id, integer col, integer direction, sequence a, sequence b) return( compare(a, b) * direction ) end function lvSortRoutine = routine_id("local_lvsortrtn") function lvSortitems( atom lParam1, atom lParam2, atom owner ) integer sign, lv lv = lv_allowsort[owner] if lv < 0 then sign = -1 lv = - lv else sign = 1 end if return call_func(lvSortRoutine,{lv_id[owner], lv, sign, peek_string(lvitem_data[lParam1][2][lv][1] ), peek_string(lvitem_data[lParam2][2][lv][1] ) }) end function ---End New Code--------- then in your program you need to create a sort function that takes five parameters. 1) The integer ID of the listview control requesting the sort. 2) The integer column number that was clicked. 3) The integer direction to sort in. -1 means Largest to Smallest, 1 means Smallest to Largest. 4) A sequence value (string) from the column the user clicked. 5) Another sequence value (string) from the same column. Your function must return an integer. 0 ==> When values are equal. 1 ==> When first string should go after the second. -1 ==> When first string should go before the second. Next, set the global variable "lvSortRoutine" with the routine_id() of your sorting function. And that's it. > Secondly has anyone written a sort routine they would like to share. My > problem is as follows: > N1-1-1 > N1-1-10 > N1-1-2 > N1-1-3 > > This is a typical numbering system used in master key systems and I would > rather have them display in a listview as follows: > N1-1-1 > N1-1-2 > N1-1-3 > N1-1-10 > For your specific situation you could try something like this ... -- Custom Sort Routine -- function expand_key(sequence key) atom val sequence newkey, elem integer digit -- Initialize newkey = {} elem = {} val = -1 -- Inspect each character for i = 1 to length(key) do -- Test for digit. digit = find(key[i], "0123456789") - 1 -- Is this a digit? if digit < 0 then -- No. Am I collecting non-digits? if val < 0 then -- Yes. Add it to current element. elem &= key[i] else -- No. Append current number. newkey &= {{val}} -- Indicate that I'm now collecting non-digits val = -1 -- Init current element to this char. elem = {key[i]} end if else -- Yes. Am I collecting digits? if val < 0 then -- No. Append uppercase version of current element. newkey &= {upper(elem)} -- reset current element. elem = {} -- indicate that I'm now collecting digits and -- get first digit. val = digit else -- Yes. Convert digit to number val = (val * 10) + digit end if end if end for -- Don't forget to append the last token. if val < 0 then newkey &= {upper(elem)} else newkey &= {{val}} end if -- Send back the expanded key. return newkey end function integer stdsort function SortKeyNumbers(integer id, integer colm, integer direction, sequence KeyA, sequence KeyB ) sequence lExpandedKeyA, lExpandedKeyB -- If this is not the right listview or column -- use the original sorting routine. if id != myLV or colm != myColumn then return call_func(stdsort, {id, direction, KeyA, KeyB}) end if -- Convert the key 'numbers' into expanded form. lExpandedKeyA = expand_key(KeyA) lExpandedKeyB = expand_key(KeyB) return (compare(lExpandedKeyA, lExpandedKeyB) * direction) end function -- Save original sorting routine. stdsort = lvSortRoutine -- Insert my custom routine. lvSortRoutine = routine_id("SortKeyNumbers") -- End of Custom Sort Routine -- --------------- Good luck, Derek
4. Re: Sorting and listviews
- Posted by Igor Kachan <kinz at peterlink.ru> Jul 13, 2001
- 383 views
Hi Tony, > Secondly has anyone written a sort routine they would like to share. > My problem is as follows: > N1-1-1 > N1-1-10 > N1-1-2 > N1-1-3 > > This is a typical numbering system used in master > key systems and I would > rather have them display in a listview as follows: > N1-1-1 > N1-1-2 > N1-1-3 > N1-1-10 > > The default sort routine looks very unprofessional, > and as I use the lists > to set the order of reports it is even more un professional. The possible solution is : N1-1-01 N1-1-10 N1-1-02 N1-1-03 Then standard RDS include sort.e and sort() works as you wish, i.e. N1-1-01 N1-1-02 N1-1-03 N1-1-10 Same about DOS's sort command. Maybe, this helps too. Regards, Igor Kachan kinz at peterlink.ru
5. Re: Sorting and listviews
- Posted by gertie at ad-tek.net Jul 13, 2001
- 362 views
On 13 Jul 2001, at 22:17, Igor Kachan wrote: > > Hi Tony, > > > Secondly has anyone written a sort routine they would like to share. > My > problem is as follows: > > N1-1-1 > > N1-1-10 > > N1-1-2 > > N1-1-3 > > > > This is a typical numbering system used in master > > key systems and I would > > rather have them display in a listview as follows: > > N1-1-1 > > N1-1-2 > > N1-1-3 > > N1-1-10 > > > > The default sort routine looks very unprofessional, > > and as I use the lists > > to set the order of reports it is even more un professional. > > > The possible solution is : > > N1-1-01 > N1-1-10 > N1-1-02 > N1-1-03 > > Then standard RDS include sort.e > and sort() works as you wish, i.e. > > N1-1-01 > N1-1-02 > N1-1-03 > N1-1-10 Great minds think alike, eh, Igor? I was just coding that solution too! The code to do this would be sort of like: -- Sort a list -- Kat -- July 13, 2001 with trace include sort.e include get.e include strtok.e - you might haveto make parse() and deparse() global atom key sequence list, parsedlist -- set list to something, so we can sort it list = { "N1-1-1", "N1-1-10", "N1-1-2", "N1-1-3", "N3-1-10", "N3-4-2", "N21-5-9" } puts(1,"starting with:\n") for loop = 1 to length(list) do puts(1,list[loop]&"\n") end for puts(1,"\n\n") for loop = 1 to length(list) do parsedlist = parse(list[loop],'-') for loop2 = 1 to length(parsedlist) do while length(parsedlist[loop2]) < 5 do -- 5 is a rather random number parsedlist[loop2] = "0" & parsedlist[loop2] end while end for list[loop] = deparse(parsedlist,'-') end for list = sort(list) for loop = 1 to length(list) do parsedlist = parse(list[loop],'-') for loop2 = 1 to length(parsedlist) do while equal('0',parsedlist[loop2][1]) do parsedlist[loop2] = parsedlist[loop2][2..length(parsedlist[loop2])] end while end for list[loop] = deparse(parsedlist,'-') end for for loop = 1 to length(list) do puts(1,list[loop]&"\n") end for puts(1,"\n\nall done, press something to close out\n\n") key = wait_key() Kat
6. Re: Sorting and listviews
- Posted by irvm at ellijay.com Jul 13, 2001
- 375 views
On Friday 13 July 2001 05:25, Tony Steward wrote: > Secondly has anyone written a sort routine they would like to share. My > problem is as follows: > N1-1-1 > N1-1-10 > N1-1-2 > N1-1-3 > > This is a typical numbering system used in master key systems and I would > rather have them display in a listview as follows: > N1-1-1 > N1-1-2 > N1-1-3 > N1-1-10 > > The default sort routine looks very unprofessional, and as I use the lists > to set the order of reports it is even more un professional. > > Thanks > Tony Steward Here's a way that works by converting the array into numbers, sorting, then converting back to strings for display. If you've got a mix of numeric and non-numerics, ("N1-1-10A") then it won't without some serious modifications. include sort.e include get.e include strtok.e sequence s, sn object v s = {"N1-1-1","N1-1-10","N1-1-3","N1-1-2"} sn = s -- save into temporary new array for i = 1 to length(sn) do sn[i] = parse(sn[i],'-') -- parse into numbers v = value(sn[i][2]) -- convert to numeric sn[i][2] = v[2] v = value(sn[i][3]) sn[i][3] = v[2] ? sn[i] end for puts(1,"Sorted\n") sn = sort(sn) for i = 1 to length(sn) do -- change 'em back to strings printf(1,"%s-%d-%d\n",{sn[i][1],sn[i][2],sn[i][3]}) end for
7. Re: Sorting and listviews
- Posted by gertie at ad-tek.net Jul 13, 2001
- 380 views
On 13 Jul 2001, at 21:03, irvm at ellijay.com wrote: > > On Friday 13 July 2001 05:25, Tony Steward wrote: > > > Secondly has anyone written a sort routine they would like to share. My > > problem is as follows: > > N1-1-1 > > N1-1-10 > > N1-1-2 > > N1-1-3 > > > > This is a typical numbering system used in master key systems and I would > > rather have them display in a listview as follows: > > N1-1-1 > > N1-1-2 > > N1-1-3 > > N1-1-10 > > > > The default sort routine looks very unprofessional, and as I use the lists > > to set the order of reports it is even more un professional. > > > > Thanks > > Tony Steward > > Here's a way that works by converting the array into numbers, sorting, then > converting back to strings for display. If you've got a mix of numeric and > non-numerics, ("N1-1-10A") then it won't without some serious modifications. <snip> -- copy/pasted from screen: starting with: N1-1-1 N21-5-9 N1-1-10 N1-1-2 N1-1-3 B6-3-65 X32-6ba-2 X32-6a2-2 X32-6a-2 N3-1-10 N3-4-2 B6-3-65a press something to sort it B6-3-65 B6-3-65a N1-1-1 N1-1-2 N1-1-3 N1-1-10 N3-1-10 N3-4-2 N21-5-9 X32-6a-2 X32-6a2-2 X32-6ba-2 all done, press something to close out -- Sort a list -- Kat -- July 13, 2001 with trace include sort.e include get.e include strtok.e atom key sequence list, parsedlist -- set list to something, so we can sort it list = { "N1-1-1", "N21-5-9", "N1-1-10", "N1-1-2", "N1-1-3", "B6-3-65", "X32-6ba-2", "X32-6a2-2", "X32-6a-2", "N3-1-10", "N3-4-2", "B6-3-65a" } puts(1,"starting with:\n") for loop = 1 to length(list) do puts(1,list[loop]&"\n") end for puts(1,"\n\npress something to sort it\n\n") key = wait_key() for loop = 1 to length(list) do parsedlist = parse(list[loop],'-') for loop2 = 1 to length(parsedlist) do while length(parsedlist[loop2]) < 5 do parsedlist[loop2] = "0" & parsedlist[loop2] end while end for list[loop] = deparse(parsedlist,'-') end for list = sort(list) for loop = 1 to length(list) do parsedlist = parse(list[loop],'-') for loop2 = 1 to length(parsedlist) do while equal('0',parsedlist[loop2][1]) do parsedlist[loop2] = parsedlist[loop2][2..length(parsedlist[loop2])] end while end for list[loop] = deparse(parsedlist,'-') end for for loop = 1 to length(list) do puts(1,list[loop]&"\n") end for puts(1,"\n\nall done, press something to close out\n\n") key = wait_key()