Editable TListView?
BlitzMax Forums/BlitzMax Programming/Editable TListView?
| ||
Hi there, I am using the TListView.bmx file that I got from Logic GUI but the fields can't be edited directly by the user, the fields are not editable by entering new values on the keyboard. Is there a possibility to edit the fields values directly? Many thanks for your help. |
| ||
No, it is not possible. You will need to create a popup window featuring a textfield or similar for such an interaction. |
| ||
It is possible, but you have to create it yourself (as it's not native functionality for Windows list control). Here are the steps to achieve this:: 1. When user clicks left mouse button figure out coordinates where button was pressed. 2. Find out which item (aka line) was activated. This is easy because Blitzmax events tell you that. 3. Find out which column resides in those coordinates. One way is to get all column widths and then do the additions going them one by one. Other way is to use win32 messages See listview messages like LVM_SUBITEMHITTEST to determine column. 4. Now that we have column and item we need to use those to get exact coordinates/width/height of the area in that column/item. There is a Windows message called LVM_GETSUBITEMRECT which gives what we want. 5.Create/show an editbox (like MaxGui textfield) in those coordinates with width exactly the width of the column and height exactly the height of the item (line) and set the editbox text with the text in the listview. 6. When editbox looses focus set the edited text in listview and destroy/hide editbox. Some additional things need to be addressed, but basically thats it. -Henri |
| ||
Ok, thank you very much guys for this information. Sounds like a lot of work.... I appreciate the time you took guys to answer my question. |
| ||
Hi there, In order to figure out the column selected in the selected row of the list view, I added the following code to the TListView.bmx file In all honesty, I don't really know what I am doing and of course it doesn't work. Is there a quick fix to this issue? Many thanks for your help. Method getListViewColumnSelected:Int(mouse_posx:Int, mouse_posy:Int) Local LVM_Item:LVHITTESTINFO = New LVHITTESTINFO LVM_Item.pt_x = mouse_posx LVM_Item.pt_y = mouse_posy SendMessageW(ListboxHwnd, LVM_SUBITEMHITTEST, 0, Int(Byte Ptr LVM_Item)) Return LVM_Item.iSubItem End Method |
| ||
I tried it out and it seems to work for me. In order for Hittest to work it propably needs some mouseaction. Here's a small example (try changing x-coord): 'EXAMPLE import maxgui.drivers Local win:tgadget = CreateWindow("ListView Test", 300, 200, 600, 400) Local lv:TListView = TListview.Create(0, 0, ClientWidth(win), ClientHeight(win), win) lv.addListViewColumn("COL 0",100) lv.addListViewColumn("COL 1",100) lv.addListViewColumn("COL 2",100) lv.deleteListviewColumn(0) For Local i:Int = 0 To 9 lv.addListViewItem([String("Item "+i+"|Col 0"), String("Item "+i+"|Col 1"), String("Item "+i+"|Col 2")]) Next Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End Case EVENT_GADGETACTION Select EventSource() Case lv Print "action" Print lv.getListViewColumnSelected(100, 10) EndSelect EndSelect Forever Structure I used: Type LVHITTESTINFO Field pt_x:Int Field pt_y:Int Field flags:Int Field iItem:Int Field iSubItem:Int Field iGroup:Int EndType Not sure if it makes difference, but for my test OS is win7. -Henri |
| ||
Hi Henri Many thanks for your help. I tried to expand on your example but I am still out of luck. It looks like that getting the position of the mouse over the TListview gadget is a challenge. Looking at the forum, I came up with the program below. Is there something obvious that I am missing. I never thought that something that simple to think about would be that difficult to implement ;-) Many thanks for your kind help. 'EXAMPLE Import maxgui.drivers Import "ExternalTypes/TListView.bmx" Extern "win32" Function GetCursorPos( point:Byte Ptr ) End Extern Type TPoint Field x,y End Type Global point:TPoint = New TPoint Function MouseX(gadget:tgadget = Null) If Not gadget gadget=Desktop() hwnd=QueryGadget(gadget,GADGET_HWND) Local lpPoint[2] GetCursorPos lpPoint ScreenToClient hwnd,lpPoint Return lpPoint[0] End Function Function MouseY(gadget:tgadget=Null) If Not gadget gadget=Desktop() hwnd=QueryGadget(gadget,GADGET_HWND) Local lpPoint[2] GetCursorPos lpPoint ScreenToClient hwnd,lpPoint Return lpPoint[1] End Function Global win:tgadget = CreateWindow("ListView Test", 300, 200, 600, 400) Global lv:TListView = TListview.Create(0, 0, ClientWidth(win), ClientHeight(win), win) lv.addListViewColumn("COL 0",100) lv.addListViewColumn("COL 1",100) lv.addListViewColumn("COL 2",100) lv.deleteListviewColumn(0) For Local i:Int = 0 To 9 lv.addListViewItem([String("Item "+i+"|Col 0"), String("Item "+i+"|Col 1"), String("Item "+i+"|Col 2")]) Next Repeat GetCursorPos point WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE End Case EVENT_MOUSEMOVE Case EVENT_GADGETACTION Select EventSource() Case lv Print "The column selected is : " + lv.getListViewColumnSelected(MouseX(lv), MouseY(lv)) EndSelect EndSelect Forever |
| ||
I believe that the best way to get the mousecoords is straight from the source. There is a NewListProc() function inside TListView type which is a native callback function for listview. Every event that originates from listview goes here first which seems a good place to catch mousecoords. Add two global variables inside TListView type called xPos:int and yPos:int. Then add this statement inside NewListProc() function If Msg = WM_LBUTTONDOWN 'Check mouse location in relative to listview xPos = (lParam & $FFFF) yPos = (lParam Shr 16) EndIf Now replace lv.getListViewColumnSelected-parameters with lv.xPos and lv.yPos and voila :-) -Henri |
| ||
Hiya guys... If i understand what youre trying to achieve here, how about sending a LVM_SUBITEMHITTEST message to the hwnd of the listviewcontrol with a LVHITTESTINFO structure to get the details returned from there? |
| ||
Hi Henri, You are a genius! Your solution worked liked a charm! I owe you a beer, for sure! This was getting frustrating, thank you so much. I am trying to write an app to help me learn the guitar. The listview has columns for chord names, lyrics etc... I need a way to change the values by double clicking on them in order to create/edit a song. I suppose that ideally, I would have needed a grid control but I don't think there is one with maxgui. Also tried to install wxMax to give it a try but I did not manage to compile the module... Well, sweat for another day.... I mostly do Excel Vba programming at work so this Win32 and gcc stuff is not my forte ;-) Many thanks for your assistance. Hi Col, What you suggest is what we did, but I didn't know how to properly get the position of the mouse over the listview control. |
| ||
Ahh yes, up at post #5. Ignore me... I'll crawl into my little corner :-) Good luck with the app, sounds cool. |