Listview question

Started by Frank Brübach, March 19, 2024, 02:06:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frank Brübach

Hi Charles

I am using the Listview example of WinGui Folder all is OK but the Header for columns Nummer arent correct ;)

Do you know a way to load Data for These rows and cells or do I must Take String Array Text? Or alternative a combobox?

Thank,  Frank


    ' - listview example oxygen, 18-3-24
    ' - frank bruebach, column headers numbers aren't in correct increasement order
     
    $ filename "t.exe"
       
    uses WinUtil
    'uses mylistview
    indexbase 1
    '----------------------------------------------------------------------- //

    'mylistview.inc

    % LVCF_FMT 1
    % LVCF_WIDTH 2
    % LVCF_TEXT=4
    % LVCF_SUBITEM 8
    % LVIF_TEXT=1
    % LVIF_PARAM=4
    % LVIF_STATE=8
    % LVIS_FOCUSED=1
    % LVN_ITEMCHANGING= -100
    % LVM_INSERTITEM=4103
    % LVM_SETITEM=4102
    % LVM_INSERTCOLUMN=4123
    % LVM_SETEXTENDEDLISTVIEWSTYLE= 4150
    % LVM_SETCOLUMNWIDTH=4126
    % LVS_REPORT=1
    % LVM_ENSUREVISIBLE=4115
    % LVS_SINGLESEL=4
    % LVS_SHOWSELALWAYS=8
    % LVS_EX_GRIDLINES=1
    % LVS_EX_FULLROWSELECT=32
    % LVSCW_AUTOSIZE_USEHEADER= -2
    % NM_CLICK= -2
    % NM_CUSTOMDRAW= -12
    % GWLP_WNDPROC= -4
    % CDRF_DODEFAULT=0
    % CDRF_NOTIFYITEMDRAW=32
    % CDRF_NOTIFYSUBITEMDRAW=32
    % CDDS_PREPAINT=1
    % CDDS_ITEM=65536
    % CDDS_SUBITEM=131072
         
      type NMHDR
      sys     hwndFrom
      sys     idFrom  'uint ptr
      uint    code
      end type
     
    type LVCOLUMN
      uint  mask
      int   fmt
      int   cx
      char* pszText
      int   cchTextMax
      int   iSubItem
      int   iImage
      int   iOrder
      int   cxMin
      int   cxDefault
      int   cxIdeal 
    end type
    typedef LVCOLUMN LV_COLUMN
     
    type LVITEM 
      uint   mask
      int    iItem
      int    iSubItem
      uint   state
      uint   stateMask
      char*  pszText
      int    cchTextMax
      int    iImage       // index of the list view item's icon
      sys    lParam       // 32-bit value to associate with item
      int    iIndent
      int    iGroupId
      uint   cColumns
      'uint   *puColumns
      'int    *piColFmt
      'int    iGroup
    end type
    typedef LVITEM LV_ITEM
     
     
    type NMLISTVIEW
      NMHDR  hdr
      int    iItem
      int    iSubItem
      UINT   uNewState
      UINT   uOldState
      UINT   uChanged
      POINT  ptAction
      sys    lParam
    end type
    typedef NMLISTVIEW NM_LISTVIEW
     
    type NMCUSTOMDRAW
      NMHDR     hdr
      DWORD     dwDrawStage
      sys       hdc
      RECT      rc
      sys       dwItemSpec 'DWORD_PTR
      UINT      uItemState
      sys       lItemlParam
    end type
     
    type NMLVCUSTOMDRAW
      NMCUSTOMDRAW nmcd
      int          clrText     'COLORREF
      int          clrTextBk   'COLORREF
      int          iSubItem
      DWORD        dwItemType
      int          clrFace     'COLORREF
      int          iIconEffect
      int          iIconPhase
      int          iPartId
      int          iStateId
      RECT         rcText
      UINT         uAlign
    end type
   
    static int col,icol
     
    macro ListView_InsertColumn(hwnd,iCol,pcol) (SendMessage(hwnd, LVM_INSERTCOLUMN, iCol, pcol))
    macro ListView_InsertItem(hwnd,pitem) (SendMessage(hwnd, LVM_INSERTITEM,0, pitem))
    macro ListView_SetItem(hwnd,pitem) (SendMessage(hwnd, LVM_SETITEM, 0, pitem))
     
        string text
        'Column Headers
        'For i = 0 To LVCOLS
        '   lvc.mask = LVCF_FMT OR LVCF_WIDTH OR LVCF_TEXT OR LVCF_SUBITEM 'LVCF_TEXT
        '   text="Column #" & str(i+1)
        '   lvc.pszText = text               
        '   ListView_InsertColumn(hListview, i, &lvC)
        'Next i

    sub ListView_Insert_Column(sys hwnd, int id, col, bstring Expr, int width, int fmt)
       LV_COLUMN lvc
       lvc.mask = LVCF_FMT OR LVCF_WIDTH OR LVCF_TEXT OR LVCF_SUBITEM
       lvc.fmt = fmt
       lvc.pszText = Expr   
       lvc.cx = width
       ListView_InsertColumn(GetDlgItem(hwnd, id), col-1, &lvc) 'col-1, &lvc)
    end sub
     
    sub ListView_Insert_Item(sys hwnd, int id, row, image, bstring Expr)
       LV_ITEM lvi
       lvi.stateMask   = LVIS_FOCUSED
       lvi.mask = LVIF_TEXT
       lvi.pszText =  Expr ' "Column #" & str(i+1) 'Expr +
       lvi.iItem = row
       ListView_InsertItem(GetDlgItem(hwnd,id), &lvi)
    end sub
     
    sub ListView_Set_Text(sys hwnd, int id, row, col, bstring Expr)
       LV_ITEM lvi
       if col=1 then
         lvi.mask = LVIF_TEXT or LVIF_STATE or lVIF_PARAM
       else
         lvi.mask = LVIF_TEXT or LVIF_STATE
       end if 
       lvi.pszText = Expr
       lvi.iItem = row-1
       lvi.iSubItem = col-1
       ListView_SetItem(GetDlgItem(hwnd,id), &lvi)
    end sub
     
    function MAX(int num1, num2) as int
      if num1 > num2 then return num1
      return num2
    end function
     
    function MIN(int num1, num2) as int
      if num1 < num2 then return num1
      return num2
    end function
         
    % IDC_ListView = 500
     
    sys hMainWin, hListView ', int SortDirection
    int MaxRow, MaxCol, CurrentRow, CurrentCol
    sys OrigLVProc
     
     
    'Load the common controls library...
    INITCOMMONCONTROLSEXt icce
    icce.dwSize = sizeof(INITCOMMONCONTROLSEXt)
    icce.dwICC = 0xffff
    InitCommonControlsEx(&icce)
     
    char* cmdline
    &cmdline=GetCommandLine()
    sys hInstance = GetModuleHandle(null)
     
     
    declare sub CreateLVData(sys hwnd)
    declare sub UpdateTitleBar(sys hwnd)
    declare function CustomDraw(NMLVCUSTOMDRAW* pcd) as sys
    declare function NewLVProc(sys hwnd, uint wMsg, sys wParam, lParam) as sys
    '

    '----------------------------------------------------------------------- //

    '------------------------------------- //
    MainWindow 520,360,WS_OVERLAPPEDWINDOW
    '------------------------------------- //

   '-------------------------------------------------------------------------//
    Function WndProc(sys hwnd, uint uMsg, sys wParam, lParam) as sys callback
   '-------------------------------------------------------------------------//
   
      int i,j
      NM_LISTVIEW *lpLvNm
      NMLVCUSTOMDRAW *lpLvCd
      NMHDR *pnmhdr
     
        select uMsg
       
            case WM_CREATE
               uint Style = WS_CHILD or WS_VISIBLE or LVS_REPORT or WS_TABSTOP or LVS_SHOWSELALWAYS or LVS_SINGLESEL         
               uint StyleEx = WS_EX_CLIENTEDGE
     
               hListView = CreateWindowEx(StyleEx, "SysListView32", "",Style,
                              20,20,360,200,
                              hwnd, IDC_LISTVIEW, hInstance, null)
               if hListview=null then mbox "Error: Cannot create Listview"
           
               SendMessage(hListview, LVM_SETEXTENDEDLISTVIEWSTYLE, 0,  LVS_EX_FULLROWSELECT or LVS_EX_GRIDLINES)
               'initialize data/location
               CreateLVData(hwnd)
               CurrentRow = 1 : CurrentCol = 1
               UpdateTitleBar(hwnd)
               SetFocus(hListview)
               InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, 1)
               
               'subclass LV
               OrigLVProc = SetWindowLongPtr(hListView, GWLP_WndProc, @NewLVProc)
     
            case WM_NOTIFY
               @pnmhdr=lParam
           
               select case pnmhdr.idFrom
                  case IDC_ListView
                     select case pnmhdr.code
                        case LVN_ITEMCHANGING               
                           return 1
     
                        case NM_CLICK               
                           &LpLvNm=lParam
                           CurrentRow = LpLvNm.iiTem + 1
                           CurrentCol = LpLvNm.iSubItem + 1
                           InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, 1)
                           SetFocus(hListview)
                           UpdateTitleBar(hwnd)
     
                        case NM_CUSTOMDRAW 'ok                                   
                           &lpLvCd=lParam
                           return CustomDraw(lpLvCd)
                     end select
               end select
     
       
            case WM_SIZE:
                RECT rc
                GetClientRect(hWnd, &rc)
                MoveWindow(hListview, rc.left, rc.top, rc.right, rc.bottom, 1)
                SendMessage(hListview, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER)
           
            case WM_CLOSE
                DestroyWindow(hwnd)
           
            case WM_DESTROY
                SetWindowLongPtr(hListView, GWLP_WNDPROC, OrigLVProc)       
                PostQuitMessage(0)
           
            case else
                return DefWindowProc(hwnd, uMsg, wParam, lParam)           
        end select
       
    end function
     
     
    '==========================
     sub CreateLVData(sys hwnd)
    '------------------------- //
      int i,j
      ' i++
       MaxRow=25    : MaxCol= 5 '10
       
       LV_COLUMN lvc
       
       for i = 1 to MaxCol
          Listview_insert_column (hwnd, IDC_ListView, str(i), "Cols " + str(i), 100, 0)  ' header   
       next i
     
       for i = 1 to MaxRow
          Listview_insert_item (hwnd, IDC_ListView, str(i), 0, "Row " + str(i) + " Col 1")
          for j = 1 to MaxCol
             Listview_set_text (hwnd, IDC_ListView, str(i), str(j), "Row " + str(i) + " Col " + str(j))
          next j
       next i
    end sub
     
    '===========================
    sub UpdateTitleBar(sys hwnd)
       SetWindowText (hwnd, "ListView Grid Demo2:  " + str(CurrentRow) + " : " + str(CurrentCol))
    end sub
     
     
    '=============================
    ' Subclass ListView procedure
    Function NewLVProc(sys hwnd, uint wMsg, sys wParam, lParam) as sys callback
     
       select case wMsg
             
          case WM_KEYDOWN     
             select case wParam
     
                case VK_Up         
                   CurrentRow = MAX(1,CurrentRow-1)
                   UpdateTitleBar(GetParent(hwnd))                             
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, 1)
                   
                case VK_Down           
                   CurrentRow = MIN(MaxRow,CurrentRow+1)
                   UpdateTitleBar(GetParent(hwnd))
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, 1)
                   
                case VK_Left
                   CurrentCol = MAX(1,CurrentCol-1)
                   UpdateTitleBar(GetParent(hwnd))                           
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, 1)
     
                case VK_Right
                   CurrentCol = MIN(MaxCol,CurrentCol+1)
                   UpdateTitleBar(GetParent(hwnd))               
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, 1)                             
     
               case VK_Home
                   CurrentCol = 1
                   if GetKeyState(VK_Control) then CurrentRow = 1               
                   UpdateTitleBar(GetParent(hwnd))
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, 1)               
     
                case VK_End
                   CurrentCol = MaxCol
                   if GetKeyState(VK_Control) then CurrentRow = MaxRow                             
                   UpdateTitleBar(GetParent(hwnd))               
                   InvalidateRect(GetDlgItem(hwnd, IDC_ListView), null, false)
                   SendMessage(hListView, LVM_ENSUREVISIBLE, CurrentRow, false)               
            end select
       end select
       
       return CallWindowProc(OrigLVProc, hwnd, wMsg, wParam, lParam)   
    end function
     
    '===============================================
    function CustomDraw(NMLVCUSTOMDRAW* pcd) as sys
    '-----------------------------------------------
        %= st1 CDDS_ITEM | CDDS_PREPAINT
        %= st2 CDDS_ITEM | CDDS_SUBITEM | CDDS_PREPAINT
        select case pcd.nmcd.dwDrawStage
            case CDDS_PREPAINT:
               'item notification
                return CDRF_DODEFAULT | CDRF_NOTIFYITEMDRAW
     
            case st1:       
                'subitem notification
                return CDRF_DODEFAULT | CDRF_NOTIFYSUBITEMDRAW
     
            case st2:       
                select case pcd.iSubItem           
                    if (pcd.nmcd.dwItemSpec=CurrentRow-1) and (pcd.iSubItem=CurrentCol-1) then               
                       'highlight the selected row
                       pcd.clrTextBk = YELLOW 'GREEN
                    else
                       pcd.clrTextBk = WHITE
                    end if
                 end select                               
        end select
        return CDRF_DODEFAULT
    end function
    ' ends
     
  •  

