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
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
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
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