Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Virtual Listview Control

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Virtual Listview Control

    Code:
    ' virtual listbox.bas
    ' 06-08-2004
    
    ' written by: pedro ramirez
    
    ' this program is intended as a guide to show the use and handling of a virtual listview control.
    
    ' it shows the use of checkboxes, sorting and trapping of keys and mouse clicks and how to use
    ' a virtual listview. i think this is a sample as complete and simple as it can get before
    ' digging down further into the workings of a listview control. i have made some commercial apps
    ' using this code as guide entirely.
    
    ' to build this program took many, many, many days of researching through the forums, asking for
    ' help and browsing both the win32 help and the msdn library. i hope those of you who are just
    ' getting to know the listview control can benefit from it.
    
    ' this sample utilizes the checboxes built inside the listbox. if you want to add/or change the image
    ' you can find the needed code where it all started:
    ' http://www.powerbasic.com/support/pb...ad.php?t=10343 
    
    ' this sample is public domain
    
    
    #compile exe
    #dim all
    #include "win32api.inc"
    #include "commctrl.inc"
    
    
      ' 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 lvfilescheck() as long    ' array to keep track of checked and unchecked checkboxes
      global glvsort        as long    ' variable used to keep track of the direction of sorting
      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
      declare function showvirtuallv(byval hparent as dword) as long
      declare sub sortcolumn(byval clmn as long)
    
    
    ' program entry point
    function pbmain()
    
    
         local lresult as long
         local hdlg    as dword
    
    
         dialog new  %hwnd_desktop, "simple virtual listview with state images", 70, 70, _
              205, 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, 201, 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 tlvi    as lv_item
         local szbuf   as asciiz * 50
         local lstyle  as long
         dim   lrowcnt as global long
         dim   lcolcnt as global long
         local temp()  as string
    
    
         lcolcnt = 5    : ' # of columns in virtual listview
         lrowcnt = 20   : ' # or rows in virtual listview
    
    
         ' we'll use a temp() array to store the elements of each row and them join then into
         ' the lvfiles() array which holds the virtual listview data.
    
    
         dim temp(lcolcnt - 1)         as local string
         dim lvfiles(lrowcnt - 1)      as global string
         dim lvfilescheck(lrowcnt - 1) as global long
    
    
         ' 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)
    
    
         '***********************************
         '  first step - %lvs_ex_checkboxes
         '***********************************
         ' to use state images we must add %lvs_ex_checkboxes to the listview style. this tells
         ' the listview control to allocate space for the image in the first colummn.
    
    
         listview_setextendedlistviewstyle hctl, lstyle or %lvs_ex_fullrowselect or _
              %lvs_ex_gridlines or %lvs_ex_checkboxes or %lvs_ex_headerdragdrop
    
    
         ' load column headers.
         ' lvcf_width allows adjustment of column width
    
    
         ' first we set the first column which holds the checkboxes
         tlvc.mask    = %lvcf_width
         tlvc.fmt     = %lvcfmt_left
         tlvc.psztext = varptr(szbuf)
    
    
         ' column 0 - we only want show the checkboxes here.
    
    
         szbuf        = "  : ' nothing, nada, empty, vacio, void
         tlvc.cx      = 19  : ' here we set the width for the first column (column 0)
         tlvc.iorder  = 0
         listview_insertcolumn hctl, 0, tlvc
    
         ' and now the rest of the column headers
         tlvc.mask    = %lvcf_text or %lvcf_fmt or %lvcf_subitem or %lvcf_width
         tlvc.cx      = 100  : ' here we set the width for all columns
    
    
         for lcol = 1 to lcolcnt - 1
              szbuf       = using$("column #", lcol)
              tlvc.iorder = lcol
              listview_insertcolumn hctl, lcol, tlvc
         next lcol
    
    
         ' prepare sample data for virtual listview
         ' from row 0, column 1 on
         ' this data will be read by the virtual listview through the %lvn_getdispinfo message
         ' trap in the dialog callback
    
    
         for lrow = 0 to lrowcnt - 1
              for lcol = 1 to lcolcnt - 1
                   temp(lcol) = using$("column #, row #", lcol, lrow)
              next
              lvfiles (lrow) = join$ (temp(), $tab)
         next
    
    
         ' set the first row as selected
         listview_setitemstate (hctl,0,%lvis_selected or %lvis_focused,%lvis_selected or %lvis_focused)
    
    
         ' 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
        local keydown    as lv_keydown ptr
        local checkstate as long
        local scelltext  as asciiz * 50
        local n          as long
    
         select case as long cbmsg
    
    
              case %wm_command
    
    
                   ' process control notifications
                   select case as long cbctl
    
    
                        ' trapping the enter key (%idok)
    
    
                        ' generic
                        ' this is not the enter key but the ok button of the dialog
                        ' (showed for educational purposes)
    
    
                        'case %idok           ' enter key
                        '    msgbox "you pressed enter (%idok of dialog control)"
    
    
                        ' we can be more specific by identifying that it was the listview control
                        ' default ok button
                        ' this is the best alternative i´ve found so far. there may be a better one
                        ' but may involve subclassing. this will only respond when the user has the
                        ' focus on the listview and it actually hits the enter key when a item is
                        ' selected.
    
    
                        case %idok
    
    
                             ' hctl is the virtual listview control handle for this program
                             ' test if the listview has the focus
                             if getfocus = hctl then
    
    
                        '          msgbox "you pressed enter (%idok of listview control)"
    
    
                                  ' to get the item:  (and toggle its corresponding checkbox)
                                  ' to actually toggle checkbox states we trap the space bar under
                                  ' %lvn_keydown below. this is shown to demostrate that the trapping
                                  ' of the enter key works as expected.
                                  n = listview_getnextitem(byval hctl, -1, %lvni_selected)
                                  lvfilescheck(n) = (lvfilescheck(n) = 0)
                                  invalidaterect hctl, byval %null, 0
                                  updatewindow hctl
                             end if
    
    
                        case %idcancel       ' esc key  of dialog
    
    
                            dialog end cbhndl
    
                        case %idc_virtuallistview
                            ' pbforms puts this message trap here. i have not needed to figure it
                            ' out (yet).
    
    
                   end select
    
              case %wm_notify
    
    
                ' the wm_notify message informs the parent window of a control that an event has
                ' occurred in the control or that the control requires some kind of information.
    
    
                ' handle listview notifications only
    
    
                        if lowrd(cbwparam) <> %idc_virtuallistview then exit select
    
    
                        ' obtain the nm_listview pointer from cblparam
                        pnmlv = cblparam
    
    
                        ' obtain the lv_keydown pointer from cblparam
                        keydown = 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 + 1)
                                                @plvdi.item.psztext = varptr(szname)
                                        end if
    
    
                                        '***************************************************************
                                        '  second step - show current state image in listview elements
                                        '***************************************************************
    
    
                                        ' here we notify the listview that this item has a state image
                                        if (@plvdi.item.mask and %lvif_image) then
    
    
                                                ' in order for the listview to show the state images
                                                ' the mask and statemask must be set to the following
                                                ' parameters
    
    
                                                @plvdi.item.mask =%lvif_state or %lvif_text
                                                @plvdi.item.statemask =%lvis_stateimagemask
                                        end if
    
    
                                        'virtual listview asks for item state image
                                        if (@plvdi.item.mask and %lvif_state) then
    
    
                                              select case lvfilescheck(@plvdi.item.iitem)
    
    
                                                  ' toggle state of checkboxes
                                                  case 0
                                                       @plvdi.item.state = indextostateimagemask(1)
                                                  case -1
                                                       @plvdi.item.state = indextostateimagemask(2)
                                              end select
    
    
                                        end if
    
    
                                case %lvn_columnclick      ' click on column header to sort
    
    
                                        if @pnmlv.isubitem <> -1& then
                                                sortcolumn @pnmlv.isubitem + 1  ' sort clicked column
                                        end if
    
    
                                case %nm_click
    
    
                                     if @pnmlv.isubitem = 0 then   ' if first column is clicked
    
    
                                          ' toggle checkbox state
                                          lvfilescheck(@pnmlv.iitem) = (lvfilescheck(@pnmlv.iitem) = 0)
    
    
                                          ' update listview
                                          ' method 1 - update the complete listview window
                                          ' (less flicker than other method)
                                          invalidaterect hctl, byval %null, 0
                                          updatewindow hctl
    
    
                                          ' method 2
                                          ' update listview beginning at checked element
                                          ' (downside: it makes the listview display to flicker)
                                          'listview_update(hctl, @pnmlv.iitem)
                                     end if
    
                                case %nm_dblclk
    
                                     if @pnmlv.isubitem > 0 then   ' if other than the first column is clicked
    
    
                                          'to get the text in the cell use the following code
                                          listview_getitemtext (byval hctl, _
                                                                byval @pnmlv.iitem, _
                                                                byval @pnmlv.isubitem, _
                                                                scelltext, _
                                                                sizeof (scelltext))
    
    
                                          msgbox "you double-clicked on an item!" + $crlf + $crlf + _
                                          "column: " + str$(@pnmlv.isubitem) + $crlf+ _
                                          "row: " + str$(@pnmlv.iitem) + $crlf + _
                                          "cell text: " + scelltext
    
    
                                          ' after msgbox set the focus on the listview again
                                          control set focus cbhndl, %idc_virtuallistview
    
    
                                     end if
    
    
    ' ***************needs the proper message name (but it works anyway)**********************************************
    '                the code within was substituted for the code testing %nm_click above
    '                 http://www.powerbasic.com/support/pb...ad.php?t=20777 
    
                                        ' if first column or checkbox is clicked then
    
    
    '                                    if  lowrd(cblparam)=63288 then
    
    
                                             ' toggle checkbox state
    '                                         lvfilescheck(@plvdi.item.iitem) = (lvfilescheck(@plvdi.item.iitem) = 0)
                                             ' update item (downside: it makes the listview display to flicker)
    '                                         listview_update(hctl, @plvdi.item.iitem)
    '                                    end if
    
    
    ' ***************needs the proper message name (but it works anyway)**********************************************
    
    
                               case  %lvn_keydown  ' processes every key except enter(ok) and esc (cancel)
    
    
                                     ' check for the space bar to toggle the checkbox
                                     if @keydown.wvkey = %vk_space then
                                          for n = 0 to listview_getitemcount (hctl)
                                               if listview_getitemstate(hctl,n,%lvis_selected) = %lvis_selected then
                                                    ' toggle checkbox state
                                                    lvfilescheck(n) = (lvfilescheck(n) = 0)
    
    
                                                    ' update listview
                                                    ' method 1 - update the complete listview window
                                                    ' (less flicker than other method)
                                                    invalidaterect hctl, byval %null, 0
                                                    updatewindow hctl
    
    
                                                    ' method 2
                                                    ' update listview beginning at checked element
                                                    ' (downside: it makes the listview display to flicker)
                                                    'listview_update(hctl, @pnmlv.iitem)
    
    
                                                    ' if the %lvs_singlesel style is selected uncomment the next line
                                                    ' exit select
                                               end if
                                          next n
    
    
                                     end if
    
                                     ' we check for system keys that do not affect the selection bar in the listview
                                     ' control and let then pass through. everything else we filter it out.
    
    
                                     if @keydown.wvkey >= %vk_lbutton and @keydown.wvkey =< %vk_help then function = %false : exit select
                                     if @keydown.wvkey >= %vk_lwin and @keydown.wvkey =< %vk_sleep then function = %false : exit select
    
    
                                     ' no more key press processing by the os
                                     function = %true
    
    
                        end select
    
    
         end select
    
    
    end function
    
    sub sortcolumn(byval clmn as long)
        local i        as long
        local dummy()  as string
        local dummy2() as string
    
        glvsort = (glvsort = 0)              ' toggle direction flag
    
        redim dummy(lrowcnt-1) as string     ' use temporary array for sorting
        redim dummy2(lrowcnt-1) as string    ' use temporary array for sorting
    
        for i = 0 to lrowcnt-1              ' parse out proper "column" to temp. array
            dummy(i) = parse$(lvfiles(i), $tab , clmn)
            dummy2(i) = dummy (i)
        next
    
        if glvsort then
            array sort dummy(), collate ucase, tagarray lvfiles(), descend 'sort temp arr, tag original
            array sort dummy2(), collate ucase, tagarray lvfilescheck(), descend 'sort temp arr, tag original
        else
            array sort dummy(), collate ucase, tagarray lvfiles(), ascend
            array sort dummy2(), collate ucase, tagarray lvfilescheck(), ascend
        end if
    
    
        ' redraw listview
        invalidaterect hctl, byval %null, 0
        updatewindow hctl
    
    end sub
    ------------------

  • #2
    This code doesn't seem to work anymore with PB 10. any idea why ?
    Jean-Pierre LEROY

    Comment


    • #3
      Works here. PBWin 10.04 on Vista.

      What changed since the last time it worked for you?
      Dale

      Comment


      • #4
        Compiles here also with PBWin 10.04 and Win7. I don't see any data, but the column headers and a grid displays.

        Frank

        Comment


        • #5
          Yes the source code compiles correctly with PBWin 10.04. But like Franck I can see the column headers and a grid but without any data.
          Jean-Pierre LEROY

          Comment


          • #6
            PBWin 10.4 uses unicode, and the original code uses ansi API calls, and asciiz and ansi strings. It's just a matter to define %UNICODE = 1 and change ASCIIZ TO WSTRINGZ and STRING to WSTRING.

            This works using my headers: (it will fail to compile using the PB headers because, in them, "listview_getitemtext" has no support for unicode - it uses an ASCIIZ string)

            Code:
            ' virtual listbox.bas
            ' 06-08-2004
            
            ' written by: pedro ramirez
            
            ' this program is intended as a guide to show the use and handling of a virtual listview control.
            
            ' it shows the use of checkboxes, sorting and trapping of keys and mouse clicks and how to use
            ' a virtual listview. i think this is a sample as complete and simple as it can get before
            ' digging down further into the workings of a listview control. i have made some commercial apps
            ' using this code as guide entirely.
            
            ' to build this program took many, many, many days of researching through the forums, asking for
            ' help and browsing both the win32 help and the msdn library. i hope those of you who are just
            ' getting to know the listview control can benefit from it.
            
            ' this sample utilizes the checboxes built inside the listbox. if you want to add/or change the image
            ' you can find the needed code where it all started:
            ' http://www.powerbasic.com/support/pb...ad.php?t=10343
            
            ' this sample is public domain
            
            
            #compile exe
            #dim all
            %UNICODE = 1
            #include "win32api.inc"
            #include "commctrl.inc"
            
            
              ' virtual listview id
              %idc_virtuallistview = 2000
            
            
              global lvfiles()      as wstring  ' declare a global array to hold the virtual listview data
              global hctl           as long    ' global variable to hold the virtual listview control handle
              global lvfilescheck() as long    ' array to keep track of checked and unchecked checkboxes
              global glvsort        as long    ' variable used to keep track of the direction of sorting
              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
              declare function showvirtuallv(byval hparent as dword) as long
              declare sub sortcolumn_(byval clmn as long)
            
            
            ' program entry point
            function pbmain()
            
            
                 local lresult as long
                 local hdlg    as dword
            
            
                 dialog new  %hwnd_desktop, "simple virtual listview with state images", 70, 70, _
                      205, 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, 201, 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 tlvi    as lv_item
                 local szbuf   as WSTRINGZ * 50
                 local lstyle  as long
                 dim   lrowcnt as global long
                 dim   lcolcnt as global long
                 local temp()  as wstring
            
            
                 lcolcnt = 5    : ' # of columns in virtual listview
                 lrowcnt = 20   : ' # or rows in virtual listview
            
            
                 ' we'll use a temp() array to store the elements of each row and them join then into
                 ' the lvfiles() array which holds the virtual listview data.
            
            
                 dim temp(lcolcnt - 1)         as local wstring
                 dim lvfiles(lrowcnt - 1)      as global wstring
                 dim lvfilescheck(lrowcnt - 1) as global long
            
            
                 ' 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)
            
            
                 '***********************************
                 '  first step - %lvs_ex_checkboxes
                 '***********************************
                 ' to use state images we must add %lvs_ex_checkboxes to the listview style. this tells
                 ' the listview control to allocate space for the image in the first colummn.
            
            
                 listview_setextendedlistviewstyle hctl, lstyle or %lvs_ex_fullrowselect or _
                      %lvs_ex_gridlines or %lvs_ex_checkboxes or %lvs_ex_headerdragdrop
            
            
                 ' load column headers.
                 ' lvcf_width allows adjustment of column width
            
            
                 ' first we set the first column which holds the checkboxes
                 tlvc.mask    = %lvcf_width
                 tlvc.fmt     = %lvcfmt_left
                 tlvc.psztext = varptr(szbuf)
            
            
                 ' column 0 - we only want show the checkboxes here.
            
            
                 szbuf        = "  : ' nothing, nada, empty, vacio, void
                 tlvc.cx      = 19  : ' here we set the width for the first column (column 0)
                 tlvc.iorder  = 0
                 listview_insertcolumn hctl, 0, tlvc
            
                 ' and now the rest of the column headers
                 tlvc.mask    = %lvcf_text or %lvcf_fmt or %lvcf_subitem or %lvcf_width
                 tlvc.cx      = 100  : ' here we set the width for all columns
            
            
                 for lcol = 1 to lcolcnt - 1
                      szbuf       = using$("column #", lcol)
                      tlvc.iorder = lcol
                      listview_insertcolumn hctl, lcol, tlvc
                 next lcol
            
            
                 ' prepare sample data for virtual listview
                 ' from row 0, column 1 on
                 ' this data will be read by the virtual listview through the %lvn_getdispinfo message
                 ' trap in the dialog callback
            
            
                 for lrow = 0 to lrowcnt - 1
                      for lcol = 1 to lcolcnt - 1
                           temp(lcol) = using$("column #, row #", lcol, lrow)
                      next
                      lvfiles (lrow) = join$ (temp(), $tab)
                 next
            
            
                 ' set the first row as selected
                 listview_setitemstate (hctl,0,%lvis_selected or %lvis_focused,%lvis_selected or %lvis_focused)
            
            
                 ' 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 WSTRINGZ * 50
                local keydown    as lv_keydown ptr
                local checkstate as long
                local scelltext  as WSTRINGZ * 50
                local n          as long
            
                 select case as long cbmsg
            
            
                      case %wm_command
            
            
                           ' process control notifications
                           select case as long cbctl
            
            
                                ' trapping the enter key (%idok)
            
            
                                ' generic
                                ' this is not the enter key but the ok button of the dialog
                                ' (showed for educational purposes)
            
            
                                'case %idok           ' enter key
                                '    msgbox "you pressed enter (%idok of dialog control)"
            
            
                                ' we can be more specific by identifying that it was the listview control
                                ' default ok button
                                ' this is the best alternative i´ve found so far. there may be a better one
                                ' but may involve subclassing. this will only respond when the user has the
                                ' focus on the listview and it actually hits the enter key when a item is
                                ' selected.
            
            
                                case %idok
            
            
                                     ' hctl is the virtual listview control handle for this program
                                     ' test if the listview has the focus
                                     if getfocus = hctl then
            
            
                                '          msgbox "you pressed enter (%idok of listview control)"
            
            
                                          ' to get the item:  (and toggle its corresponding checkbox)
                                          ' to actually toggle checkbox states we trap the space bar under
                                          ' %lvn_keydown below. this is shown to demostrate that the trapping
                                          ' of the enter key works as expected.
                                          n = listview_getnextitem(byval hctl, -1, %lvni_selected)
                                          lvfilescheck(n) = (lvfilescheck(n) = 0)
                                          invalidaterect hctl, byval %null, 0
                                          updatewindow hctl
                                     end if
            
            
                                case %idcancel       ' esc key  of dialog
            
            
                                    dialog end cbhndl
            
                                case %idc_virtuallistview
                                    ' pbforms puts this message trap here. i have not needed to figure it
                                    ' out (yet).
            
            
                           end select
            
                      case %wm_notify
            
            
                        ' the wm_notify message informs the parent window of a control that an event has
                        ' occurred in the control or that the control requires some kind of information.
            
            
                        ' handle listview notifications only
            
            
                                if lowrd(cbwparam) <> %idc_virtuallistview then exit select
            
            
                                ' obtain the nm_listview pointer from cblparam
                                pnmlv = cblparam
            
            
                                ' obtain the lv_keydown pointer from cblparam
                                keydown = 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 + 1)
                                                        @plvdi.item.psztext = varptr(szname)
                                                end if
            
            
                                                '***************************************************************
                                                '  second step - show current state image in listview elements
                                                '***************************************************************
            
            
                                                ' here we notify the listview that this item has a state image
                                                if (@plvdi.item.mask and %lvif_image) then
            
            
                                                        ' in order for the listview to show the state images
                                                        ' the mask and statemask must be set to the following
                                                        ' parameters
            
            
                                                        @plvdi.item.mask =%lvif_state or %lvif_text
                                                        @plvdi.item.statemask =%lvis_stateimagemask
                                                end if
            
            
                                                'virtual listview asks for item state image
                                                if (@plvdi.item.mask and %lvif_state) then
            
            
                                                      select case lvfilescheck(@plvdi.item.iitem)
            
            
                                                          ' toggle state of checkboxes
                                                          case 0
                                                               @plvdi.item.state = indextostateimagemask(1)
                                                          case -1
                                                               @plvdi.item.state = indextostateimagemask(2)
                                                      end select
            
            
                                                end if
            
            
                                        case %lvn_columnclick      ' click on column header to sort
            
            
                                                if @pnmlv.isubitem <> -1& then
                                                        sortcolumn_ @pnmlv.isubitem + 1  ' sort clicked column
                                                end if
            
            
                                        case %nm_click
            
            
                                             if @pnmlv.isubitem = 0 then   ' if first column is clicked
            
            
                                                  ' toggle checkbox state
                                                  lvfilescheck(@pnmlv.iitem) = (lvfilescheck(@pnmlv.iitem) = 0)
            
            
                                                  ' update listview
                                                  ' method 1 - update the complete listview window
                                                  ' (less flicker than other method)
                                                  invalidaterect hctl, byval %null, 0
                                                  updatewindow hctl
            
            
                                                  ' method 2
                                                  ' update listview beginning at checked element
                                                  ' (downside: it makes the listview display to flicker)
                                                  'listview_update(hctl, @pnmlv.iitem)
                                             end if
            
                                        case %nm_dblclk
            
                                             if @pnmlv.isubitem > 0 then   ' if other than the first column is clicked
            
            
                                                  'to get the text in the cell use the following code
                                                  listview_getitemtext (byval hctl, _
                                                                        byval @pnmlv.iitem, _
                                                                        byval @pnmlv.isubitem, _
                                                                        scelltext, _
                                                                        sizeof (scelltext))
            
            
                                                  msgbox "you double-clicked on an item!" + $crlf + $crlf + _
                                                  "column: " + str$(@pnmlv.isubitem) + $crlf+ _
                                                  "row: " + str$(@pnmlv.iitem) + $crlf + _
                                                  "cell text: " + scelltext
            
            
                                                  ' after msgbox set the focus on the listview again
                                                  control set focus cbhndl, %idc_virtuallistview
            
            
                                             end if
            
            
            ' ***************needs the proper message name (but it works anyway)**********************************************
            '                the code within was substituted for the code testing %nm_click above
            '                 http://www.powerbasic.com/support/pb...ad.php?t=20777
            
                                                ' if first column or checkbox is clicked then
            
            
            '                                    if  lowrd(cblparam)=63288 then
            
            
                                                     ' toggle checkbox state
            '                                         lvfilescheck(@plvdi.item.iitem) = (lvfilescheck(@plvdi.item.iitem) = 0)
                                                     ' update item (downside: it makes the listview display to flicker)
            '                                         listview_update(hctl, @plvdi.item.iitem)
            '                                    end if
            
            
            ' ***************needs the proper message name (but it works anyway)**********************************************
            
            
                                       case  %lvn_keydown  ' processes every key except enter(ok) and esc (cancel)
            
            
                                             ' check for the space bar to toggle the checkbox
                                             if @keydown.wvkey = %vk_space then
                                                  for n = 0 to listview_getitemcount (hctl)
                                                       if listview_getitemstate(hctl,n,%lvis_selected) = %lvis_selected then
                                                            ' toggle checkbox state
                                                            lvfilescheck(n) = (lvfilescheck(n) = 0)
            
            
                                                            ' update listview
                                                            ' method 1 - update the complete listview window
                                                            ' (less flicker than other method)
                                                            invalidaterect hctl, byval %null, 0
                                                            updatewindow hctl
            
            
                                                            ' method 2
                                                            ' update listview beginning at checked element
                                                            ' (downside: it makes the listview display to flicker)
                                                            'listview_update(hctl, @pnmlv.iitem)
            
            
                                                            ' if the %lvs_singlesel style is selected uncomment the next line
                                                            ' exit select
                                                       end if
                                                  next n
            
            
                                             end if
            
                                             ' we check for system keys that do not affect the selection bar in the listview
                                             ' control and let then pass through. everything else we filter it out.
            
            
                                             if @keydown.wvkey >= %vk_lbutton and @keydown.wvkey =< %vk_help then function = %false : exit select
                                             if @keydown.wvkey >= %vk_lwin and @keydown.wvkey =< %vk_sleep then function = %false : exit select
            
            
                                             ' no more key press processing by the os
                                             function = %true
            
            
                                end select
            
            
                 end select
            
            
            end function
            
            sub sortcolumn_(byval clmn as long)
                local i        as long
                local dummy()  as wstring
                local dummy2() as wstring
            
                glvsort = (glvsort = 0)              ' toggle direction flag
            
                redim dummy(lrowcnt-1) as wstring     ' use temporary array for sorting
                redim dummy2(lrowcnt-1) as wstring    ' use temporary array for sorting
            
                for i = 0 to lrowcnt-1              ' parse out proper "column" to temp. array
                    dummy(i) = parse$(lvfiles(i), $tab , clmn)
                    dummy2(i) = dummy (i)
                next
            
                if glvsort then
                    array sort dummy(), collate ucase, tagarray lvfiles(), descend 'sort temp arr, tag original
                    array sort dummy2(), collate ucase, tagarray lvfilescheck(), descend 'sort temp arr, tag original
                else
                    array sort dummy(), collate ucase, tagarray lvfiles(), ascend
                    array sort dummy2(), collate ucase, tagarray lvfilescheck(), ascend
                end if
            
            
                ' redraw listview
                invalidaterect hctl, byval %null, 0
                updatewindow hctl
            
            end sub
            Forum: http://www.jose.it-berater.org/smfforum/index.php

            Comment


            • #7
              Thanks Jose, but I got the following display when I compiled and run it -- it display funny characters?

              Click image for larger version  Name:	mess.png Views:	1 Size:	2.3 KB ID:	770574
              Last edited by Anne Wilson; 6 Mar 2018, 03:56 PM.

              Comment


              • #8
                The code that I have posted above works fine in Windows 7. Don't know if you may need to change something else to work with Windows 10. The key is that you have to use unicode strings, not ansi.
                Forum: http://www.jose.it-berater.org/smfforum/index.php

                Comment


                • #9
                  I was getting same as Anne W. in Windows 10

                  I added
                  Code:
                  #RESOURCE MANIFEST,    1, "xptheme.xml"
                  and it displays ok now

                  Comment


                  • #10
                    Thanks so much Guys, you do need the manifest in Windows 10

                    Comment


                    • #11
                      Thank you Jose for your help.

                      It works perfectly now.
                      Jean-Pierre LEROY

                      Comment

                      Working...
                      X