Frank Brübach

I am thinking about These Kind of row Data with a function

' just an idea for rowdata
'
Function GetRowData(rowNum As Integer) As String()
    Dim rowData(4) As String ' for 5 columns of data

    Select Case rowNum
        Case 1
            rowData(0) = "Diana Rigg"
            rowData(1) = "123 Main St"
            rowData(2) = "1500 queens"
            rowData(3) = "35"
        Case 2
            rowData(0) = "Jane Smith"
            rowData(1) = "456 Elm St"
            rowData(2) = "1800 Lisopsdown"
            rowData(3) = "40"
        Case 3
            rowData(0) = "Henry Maske"
            rowData(1) = "Berliner Str. 30"
            rowData(2) = "10352 Berlin"
            rowData(3) = "60"
  Case 4
            rowData(0) = "Guido Walfisch"
            rowData(1) = "Waterstreet 150"
            rowData(2) = "10652 Berlin"
            rowData(3) = "80"
       
    End Select
    ' Return rowData array
    GetRowData = rowData
End Function
  •  

Frank Brübach

PS and how and where to Change the Background color of the headers?


and how I can change the color of background of the headers?

 
    '===============================================
    function CustomDraw(NMLVCUSTOMDRAW* pcd) as sys
    '-----------------------------------------------
        %= st1 CDDS_ITEM | CDDS_PREPAINT
        %= st2 CDDS_ITEM | CDDS_SUBITEM | CDDS_PREPAINT
        select case pcd.nmcd.dwDrawStage
            case CDDS_PREPAINT:
               'item notification
                return CDRF_DODEFAULT | CDRF_NOTIFYITEMDRAW
     
            case st1:       
                'subitem notification
                return CDRF_DODEFAULT | CDRF_NOTIFYSUBITEMDRAW
     
            case st2:       
                select case pcd.iSubItem           
                    if (pcd.nmcd.dwItemSpec=CurrentRow-1) and (pcd.iSubItem=CurrentCol-1) then               
                       'highlight the selected row
                       pcd.clrTextBk = YELLOW 'GREEN
                    else
                       pcd.clrTextBk = WHITE
                    end if                     
           case st3:
               select case pcd.iSubItem
                     '----------------------------------------- //
                     ' // where and how to paint the background of the headers ?
                     int hBrush
                     hBrush = CreateSolidBrush(RGB(228,120,51))
                     InflateRect @pcd.nmcd.rc, -2, -2
                     FillRect @pcd.nmcd.hdc, @pcd.nmcd.rc, hBrush

                     SetBkMode @pcd.nmcd.hdc, %TRANSPARENT
                     ' // Change your text color here...
                     SetTextColor @pcd.nmcd.hdc, RGB(92,51,23)
                     '----------------------------------------- //

               end if

                 end select                               
        end select
        return CDRF_DODEFAULT
    end function
    ' ends
     

