    'WIP - Work in Progress - not complete - 
    'Everybody is invited to improve this code
     
    $ filename "t.exe"
     
    'uses rtl32
    'uses rtl64
     
    uses WinUtil
     
     
    % 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 xx
      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
     
     
    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))
     
    sub ListView_Insert_Column(sys hwnd, int id, col, string 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)
    end sub
     
    sub ListView_Insert_Item(sys hwnd, int id, row, image, string Expr)
       LV_ITEM lvi
       lvi.stateMask   = LVIS_FOCUSED
       lvi.mask = LVIF_TEXT 
       lvi.pszText = Expr
       lvi.iItem = row
       ListView_InsertItem(GetDlgItem(hwnd,id), &lvi)
    end sub 
     
    sub ListView_Set_Text(sys hwnd, int id, row, col, string 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 420,260,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,
                              10,10,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
       MaxRow=50    : MaxCol=10
       
       LV_COLUMN lvc
       
       for i = 1 to MaxCol
          Listview_insert_column (hwnd, IDC_ListView, i, "Col " + str(i), 100, 0)      
       next i
     
       for i = 1 to MaxRow
          Listview_insert_item (hwnd, IDC_ListView, i, 0, "Row " + str(i) + " Col 1")
          for j = 1 to MaxCol
             Listview_set_text (hwnd, IDC_ListView, i, j, "Row " + str(i) + " Col " + str(j))
          next j
       next i
    end sub
     
    '==================
    sub UpdateTitleBar(sys hwnd)
       SetWindowText (hwnd, "ListView Grid Demo:  " + 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 = GREEN
                    else
                       pcd.clrTextBk = WHITE
                    end if
                 end select                               
        end select
        return CDRF_DODEFAULT
    end function
     
     