Thread: Can a listbox row be editable by the user? like a spreadsheet?

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    161

    Can a listbox row be editable by the user? like a spreadsheet?

    What I'm trying to do is rig up an inline assembler. I've done a decent amount of C, but this is my first taste of using the API. So how can I display a bunch of assembly in a listbox/spreadsheet view and have each line editable as if working on an excel spreadsheet? Can a listbox do it or do I need something else?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, the listbox can't do that (to my knowledge).
    However, a treeview control might be able to do that.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    Are you using MFC (or similar library) or straight Win32?

    http://www.codeproject.com/KB/combobox/lbed.aspx has an MFC sample. This should give you an idea what needs to be done if you aren't using MFC.

  4. #4
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by DaveH View Post
    Are you using MFC (or similar library) or straight Win32?

    http://www.codeproject.com/KB/combobox/lbed.aspx has an MFC sample. This should give you an idea what needs to be done if you aren't using MFC.
    Straight Win32.

    Well, I dunno anything of MFC, but it looks as if they're somehow grabbing the exact location of the listbox item on the screen, then showing an editbox over it to do the actual editing. Am I close? Anyone want to be kind enough to point me in the direction of the right API calls to get the location of the text like that and stick the edit box over it? An example of that same thing Dave linked to but without MFC would wonderful.
    Last edited by Viper187; 06-03-2008 at 01:52 PM.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Am I close?
    Right on.

    >> ... calls to get the location of the text like that
    LB_GETITEMRECT message to listbox

    >> and stick the edit box over it?
    CreateWindow[Ex]("Edit") with WS_BORDER | WS_CHILD | WS_VISIBLE | ES_WANTRETURN (according to code in the article)

    http://msdn.microsoft.com/en-us/libr...44(VS.85).aspx

    Translating MFC code isn't *too* bad. For controls, many of the methods simply correspond to a windows message. Like "m_pLB->GetItemRect(n, &r);", which sends an LB_GETITEMRECT message to the windows handle associated with m_pLB.

    gg

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If I'm not mistaken, a treeview control supports editing labels natively without the need for hacks or tricks.
    If you want, you could try both methods and find the one more suitable to your liking. I don't have a link to an example on how to do it or remember how to do it, however.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    ListView seems to be the tight tool for the job. However, making use of the built-in label editing functionality is proving to be troublesome. It creates an editbox itself over the list item and you can grab a handle to it with LVM_GETEDITCONTROL, but it only does that on the first column. Using EM_SETRECT or SetWindowPos() to move it over another column refuses to work. I wish somebody would do proper examples of stuff like this without MFC.

    Here's where I'm having issues:
    Code:
    					    case LVN_BEGINLABELEDIT:
    					        hEditBox = (HWND)SendDlgItemMessage(hwnd, LST_DATA, LVM_GETEDITCONTROL, 0, 0);
                                                    LV_ITEM lvItem = ( (NMLVDISPINFO*)lParam )->item;
    					        DWORD dwPos = GetMessagePos();
    					        POINT pLoc = { GET_X_LPARAM( dwPos ), GET_Y_LPARAM( dwPos ) };
    					        ScreenToClient( hwnd, &pLoc );
    
    					        LVHITTESTINFO	lvHit;
    					        lvHit.pt.x = pLoc.x;
    					        lvHit.pt.y = pLoc.y;
    					        lvHit.iItem = lvItem.iItem;
    					        int item = SendDlgItemMessage(hwnd, LST_DATA, LVM_SUBITEMHITTEST, 0, (LPARAM)&lvHit);
    //					        sprintf(txtInput,"%d",lvItem.iSubItem);
    //					        MessageBox(hwnd,txtInput,"Debug",0);
    					        RECT lvRect = { lvHit.iSubItem, LVIR_LABEL }; 
                                                    SendDlgItemMessage(hwnd, LST_DATA, LVM_GETSUBITEMRECT, lvItem.iItem, (LPARAM)&lvRect);
                                                    SetWindowPos(hEditBox,NULL,lvRect.left,lvRect.top,0,0,SWP_SHOWWINDOW|SWP_NOZORDER|SWP_NOSIZE);
    Last edited by Viper187; 06-05-2008 at 01:41 PM.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The thing is that Win32 is so tricky that most people use some type of framework. MFC is one of them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    http://www.codeguru.com/cpp/controls...icle.php/c923/
    Yep - more MFC.....sorry.
    Post back here if you have any trouble "translating" any of those steps into pure Win32 code.

    gg

  10. #10
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Quote Originally Posted by Codeplug View Post
    http://www.codeguru.com/cpp/controls...icle.php/c923/
    Yep - more MFC.....sorry.
    Post back here if you have any trouble "translating" any of those steps into pure Win32 code.

    gg
    That's creating an editbox on the subitems though. There should be a way to force the one ListView creates itself to move where you want it. Problem is, something forces it to move back immediately. I didn't realize it until I used a messagebox to test the return of SetWindowPos(). While the messagebox was showing, the editcontrol was moved, but it moved back as soon as I closed the messagebox. I've heard subclassing the control might get around that behavior, but that sounds like more trouble than it's worth.

    edit: Looking closer at that example, I guess I'd need to subclass either way. I still don't understand how to actually subclass though. Anyone got non-MFC examples of that?

    edit2: Found one. Now I'm just wondering which event(s) to handle and if using GetMessagePos() in the handler will still give me the same coords as it would've in LVN_BEGINLABELEDIT.

    Code:
    case LVN_BEGINLABELEDIT:
     oldEditProcedure = (WNDPROC)GetWindowLongPtr (hEditBox, GWLP_WNDPROC);			
     SetWindowLongPtr (hEditBox, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    Code:
    LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     
    switch (message)
    {
    	case WM_WINDOWPOSCHANGING:
    	    {
     			WINDOWPOS* windowPos = (WINDOWPOS*)lParam;
    
    			windowPos->x += 100;
    	 return CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
    	   }     
    	default:
    
    	if (oldEditProcedure) {
    	return CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
    	}
    	else {
    	return DefWindowProc (hwnd, message, wParam, lParam);
    	}
    }
    }
    Last edited by Viper187; 06-05-2008 at 04:10 PM.

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> There should be a way to force the one ListView creates itself to move where you want it
    ListView only supports editting of the first column. Any other columns (subitems) then you have to do it - all of it. I don't recommend "forcing" anything. You *may* be able to get this approach working, but I don't see any advantage in forcing the use of the list view's edit box.

    >> I guess I'd need to subclass either way.
    I don't think subclassing is absolutely required. You have to:
    - detect which row/column was clicked
    - show a edit box over that cell
    - apply changes to cell from the edit
    Very similiar to the edittable listbox - just on a per-cell basis.

    gg

  12. #12
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    It's coming together, albeit slowly. My next issue shouldn't be too difficult, but I can't get it. I'm trying to make it so only hex characters can be typed in the editbox. I looked up WM_KEYDOWN/WM_KEYUP but I'm not having any luck preventing the text from getting to the box. Returning 0/1 didn't seem to have any effect. Do I have to edit the wParam itself or something?

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Here's where you do need to subclass...
    In your subclassed windows procedure, handle WM_CHAR. If the char is ok, pass it along to the original windows procedure, otherwise return 0.

    gg

  14. #14
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Make sure the Edit you create sends a msg back to the LV (or the LV parent) to show it has finished.

    I use an end label edit msg.

    Make sure you process loss of focus in the edit as well ie user ignores edit.

    I also process arrow presses/returns to move the edits location as per excel.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  15. #15
    Registered User
    Join Date
    Jun 2008
    Posts
    161
    Yep, WM_CHAR did the trick. I guess it helps when you know the right bloody thing to handle. lol

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to cast a ListBox item to an int for a switch statment?
    By Swaine777 in forum C++ Programming
    Replies: 8
    Last Post: 09-26-2004, 08:52 PM
  2. ~ User Input script help~
    By indy in forum C Programming
    Replies: 4
    Last Post: 12-02-2003, 06:01 AM
  3. comparing user input
    By lambs4 in forum C Programming
    Replies: 5
    Last Post: 12-15-2002, 10:28 AM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. Getting FULL filename from listbox
    By Garfield in forum Windows Programming
    Replies: 8
    Last Post: 01-27-2002, 08:28 AM