Thanks again
  •  

Charles Pegge

Hi Frank,

I don't know much about ListView. You will have to ask Bill:

https://learn.microsoft.com/en-us/windows/win32/controls/create-a-list-view-control

On the subject of loading and storing data, one of the simplest methods is to use a fixed-size text file, and map the row and column data into one text string. This technique is a good starting point, and is easy to extend to gain more flexibility.

'data table demo
'
'
===================
class FixedTable10k
===================
'
% TableSize  10000 'bytes
% RecordSize 100   'bytes
% FieldSize  10    'bytes
% offset    -109   '1-record-field
'
bstring ft 'FixedTable storage
'
method constructor()
====================
  ft=space(TableSize)
end method
'
method destructor()
===================
  ft=""
end method
'
method load(string f="t.dat")
=============================
  ft=getfile(f)
end method
'
method save(string f="t.dat")
=============================
  putfile(f,ft)
end method
'
method pad(string s) as string
==============================
  int le=len(s)
  if le=10
    return s
  else
    return left(s+space(FieldSize),FieldSize)
  endif
end method
'
method get(int y,x) as string
=============================
  return mid(ft, y*RecordSize+x*FieldSize+offset,FieldSize)
end method
'
method put(int y,x, string s)
=============================
  mid(ft, y*RecordSize+x*fieldSize+offset)=pad(s)
end method
'
method show(int y=0,x=0)
========================
  if y=0
    print ""
    exit method
  endif
  if x=0
    'whole record
    print mid(ft,y*RecordSize+FieldSize+offset,RecordSize)
  else
    'field
    print get(y,x)
  endif
end method
'
end class 'FixedTable10k
'
'TESTS
'=====
new FixedTable10k t()
t.put(2,3,"Hello")
t.put(2,4,"world")
'print t.get(2,3)
't.show(2)
't.show(2,4)
't.show(2,3)
t.save()
del t
new FixedTable10k u
u.load()
u.show(2)
u.put(2,3, ucase(u.get(2,3)) )
u.show(2)
del u