1. Changing values in a list view column
- Posted by Jonas Temple <jktemple at yhti.net> Apr 26, 2002
- 407 views
To anyone interested... The included code snippet lets you do in-place editing of a list view column's contents. To change the contents, click ONCE on the first column of each list view item. Wait a second and then an edit control should appear. Type in some text and press Enter. The column data is updated. There is a button on the bottom that SHOULD start editing of a column but it doesn't work :( Anyway, has anyone else ever tried this? Is there any way to change the contents of columns other than the first? How do I force editing of another column/row with the LVM_EDITLABLE message? I guess what I'm wondering is if you can, with a list view control, come up with a primitive grid control? Jonas Here is the code! include win32lib.ew without warning with trace atom void global constant MainWin = create(Window, "Test Editable List Views", 0, 0, 0, 500, 400, 0), lv = create(ListView, {"Column1","Column2","Column3"}, MainWin, 10, 10, 400, 300, or_all({LVS_REPORT,LVS_EDITLABELS})), pb = create( PushButton, "Test", MainWin, 10, 350, 90, 30, 0) procedure MainWin_onEvent(atom event, atom wParam, atom lParam) atom edit_ctl, iLength, buffer, id, msg sequence text, selection if event = WM_NOTIFY then id = getId( fetch( lParam, NMHDR_hwndFrom )) msg = fetch( lParam, NMHDR_code ) if id = lv and (msg = LVN_ENDLABELEDITW or msg = LVN_ENDLABELEDITA) then edit_ctl = sendMessage(lv, LVM_GETEDITCONTROL, 0, 0) if edit_ctl then iLength = w32Func( xSendMessage, { edit_ctl, WM_GETTEXTLENGTH, 0, 0 } ) if iLength > 0 then iLength += 1 buffer = acquire_mem(0, iLength ) iLength = w32Func( xSendMessage, { edit_ctl, WM_GETTEXT, iLength, buffer } ) text = peek( {buffer, iLength} ) release_mem( buffer ) selection = getLVSelected(lv) setLVItemText(lv, selection[1], 0, text) end if end if end if end if end procedure onEvent[MainWin] = routine_id("MainWin_onEvent") procedure MainWin_onOpen() atom index, mask, void sequence data mask = or_all({LVS_EX_HEADERDRAGDROP,LVS_EX_GRIDLINES, LVS_EX_TRACKSELECT }) void = sendMessage(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, mask, mask) for i = 1 to 3 do data = {"Row" & sprintf("%d", i) & "Col1", "Row" & sprintf("%d", i) & "Col2", "Row" & sprintf("%d", i) & "Col3"} index = addLVItem(lv, 0, data) end for end procedure onOpen[MainWin] = routine_id("MainWin_onOpen") procedure pb_onClick() sequence selection atom void selection = getLVSelected(lv) void = sendMessage(lv, LVM_EDITLABEL, 1, 0) end procedure onClick[pb] = routine_id("pb_onClick") WinMain(MainWin, Normal)
2. Re: Changing values in a list view column
- Posted by euman at bellsouth.net Apr 26, 2002
- 409 views
Hello Jonas, The easier way would be to only code in API and use a typical listbox and not the listview control at all. by using LBS_OWNERDRAWFIXED = 16, or LBS_OWNERDRAWVARIABLE = 32, you would have total control over your listbox and because earlier versions of windows dont have some of the great listview features you could code the listbox to act anyway a listview could and also work on the old Win O/S's. There may be other ways to do what you want other than what I present but this seemed easiest for me. the below code is in no way optimized for size or speed but should give a good idea how this all fits together. This code only adds bitmaps to listboxs but with very little change you could setup grids. if iMsg = WM_CREATE then <snip...> hList = CreateWindow(WS_EX_CLIENTEDGE,"listbox",0,or_all({WS_CHILD,WS_TABSTOP,LBS_OWNERDRAWFIXED,LBS_HASSTRINGS}), 230, 240, 290, 110, hwnd, ID_hList, hInst, 0) itemDC = c_func(xGetDC, {hList}) hListmem = c_func(xCreateCompatibleDC,{itemDC}) c_proc(xReleaseDC, {hList, itemDC}) junk = SendMessage(hList, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0) -- you guess what Im doing here? AddItem(hList, "Core Files (Interpreter and Include files)", dacheck) AddItem(hList, "Documentation and Tutorials", checked) AddItem(hList, "Demonstration source code", checked) junk = SendMessage(hList, LB_SETCURSEL, 0, 0) elsif iMsg = WM_DRAWITEM then action = peek4u(lParam+12) itemDC = peek4u(lParam+24) if action = ODA_DRAWENTIRE then if peek4u(lParam+20) = hList then junk = SendMessage(hList, LB_GETITEMDATA, peek4u(lParam+8), 0) hListbmp = c_func(xSelectObject,{hListmem, junk}) rect_left = peek4u(lParam+28) rect_top = peek4u(lParam+32) rect_right = peek4u(lParam+36) rect_bottom= peek4u(lParam+40) junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) if SendMessage(hList, LB_GETSEL, peek4u(lParam+8), 0) then poke4(lParam+28, rect_left + 20) c_proc(xDrawFocusRect,{itemDC, lParam+28}) FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, hbrush) SetTextColor(itemDC, 16777215) junk = c_func(xSetBkColor,{itemDC, 3670016}) else SetTextColor(itemDC, 3670016) junk = c_func(xSetBkColor,{itemDC, 16777215}) end if txtbuff = allocate(256) junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) c_proc(xGetTextMetrics,{itemDC, txtmetrics}) y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) free(txtbuff) end if elsif action = ODA_SELECT then junk = SendMessage(hList, LB_GETCURSEL, 0, 0) if desel then rect_left = peek4u(lParam+28) rect_top = peek4u(lParam+32) rect_right = peek4u(lParam+36) rect_bottom= peek4u(lParam+40) FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, wbrush) hListbmp = c_func(xSelectObject,{hListmem, uncheck}) junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) txtbuff = allocate(256) junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) c_proc(xGetTextMetrics,{itemDC, txtmetrics}) y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) free(txtbuff) desel = 0 else rect_left = peek4u(lParam+28) rect_top = peek4u(lParam+32) rect_right = peek4u(lParam+36) rect_bottom= peek4u(lParam+40) FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, hbrush) hListbmp = c_func(xSelectObject,{hListmem, uncheck}) junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) txtbuff = allocate(256) junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) c_proc(xGetTextMetrics,{itemDC, txtmetrics}) y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) SetTextColor(itemDC, 16777215) junk = c_func(xSetBkColor,{itemDC, 3670016}) c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) free(txtbuff) desel = 1 end if end if elsif iMsg = WM_MEASUREITEM then if peek4u(lParam) = ODT_LISTBOX then if peek4u(lParam+4) = ID_hList then junk = SendMessage(hList, LB_SETITEMHEIGHT, 0, 16) end if end if Maybe helpfull to someone. Euman ----- Original Message ----- From: "Jonas Temple" <jktemple at yhti.net> To: "EUforum" <EUforum at topica.com> Sent: Friday, April 26, 2002 1:44 PM Subject: Changing values in a list view column > > To anyone interested... > > The included code snippet lets you do in-place editing of a list view > column's contents. To change the contents, click ONCE on the first > column of each list view item. Wait a second and then an edit control > should appear. Type in some text and press Enter. The column data is > updated. There is a button on the bottom that SHOULD start editing of a > column but it doesn't work :( > > Anyway, has anyone else ever tried this? Is there any way to change the > contents of columns other than the first? How do I force editing of > another column/row with the LVM_EDITLABLE message? I guess what I'm > wondering is if you can, with a list view control, come up with a > primitive grid control? > > Jonas > > Here is the code! > > include win32lib.ew > without warning > with trace > atom void > global constant MainWin = create(Window, "Test Editable List Views", 0, > 0, 0, 500, 400, 0), > lv = create(ListView, {"Column1","Column2","Column3"}, > MainWin, 10, 10, 400, 300, > or_all({LVS_REPORT,LVS_EDITLABELS})), > pb = create( PushButton, "Test", MainWin, 10, 350, 90, > 30, 0) > > procedure MainWin_onEvent(atom event, atom wParam, atom lParam) > atom edit_ctl, iLength, buffer, id, msg > sequence text, selection > if event = WM_NOTIFY then > id = getId( fetch( lParam, NMHDR_hwndFrom )) > msg = fetch( lParam, NMHDR_code ) > if id = lv and (msg = LVN_ENDLABELEDITW or msg = > LVN_ENDLABELEDITA) then > edit_ctl = sendMessage(lv, LVM_GETEDITCONTROL, 0, 0) > if edit_ctl then > iLength = w32Func( xSendMessage, { edit_ctl, > WM_GETTEXTLENGTH, 0, 0 } ) > if iLength > 0 then > iLength += 1 > buffer = acquire_mem(0, iLength ) > iLength = w32Func( xSendMessage, { edit_ctl, > WM_GETTEXT, iLength, buffer } ) > text = peek( {buffer, iLength} ) > release_mem( buffer ) > selection = getLVSelected(lv) > setLVItemText(lv, selection[1], 0, text) > end if > end if > end if > end if > end procedure > onEvent[MainWin] = routine_id("MainWin_onEvent") > > procedure MainWin_onOpen() > atom index, mask, void > sequence data > mask = or_all({LVS_EX_HEADERDRAGDROP,LVS_EX_GRIDLINES, > LVS_EX_TRACKSELECT }) > void = sendMessage(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, mask, mask) > > for i = 1 to 3 do > data = {"Row" & sprintf("%d", i) & "Col1", > "Row" & sprintf("%d", i) & "Col2", > "Row" & sprintf("%d", i) & "Col3"} > index = addLVItem(lv, 0, data) > end for > end procedure > onOpen[MainWin] = routine_id("MainWin_onOpen") > > procedure pb_onClick() > sequence selection > atom void > selection = getLVSelected(lv) > void = sendMessage(lv, LVM_EDITLABEL, 1, 0) > end procedure > onClick[pb] = routine_id("pb_onClick") > > > WinMain(MainWin, Normal) > > > >
3. Re: Changing values in a list view column
- Posted by euman at bellsouth.net Apr 26, 2002
- 396 views
Hi Here is an example that uses tabstops in the listbox http://www.thescarms.com/vbasic/listbox.asp The code I sent earlier should be very easily hacked to do what you want to do and have total control over grids.... Euman
4. Re: Changing values in a list view column
- Posted by Derek Parnell <ddparnell at bigpond.com> Apr 26, 2002
- 420 views
Jonas, only the first column can be edited in this manner. This is because the ListView control was originally designed by Microsoft to allow different views of directory contents. The idea was that the first column would contain the filename, and it would allow you to rename the file without calling up a dialog box. You will note that when trying to change any other attributes of a file from the MS_Explorer window, you have to call up the Properties dialog. Of course, people are now using the listview for all sorts of things it wasn't originally intended for. However, MS still haven't enhanced it up date any column - only the first one. So, the ListView is not a good choice for a grid control. I expect you might need to go low-level and create a window that has a set of 'cells' that are really edit boxes or just child windows, set up as children of the grid window. You would have to handle all the row/column scrolling etc yourself. Good luck. -------------- Derek ----- Original Message ----- From: "Jonas Temple" <jktemple at yhti.net> To: "EUforum" <EUforum at topica.com> Sent: Saturday, April 27, 2002 4:44 AM Subject: Changing values in a list view column > > To anyone interested... > > The included code snippet lets you do in-place editing of a list view > column's contents. To change the contents, click ONCE on the first > column of each list view item. Wait a second and then an edit control > should appear. Type in some text and press Enter. The column data is > updated. There is a button on the bottom that SHOULD start editing of a > column but it doesn't work :( > > Anyway, has anyone else ever tried this? Is there any way to change the > contents of columns other than the first? How do I force editing of > another column/row with the LVM_EDITLABLE message? I guess what I'm > wondering is if you can, with a list view control, come up with a > primitive grid control? > > Jonas > > Here is the code! > > include win32lib.ew > without warning > with trace > atom void > global constant MainWin = create(Window, "Test Editable List Views", 0, > 0, 0, 500, 400, 0), > lv = create(ListView, {"Column1","Column2","Column3"}, > MainWin, 10, 10, 400, 300, > or_all({LVS_REPORT,LVS_EDITLABELS})), > pb = create( PushButton, "Test", MainWin, 10, 350, 90, > 30, 0) > > procedure MainWin_onEvent(atom event, atom wParam, atom lParam) > atom edit_ctl, iLength, buffer, id, msg > sequence text, selection > if event = WM_NOTIFY then > id = getId( fetch( lParam, NMHDR_hwndFrom )) > msg = fetch( lParam, NMHDR_code ) > if id = lv and (msg = LVN_ENDLABELEDITW or msg = > LVN_ENDLABELEDITA) then > edit_ctl = sendMessage(lv, LVM_GETEDITCONTROL, 0, 0) > if edit_ctl then > iLength = w32Func( xSendMessage, { edit_ctl, > WM_GETTEXTLENGTH, 0, 0 } ) > if iLength > 0 then > iLength += 1 > buffer = acquire_mem(0, iLength ) > iLength = w32Func( xSendMessage, { edit_ctl, > WM_GETTEXT, iLength, buffer } ) > text = peek( {buffer, iLength} ) > release_mem( buffer ) > selection = getLVSelected(lv) > setLVItemText(lv, selection[1], 0, text) > end if > end if > end if > end if > end procedure > onEvent[MainWin] = routine_id("MainWin_onEvent") > > procedure MainWin_onOpen() > atom index, mask, void > sequence data > mask = or_all({LVS_EX_HEADERDRAGDROP,LVS_EX_GRIDLINES, > LVS_EX_TRACKSELECT }) > void = sendMessage(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, mask, mask) > > for i = 1 to 3 do > data = {"Row" & sprintf("%d", i) & "Col1", > "Row" & sprintf("%d", i) & "Col2", > "Row" & sprintf("%d", i) & "Col3"} > index = addLVItem(lv, 0, data) > end for > end procedure > onOpen[MainWin] = routine_id("MainWin_onOpen") > > procedure pb_onClick() > sequence selection > atom void > selection = getLVSelected(lv) > void = sendMessage(lv, LVM_EDITLABEL, 1, 0) > end procedure > onClick[pb] = routine_id("pb_onClick") > > > WinMain(MainWin, Normal) > > > >
5. Re: Changing values in a list view column
- Posted by Derek Parnell <ddparnell at bigpond.com> Apr 26, 2002
- 413 views
----- Original Message ----- From: <euman at bellsouth.net> To: "EUforum" <EUforum at topica.com> Subject: Re: Changing values in a list view column > > Hello Jonas, > > The easier way would be to only code in API and use a typical listbox > and not the listview control at all. > by using > LBS_OWNERDRAWFIXED = 16, or > LBS_OWNERDRAWVARIABLE = 32, > > you would have total control over your listbox and because earlier versions > of windows dont have some of the great listview features you could code the > listbox to act anyway a listview could and also work on the old Win O/S's. > > There may be other ways to do what you want other than what I present but > this seemed easiest for me. > > the below code is in no way optimized for size or speed but should give a good > idea how this all fits together. This code only adds bitmaps to listboxs but with > very little change you could setup grids. > > if iMsg = WM_CREATE then > <snip...> > > hList = CreateWindow(WS_EX_CLIENTEDGE,"listbox",0,or_all({WS_CHILD,WS_TABSTOP,LBS_OW NERDRAWFIXED,LBS_HASSTRINGS}), > 230, 240, 290, 110, hwnd, ID_hList, hInst, 0) > > itemDC = c_func(xGetDC, {hList}) > hListmem = c_func(xCreateCompatibleDC,{itemDC}) > c_proc(xReleaseDC, {hList, itemDC}) > > junk = SendMessage(hList, WM_SETFONT, GetStockObject(DEFAULT_GUI_FONT), 0) > > -- you guess what Im doing here? > AddItem(hList, "Core Files (Interpreter and Include files)", dacheck) > AddItem(hList, "Documentation and Tutorials", checked) > AddItem(hList, "Demonstration source code", checked) > > junk = SendMessage(hList, LB_SETCURSEL, 0, 0) > > elsif iMsg = WM_DRAWITEM then > action = peek4u(lParam+12) > itemDC = peek4u(lParam+24) > > if action = ODA_DRAWENTIRE then > if peek4u(lParam+20) = hList then > > junk = SendMessage(hList, LB_GETITEMDATA, peek4u(lParam+8), 0) > hListbmp = c_func(xSelectObject,{hListmem, junk}) > > rect_left = peek4u(lParam+28) > rect_top = peek4u(lParam+32) > rect_right = peek4u(lParam+36) > rect_bottom= peek4u(lParam+40) > > junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) > > if SendMessage(hList, LB_GETSEL, peek4u(lParam+8), 0) then > poke4(lParam+28, rect_left + 20) > c_proc(xDrawFocusRect,{itemDC, lParam+28}) > FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, hbrush) > SetTextColor(itemDC, 16777215) > junk = c_func(xSetBkColor,{itemDC, 3670016}) > else > SetTextColor(itemDC, 3670016) > junk = c_func(xSetBkColor,{itemDC, 16777215}) > > end if > > txtbuff = allocate(256) > junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) > c_proc(xGetTextMetrics,{itemDC, txtmetrics}) > y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) > c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) > free(txtbuff) > > end if > > elsif action = ODA_SELECT then > > junk = SendMessage(hList, LB_GETCURSEL, 0, 0) > > if desel then > rect_left = peek4u(lParam+28) > rect_top = peek4u(lParam+32) > rect_right = peek4u(lParam+36) > rect_bottom= peek4u(lParam+40) > > FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, wbrush) > hListbmp = c_func(xSelectObject,{hListmem, uncheck}) > junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) > > txtbuff = allocate(256) > junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) > c_proc(xGetTextMetrics,{itemDC, txtmetrics}) > y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) > c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) > free(txtbuff) > > desel = 0 > else > rect_left = peek4u(lParam+28) > rect_top = peek4u(lParam+32) > rect_right = peek4u(lParam+36) > rect_bottom= peek4u(lParam+40) > > FillRect(itemDC,{rect_left+20, rect_top, rect_right, rect_bottom}, hbrush) > hListbmp = c_func(xSelectObject,{hListmem, uncheck}) > junk = c_func(xBitBlt,{itemDC, 1, rect_top, 15,rect_top+16, hListmem, 0, 0, SRCCOPY}) > > txtbuff = allocate(256) > junk = SendMessage(hList, LB_GETTEXT, peek4u(lParam+8), txtbuff) > c_proc(xGetTextMetrics,{itemDC, txtmetrics}) > y = floor(rect_top + 8 - peek4u(txtmetrics) / 2) > SetTextColor(itemDC, 16777215) > junk = c_func(xSetBkColor,{itemDC, 3670016}) > c_proc(xTextOut,{itemDC,26,y,txtbuff,c_func(xlstrlen,{txtbuff})}) > free(txtbuff) > > desel = 1 > end if > end if > > elsif iMsg = WM_MEASUREITEM then > if peek4u(lParam) = ODT_LISTBOX then > if peek4u(lParam+4) = ID_hList then > junk = SendMessage(hList, LB_SETITEMHEIGHT, 0, 16) > end if > end if > > > Maybe helpfull to someone. > Euman > Gee, Euman! That does look easy. Why would anyone use win32lib if one could do it this easily.
6. Re: Changing values in a list view column
- Posted by euman at bellsouth.net Apr 27, 2002
- 419 views
----- Original Message ----- From: "Jonas Temple" <jktemple at yhti.net> > I'm not sure I want to tackle writing a Euphoria grid control from > scratch. Why not? > It doesn't make much sense to reinvent the wheel. This will keep Euphoria on the bottom shelf. Euman