A friendly reminder...

Please be sure that you are familiar with the forum rules and guidelines. These are in place to try to maintain a place that we all want to come back to. One specifically I would like to mention is keeping threads on topic. As much as is possible, please do not be afraid to start a new thread if you have a question that shifts even just a little bit in meaning. This will help users searching for solutions, and this will also help a conversation not become confusing to follow.
See more
See less

Virtual listview example

  • Filter
  • Time
  • Show
Clear All
new posts

  • Virtual listview example

    in my search for information on virtual listview's i found this very usefull link from pedro ramirez:

    in order to learn the basics of the listview function i stripped the code down so it only shows a simple 4 column virtual listview.

    but i still have one problem i can't figure out.
    in the line's below i have to add the "+2" at the end of the second line, if i don't do this the first two columns of my listview are empty.

    if (@plvdi.item.mask and %lvif_text) then
      szname = parse$(lvfiles(@plvdi.item.iitem), $tab, @plvdi.item.isubitem +2)
      @plvdi.item.psztext = varptr(szname)
    end if

    here is the complete code:
    #compile exe
    #dim all
    #include ""
    #include ""
    ' virtual listview id
    %idc_virtuallistview = 2000
    global lvfiles()      as string  ' declare a global array to hold the virtual listview data
    global hctl           as long    ' global variable to hold the virtual listview control handle
    global lrowcnt        as long    ' holds the total rows in the listview
    global lcolcnt        as long    ' holds the total columns in the listview
    declare callback function showvirtuallvproc()
    declare function virtuallistview(byval hdlg as dword, byval lid as long) as long
    function pbmain()
         local lresult as long
         local hdlg    as dword
         dialog new  %hwnd_desktop, "simple virtual listview with state images", 70, 70,  405, 156, %ws_popup or %ws_border or %ws_dlgframe or %ws_sysmenu or _
              %ws_clipsiblings or %ws_visible or %ds_modalframe or %ds_3dlook or _
               %ds_nofailcreate or %ds_setfont, %ws_ex_windowedge or _
                 %ws_ex_controlparent or %ws_ex_left or %ws_ex_ltrreading or _
               %ws_ex_rightscrollbar, to hdlg
         ' create a virtual listview control (add the %lvs_ownerdata style)
         control add "syslistview32", hdlg, %idc_virtuallistview, "syslistview32_1", _
               2, 2, 301, 152, %ws_child or %ws_visible or %ws_border or %lvs_report _
                or %lvs_showselalways or %lvs_ownerdata, %ws_ex_left or _
                 %ws_ex_rightscrollbar or %ws_ex_clientedge or %ws_ex_staticedge
         ' prepare the virtual list elements
         virtuallistview hdlg, %idc_virtuallistview
         ' show it
         dialog show modal hdlg, call showvirtuallvproc to lresult
         function = lresult
    end function
    function virtuallistview(byval hdlg as dword, byval lid as long) as long
         local lcol    as long
         local lrow    as long
         local tlvc    as lv_column
         local szbuf   as asciiz * 50
         local lstyle  as long
         dim   lrowcnt as global long
         dim   lcolcnt as global long
         local temp()  as string
         lcolcnt = 4    : ' # of columns in virtual listview
         lrowcnt = 50000   : ' # or rows in virtual listview
         dim temp(lcolcnt)         as local string
         dim lvfiles(lrowcnt - 1)      as global string
         ' store the virtual listview handle in the global variable
         control handle hdlg, lid to hctl
         ' tell the virtual listview control the total items (rows) to show (contained in lvfiles()).
         listview_setitemcount hctl, lrowcnt
         lstyle = listview_getextendedlistviewstyle(hctl)
         listview_setextendedlistviewstyle hctl, lstyle or %lvs_ex_fullrowselect or _
                 %lvs_ex_gridlines or %lvs_ex_checkboxes or %lvs_ex_headerdragdrop
         ' set the column headers
         tlvc.psztext = varptr(szbuf)
         tlvc.mask    = %lvcf_text or %lvcf_fmt or %lvcf_subitem or %lvcf_width      = 100  : ' here we set the width for all columns
         for lcol = 1 to lcolcnt
              szbuf       = using$("column #", lcol)
              tlvc.iorder = lcol
              listview_insertcolumn hctl, lcol, tlvc
         next lcol
         for lrow = 0 to lrowcnt - 1
              for lcol = 1 to lcolcnt
                   temp(lcol) = using$("column #, row #", lcol, lrow)
              lvfiles (lrow) = join$ (temp(), $tab)
         ' set focus on virtual list view
         control set focus hdlg,%idc_virtuallistview
    end function
    callback function showvirtuallvproc()
        local pnmlv      as nm_listview ptr
        local plvdi      as lv_dispinfo ptr
        local szname     as asciiz * 50
         select case as long cbmsg
              case %wm_command
                   ' process control notifications
                   select case as long cbctl
                        case %idcancel       ' esc key  of dialog
                             dialog end cbhndl
                        case %idc_virtuallistview
                   end select
              case %wm_notify
                        if lowrd(cbwparam) = %idc_virtuallistview then
                            ' obtain the nm_listview pointer from cblparam
                            pnmlv = cblparam
                            select case @pnmlv.hdr.code
                                    case %lvn_getdispinfo
                                            ' obtain the lv_dispinfo pointer from cblparam
                                            plvdi = cblparam
                                           'virtual listview asks for item text
                                            if (@plvdi.item.mask and %lvif_text) then
                                                szname = parse$(lvfiles(@plvdi.item.iitem), $tab, @plvdi.item.isubitem+2)
                                                @plvdi.item.psztext = varptr(szname)
                                            end if
                             end select
                         end if
         end select
    end function


    [this message has been edited by julian van der vaart (edited october 27, 2005).]

  • #2
    Please use code tags so your listing is more readable and thus get a quicker response.

    Rick Angell
    Rick Angell


    • #3
      If you don't copy the text to the pszText member of lvdi (you are not copying the text, you are supplying your own buffer), that buffer must remain valid for at least two more LVN_GETDISPINFO calls.

      Because your szName variable is LOCAL, it is invalid as soon as you exit the procedure.

      Should work if you either...

      - Change szName to a STATIC var
      - Copy the text to the supplied buffer (@[email protected] = szName). In this case you 'should' test that the buffer supplied by the control is of sufficient length.

      Belay that. Since you have multiple columns, making szName a STATIC won't work, because you'll be getting multiple LVN_GETDISPINFO per row and you'll probably end up with the text in column 2 being what should be in column 4 or column 0 or something like that.

      If you want to supply your own buffer, create a STATIC array szName(max_col_no) and deposit the text in the element number corresponding to the column (subitem)


      [This message has been edited by Michael Mattias (edited October 27, 2005).]
      Michael Mattias
      Tal Systems Inc.
      Racine WI USA
      [email protected]


      • #4
        Hi Rick, thanks for the tip for using the function on this forum.

        I think i found the problem('s).

        Problem part 1.
        The line below, which is located near the bottom of the 'VirtualListView' function, joins the data out of an array into a string sperating it by TAB$.
        The problem is that it also ads a $TAB in front of the string, and not just in between the values of the array.
        LvFiles (lRow) = JOIN$ (Temp(), $TAB)

        Problem part 2.
        The PARSE$ function in the line below uses the index number from @pLVDI.item.iSubItem, the problem is that @pLVDI.item.iSubItem ranges from 0 to 3 instead of 1 to 4.
        szName = PARSE$(LvFiles(@pLVDI.item.iItem), $TAB, @pLVDI.item.iSubItem+2)

        When you add these problems you can see that the PARSE$ fucntion's index number is of by 2 numbers, that's why i need to add 2.

        It is very important for me that this script is as fast as possible, the program in which it will be used can be up to 500,000 rows big.


        [This message has been edited by Julian van der Vaart (edited October 27, 2005).]


        • #5
          julian, i´m glad the thread was of help.

          i´m using virtual listviews to handle 4000 to 5000 rows. it´s a
          you shouldn´t have any trouble with 500.000 or a million because of
          the way a virtual listview is designed to work.

          as you may have realized the virtual listview requests only the
          data it needs to show. that´s what makes it fast and suited to
          work with large amounts of data.

          you should, however, maintain and manipulate the data yourself
          outside the virtual listview. in the example the data is stored
          in a string array in memory and the virtual listview is given
          whatenever it needs to show about it.

          the trick to fast handling the amount of data you mentioned is
          not in the listview itself but in the way you perform chosen tasks
          on your data.

          i cannot help you in that department but i can recommend you to
          download the programs and files of the programming contest at
          take a look at the code contributed by paul dixon. it´s amazingly
          fast!!!. it also shows a deep understanding of low level programing
          which allows for these fast speeds when handling data.


          [this message has been edited by pedro ramirez (edited october 27, 2005).]


          • #6
            Pedro's corrected link.