I tried many times to get a datepicker working in a Listview, but never success. I had modified Pierre's code in
https://forum.powerbasic.com/forum/u...nd-date-picker
in order that it starts with
Below is my modified codes
https://forum.powerbasic.com/forum/u...nd-date-picker
in order that it starts with
- initial blank cells for the dates ( instead of some preseted strings in the original Pierre's codes )
- 100 rows in the Listview ( instead of the original 4 in Pierre's codes )
- datepicker if activated would display a window showing today's date and to allow users to pick their own date
- Modified to have a combobox to allow users to select a country
Below is my modified codes
Code:
' Modified to have a Combo box to select country and preset date picker with today's date #COMPILE EXE #DIM ALL #INCLUDE "Win32Api.inc" #INCLUDE "CommCtrl.inc" #RESOURCE MANIFEST, 1, "XPtheme.xml" GLOBAL hDlg AS DWORD GLOBAL hListView AS DWORD GLOBAL hEdit AS DWORD GLOBAL hDatePick AS DWORD GLOBAL hCombo AS DWORD GLOBAL hComboEdit AS DWORD GLOBAL pComboEdit AS DWORD GLOBAL NumLVrow AS LONG GLOBAL CountryArray() AS STRING %Listview = 101 %Edit = 201 %DatePick = 301 %Combo = 401 '______________________________________________________________________________ FUNCTION ListViewPopulate()AS LONG LOCAL ListviewColumnInfo AS LVCOLUMN LOCAL ListviewColumnInfo2 AS LVCOLUMN LOCAL ListViewItem AS LVITEM LOCAL zBuffer AS ASCIIZ * 255 LOCAL ROW AS LONG LOCAL COL AS LONG LOCAL ItemIndex AS LONG ListviewColumnInfo.mask = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM OR %LVCF_WIDTH ListviewColumnInfo.fmt = %LVCFMT_CENTER ListviewColumnInfo.cx = 160 ListviewColumnInfo.pszText = VARPTR(zBuffer) ' column 2 for date entry ListviewColumnInfo2.mask = %LVCF_FMT OR %LVCF_TEXT OR %LVCF_SUBITEM OR %LVCF_WIDTH ListviewColumnInfo2.fmt = %LVCFMT_CENTER ListviewColumnInfo2.cx = 100 ListviewColumnInfo2.pszText = VARPTR(zBuffer) zBuffer = "Editable text" LISTVIEW_INSERTCOLUMN(hListview, 1, ListviewColumnInfo) zBuffer = "Date" LISTVIEW_INSERTCOLUMN(hListview, 2, ListviewColumnInfo2) zBuffer = "Country" LISTVIEW_INSERTCOLUMN(hListview, 3, ListviewColumnInfo) FOR ROW = 0 TO NumLVrow zBuffer = " Row " & FORMAT$(ROW, "00") & ", col " & FORMAT$(0, "00") ListViewItem.stateMask = %LVIS_FOCUSED ListViewItem.pszText = VARPTR(zBuffer) ListViewItem.iSubItem = 0 'Name column ListViewItem.mask = %LVIF_TEXT OR %LVIF_PARAM OR %LVIF_STATE ListViewItem.iItem = ROW ListViewItem.lParam = ROW 'Returns the index of the new item if successful, or -1 otherwise. SendMessage(hListview, %LVM_INSERTITEM, 0, VARPTR(ListViewItem)) ListViewItem.mask = %LVIF_TEXT ListViewItem.iSubItem = 1 ' initial blanks for dates zBuffer = "" SendMessage(hListview, %LVM_SETITEM, 0, VARPTR(ListViewItem)) ListViewItem.iSubItem = 2 ' initial blanks for country zBuffer = "" SendMessage(hListview, %LVM_SETITEM, 0, VARPTR(ListViewItem)) NEXT END FUNCTION '______________________________________________________________________________ FUNCTION ComboEditProc(BYVAL hWnd AS LONG, BYVAL Msg AS LONG,_ BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG LOCAL pNcRec AS NCCALCSIZE_PARAMS POINTER SELECT CASE Msg CASE %WM_NCCALCSIZE pNcRec = lParam 'Move the client area aka edit part 1 pixels up in the edit control @pNcRec.rgrc(0).nTop = @pNcRec.rgrc(0).nTop - 1 FUNCTION = DefWindowProc(hWnd, %WM_NCCALCSIZE, wParam, lParam) EXIT FUNCTION CASE %WM_DESTROY SetWindowLong(hWnd, %GWL_WNDPROC, pComboEdit) END SELECT 'Send unprocessed messages to the original procedure FUNCTION = CallWindowProc(pComboEdit, hWnd, Msg, wParam, lParam) END FUNCTION '_____________________________________________________________________________ CALLBACK FUNCTION DlgProc LOCAL pNotify AS NMHDR POINTER LOCAL pListviewNotify AS NMLISTVIEW POINTER LOCAL pDateTimeNotify AS NMDATETIMECHANGE POINTER LOCAL CellRect AS RECT LOCAL SysTime AS SYSTEMTIME LOCAL zText , zDate AS ASCIIZ * 255 STATIC hListviewHeader AS DWORD STATIC ListviewRow AS LONG STATIC ListviewCol AS LONG SELECT CASE CBMSG CASE %WM_INITDIALOG hListviewHeader = SendMessage(hListView, %LVM_GETHEADER, 0, 0) ' Get the current time seed CALL GetlocalTime(SysTime) ListViewPopulate CASE %WM_COMMAND SELECT CASE CBCTL CASE %Edit IF CBCTLMSG = %EN_KILLFOCUS THEN SendMessage(hDlg, %WM_APP, %Edit, 0) END IF CASE %Combo IF CBCTLMSG = %CBN_KILLFOCUS THEN SendMessage(hDlg, %WM_APP, %Combo, 0) END IF CASE %IDOK IF GetFocus() = hEdit THEN SendMessage(hDlg, %WM_APP, %Edit, 0) END IF IF GetFocus() = hDatePick THEN SendMessage(hDlg, %WM_APP, %DatePick, 0) END IF IF GetFocus() = hCombo THEN SendMessage(hDlg, %WM_APP, %Combo, 0) END IF CASE %IDCANCEL IF GetFocus() = hEdit THEN ListviewRow = -1 ShowWindow(hEdit, %SW_HIDE) END IF IF GetFocus() = hDatePick THEN ListviewRow = -1 ShowWindow(hDatePick, %SW_HIDE) END IF IF GetFocus() = hCombo THEN ListviewRow = -1 ShowWindow(hCombo, %SW_HIDE) END IF END SELECT CASE %WM_APP SELECT CASE CBWPARAM CASE %Edit 'Hide edit and update listview ShowWindow(hEdit, %SW_HIDE) GetDlgItemText(hListView, %Edit, zText, SIZEOF(zText)) ListView_SetItemText(hListView, ListviewRow, ListviewCol, zText) CASE %DatePick 'Hide date picker and update listview ShowWindow(hDatePick, %SW_HIDE) SendMessage(hDatePick, %DTM_GETSYSTEMTIME, %NULL, BYVAL VARPTR(SysTime)) zText = FORMAT$(SysTime.wYear, "0000") & "-" & _ FORMAT$(SysTime.wMonth, "00") & "-" & FORMAT$(SysTime.wDay, "00") ' update listview with the selected date **************************************** ListView_SetItemText(hListView, ListviewRow, ListviewCol, zText) CASE %Combo 'Hide Combo and update listview ShowWindow(hCombo, %SW_HIDE) ComboBox_GetText(hCombo, zText, SIZEOF(zText)) ListView_SetItemText(hListView, ListviewRow, ListviewCol, zText) END SELECT CASE %WM_NOTIFY pNotify = CBLPARAM 'Listview header notification ---------------------- IF @pNotify.hwndFrom = hListviewHeader THEN 'User is dragging a listview header or a divider IF @pNotify.code = %HDN_BEGINTRACK OR @pNotify.code = _ %HDN_BEGINTRACKW OR @pNotify.code = %HDN_BEGINDRAG THEN IF IsWindowVisible(hEdit) OR IsWindowVisible(hDatePick) OR IsWindowVisible(hCombo) THEN 'Cancel text or date edition PostMessage(hDlg, %WM_COMMAND, MAK(DWORD, %IDCANCEL, %BN_CLICKED), 0) END IF END IF END IF 'Listview notification ----------------------------- IF @pNotify.hwndFrom = hListView THEN pListviewNotify = pNotify SELECT CASE @pListviewNotify.hdr.code CASE %NM_CLICK ListviewRow = @pListviewNotify.iItem IF ListviewRow <> -1 THEN 'Click was made on an item ListviewCol = @pListviewNotify.iSubItem 'Get item rect CellRect.nTop = ListviewCol CellRect.nLeft = %LVIR_LABEL 'Get subItem rect SendMessage(hListView, %LVM_GETSUBITEMRECT, ListviewRow, BYVAL VARPTR(CellRect)) 'Get item text ListView_GetItemText(hListView, ListviewRow, ListviewCol, zText, SIZEOF(zText)) 'SetWindowText(hDlg, "[" & zText & "]" & STR$(ListviewRow) & STR$(ListviewCol) & _ ' STR$(CellRect.nLeft) & STR$(CellRect.nRight) & _ ' STR$(CellRect.nTop) & STR$(CellRect.nBottom)) IF ListviewCol = 0 THEN 'Clicked on an editable text cell 'Set edit control text SetDlgItemText(hListView, %Edit, zText) 'Move and size control at listview cell coordinates MoveWindow(hEdit, CellRect.nLeft, CellRect.nTop, _ CellRect.nRight - CellRect.nLeft, _ CellRect.nBottom - CellRect.nTop, %TRUE) 'Make edit control visible ShowWindow(hEdit, %SW_SHOW) 'Set focus SendMessage(hDlg, %WM_NEXTDLGCTL, hEdit, %TRUE) END IF IF ListviewCol = 1 THEN 'Clicked on a date cell '*********************************************************************** Orig code ' SysTime.wYear = VAL(PARSE$(zText, "-", 1)) 'Get cell date year ' SysTime.wMonth = VAL(PARSE$(zText, "-", 2)) 'Get cell date month ' SysTime.wDay = VAL(PARSE$(zText, "-", 3)) 'Get cell date day ' SendMessage(hDatePick, %DTM_SETSYSTEMTIME, %GDT_VALID, BYVAL VARPTR(SysTime)) 'Set initial DatePicker date ' MoveWindow(hDatePick, CellRect.nLeft, CellRect.nTop, _ 'Move and size control at listview cell coordinates ' CellRect.nRight - CellRect.nLeft, CellRect.nBottom - CellRect.nTop, %TRUE) ' ShowWindow(hDatePick, %SW_SHOW) 'Make control visible ' SendMessage(hDlg, %WM_NEXTDLGCTL, hDatePick, %TRUE) 'Set focus '***************************************************************************** ' my modified codes ' check if it is originally a blank field zDate = "" ListView_GetItemText(hListView, ListviewRow, _ 1, zDate, SIZEOF(zDate)) IF LEN(TRIM$(zDate)) = 0 THEN ' when orig field is a blank 'Set an initial DatePicker date using today's date CALL GetlocalTime(SysTime) ELSE ' when orig field is a NON blank 'Get cell date year SysTime.wYear = VAL(PARSE$(zDate, "-", 1)) 'Get cell date month SysTime.wMonth = VAL(PARSE$(zDate, "-", 2)) 'Get cell date day SysTime.wDay = VAL(PARSE$(zDate, "-", 3)) END IF SendMessage(hDatePick, %DTM_SETSYSTEMTIME, %GDT_VALID, BYVAL VARPTR(SysTime)) 'Move and size control at listview cell coordinates MoveWindow(hDatePick, CellRect.nLeft, CellRect.nTop, _ CellRect.nRight - CellRect.nLeft, _ CellRect.nBottom - CellRect.nTop, %TRUE) 'Make control visible ShowWindow(hDatePick, %SW_SHOW) 'Set focus SendMessage(hDlg, %WM_NEXTDLGCTL, hDatePick, %TRUE) END IF IF ListviewCol = 2 THEN 'Clicked on a combobox 'Set combobox-edit text ComboBox_SetText(hCombo, zText) 'Move and size control at listview cell coordinates MoveWindow(hCombo, CellRect.nLeft, CellRect.nTop -1, _ CellRect.nRight - CellRect.nLeft, _ CellRect.nBottom - CellRect.nTop, %TRUE) 'Set combobox height, see combo subclass ComboBox_SetItemHeight(hCombo, -1, CellRect.nBottom - CellRect.nTop - 4) 'Make control visible ShowWindow(hCombo, %SW_SHOW) 'Set focus SendMessage(hDlg, %WM_NEXTDLGCTL, hCombo, %True) END IF END IF CASE %LVN_BEGINSCROLL 'ScrollBar IF IsWindowVisible(hEdit) OR IsWindowVisible(hDatePick) _ OR IsWindowVisible(hCombo) THEN 'SendMessage(hDlg, %WM_APP, 0, 0) 'Keep text change 'Cancel text change PostMessage(hDlg, %WM_COMMAND, MAK(DWORD, %IDCANCEL, %BN_CLICKED), 0) END IF END SELECT END IF 'Date picker notification ----------------------------------------------- IF @pNotify.hwndFrom = hDatePick THEN pDateTimeNotify = pNotify SELECT CASE LONG CBNMCODE CASE %NM_KILLFOCUS 'Hide datepicker and update listview cell SendMessage(hDlg, %WM_APP, %DatePick, 0) END SELECT END IF CASE %WM_SIZE IF CBWPARAM <> %SIZE_MINIMIZED THEN MoveWindow(hListview, 5, 5, LOWRD(CBLPARAM) - 10, _ HIWRD(CBLPARAM) - 10, %TRUE) END IF CASE %WM_DESTROY LOCAL RowCount AS LONG LOCAL ColCount AS LONG LOCAL hFile AS INTEGER RowCount = SendMessage(hListview, %LVM_GETITEMCOUNT, 0, 0) ColCount = SendMessage(SendMessage(hlistview, %LVM_GETHEADER, 0, 0), _ %HDM_GETITEMCOUNT, 0, 0) DIM sText(1 TO RowCount, 1 TO ColCount) AS STRING FOR ListviewRow = 1 TO RowCount FOR ListviewCol = 1 TO ColCount ListView_GetItemText(hListView, ListviewRow - 1, _ ListviewCol - 1, zText, SIZEOF(zText)) sText(ListviewRow, ListviewCol) = zText NEXT NEXT hFile = FREEFILE OPEN "ListViewData.txt" FOR OUTPUT AS hFile FOR ListviewRow = 1 TO RowCount FOR ListviewCol = 1 TO ColCount PRINT #hFile, sText(ListviewRow, ListviewCol) NEXT NEXT CLOSE hFile END SELECT END FUNCTION '______________________________________________________________________________ FUNCTION PBMAIN() LOCAL hIcon AS DWORD ' Setup the country array Setup_CountryArray ' number of listview rows NumLVrow = 100 DIALOG FONT "Segoe UI", 9 DIALOG NEW %HWND_DESKTOP, "ListView with editable text, editable date, and combobox", , , 285, 170, _ %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SYSMENU OR %WS_THICKFRAME, 0 TO hDlg hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) SetClassLong(hDlg, %GCL_HICON, hIcon) SendMessage(hDlg, %WM_SETICON, %ICON_SMALL, hIcon) CONTROL ADD "SysListView32", hDlg, %Listview, "SysListView321", 5, 5, 340, 230, _ %WS_CHILD OR %WS_VISIBLE OR %WS_BORDER OR %WS_TABSTOP OR %LVS_REPORT OR _ %LVS_SHOWSELALWAYS, %WS_EX_LEFT OR %WS_EX_RIGHTSCROLLBAR hListview = GetDlgItem(hDlg, %Listview) LISTVIEW_SETEXTENDEDLISTVIEWSTYLE(hListview, _ ListView_GetExtendedListViewStyle(hListview) OR _ %LVS_EX_FULLROWSELECT OR %LVS_EX_DOUBLEBUFFER OR _ %LVS_EX_HEADERDRAGDROP OR %LVS_EX_GRIDLINES) CONTROL ADD TEXTBOX, hDlg, %Edit, "Edit", 0, 0, 0, 0 hEdit = GetDlgItem(hDlg, %Edit) SetParent(hEdit, hListview) ShowWindow(hEdit, %SW_HIDE) CONTROL ADD "SysDateTimePick32", hDlg, %DatePick, "", 0, 0, 0, 0, _ %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, %WS_EX_CLIENTEDGE OR _ %WS_EX_LEFT OR %WS_EX_LTRREADING OR %DTS_SHORTDATEFORMAT hDatePick = GetDlgItem(hDlg, %DatePick) SetParent(hDatePick, hListview) ShowWindow(hDatePick, %SW_HIDE) CONTROL ADD COMBOBOX, hDlg, %Combo, CountryArray(), 0, 0, 0, 0, _ %WS_CHILD OR %WS_VISIBLE OR _ %CBS_DROPDOWN OR %WS_TABSTOP OR _ %CBS_DISABLENOSCROLL OR %WS_VSCROLL , %WS_EX_LEFT hCombo = GetDlgItem(hDlg, %Combo) SetParent(hCombo, hListview) ShowWindow(hCombo, %SW_HIDE) 'Get combo edit control handle and subclass it LOCAL ComboboxInf AS COMBOBOXINFO ComboboxInf.cbSize = SIZEOF(COMBOBOXINFO) GetComboBoxInfo(hCombo, BYVAL VARPTR(ComboboxInf)) hComboEdit = ComboboxInf.hwndItem pComboEdit = SetWindowLong(hComboEdit, %GWL_WndProc, CODEPTR(ComboEditProc)) DIALOG SHOW MODAL hDlg CALL DlgProc DestroyIcon(hIcon) END FUNCTION '================================ ' Setup the country array SUB Setup_CountryArray DIM CountryArray(200) ARRAY ASSIGN CountryArray() = "Afghanistan","Albania","Algeria","Andorra","Angola","Antigua and Barbuda", _ "Argentina","Armenia","Australia","Austria","Azerbaijan", _ "Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium", _ "Belize","Benin","Bhutan","Bolivia","Bosnia and Herzegovina", _ "Botswana","Brazil","Brunei","Bulgaria" ,"Burkina Faso","Burundi" ,_ "Côte d'Ivoire","Cabo Verde","Cambodia","Cameroon","Canada", _ "Central African Republic","Chad","Chile","China","Colombia", _ "Comoros","Congo-Brazzaville","Costa Rica","Croatia", _ "Cuba","Cyprus" ,"Czechia" , _ "Democratic Republic of the Congo" , "Denmark","Djibouti" , _ "Dominica" ,"Dominican Republic" , _ "Ecuador","Egypt" ,"El Salvador","Equatorial Guinea", _ "Eritrea","Estonia","Ethiopia", _ "Fiji" ,"Finland","France", _ "Gabon" ,"Gambia","Georgia","Germany","Ghana","Greece", _ "Grenada","Guatemala","Guinea","Guinea-Bissau","Guyana" , _ "Haiti" ,"Holy See","Honduras" ,"Hungary", _ "Iceland","India","Indonesia","Iran","Iraq","Ireland","Israel","Italy",_ "Jamaica" ,"Japan","Jordan" , _ "Kazakhstan","Kenya","Kiribati" ,"Kuwait","Kyrgyzstan" ,_ "Laos" ,"Latvia","Lebanon","Lesotho","Liberia" , _ "Libya" ,"Liechtenstein","Lithuania","Luxembourg", _ "Madagascar" ,"Malawi" ,"Malaysia","Maldives","Mali", _ "Malta" ,"Marshall Islands","Mauritania","Mauritius", _ "Mexico" ,"Micronesia" ,"Moldova","Monaco","Mongolia", _ "Montenegro","Morocco","Mozambique","Myanmar" , _ "Namibia","Nauru","Nepal","Netherlands" ,"New Zealand", _ "Nicaragua","Niger","Nigeria","North Korea","North Macedonia","Norway",_ "Oman" ,"Pakistan","Palau","Palestine State","Panama", _ "Papua New Guinea","Paraguay","Peru","Philippines","Poland", _ "Portugal" , "Qatar" ,_ "Romania","Russia","Rwanda", _ "Saint Kitts and Nevis" ,"Saint Lucia","Saint Vincent and the Grenadines" ,_ "Samoa" ,"San Marino" ,"Sao Tome and Principe","Saudi Arabia" ,_ "Senegal","Serbia" ,"Seychelles","Sierra Leone" ,"Singapore",_ "Slovakia","Slovenia","Solomon Islands","Somalia","South Africa",_ "South Korea","South Sudan","Spain","Sri Lanka","Sudan" , _ "Suriname","Swaziland" ,"Sweden","Switzerland" ,"Syria", _ "Tajikistan","Tanzania" ,"Thailand","Timor-Leste","Togo", _ "Tonga" ,"Trinidad and Tobago" ,"Tunisia","Turkey", _ "Turkmenistan" ,"Tuvalu", _ "Uganda","Ukraine","United Arab Emirates", _ "United Kingdom","United States of America","Uruguay","Uzbekistan", _ "Vanuatu","Venezuela","Vietnam","Yemen" ,_ "Zambia", "Zimbabwe" END SUB
Comment