Easy Navigation Through an Editable List View
First off, I would like to acknowledge that most of this code came from others at Code Guru. I took code from some of the articles submitted by Zafir Anjum, so look at his article "Editable Subitems" as a basis for this article.
This project demonstrates how the list view/control can be used to edit information in the form of a table (multiple-editable columns). I have captured the Tab, Page Down, Page Up, Up, Down, Home, and End keys to allow easy navigation through the control.
As shown in "Editable Subitems", I subclassed the CEdit control with my class called gxEditCell. Then, I added a new parameter to it's constructor. This new parameter is a pointer to the parent list control so that my edit box could inform the list control of any important events, like a key press. Then when I get a key event, I simply tell the list control which subitem I want to edit next based off the current cell that is being edited. This can be seen in the OnKeyDown function below. As you can see, when I receive the VK_UP key event, I am telling the list control to edit the subitem located directly above the current cell. I check, of course, to see if it is a valid cell first.
The reason I caught some events in the KeyDown, some in the KeyUp, and some in the OnChar, had to do with how the application behaved. If I would have caught the VK_PRIOR or VK_NEXT in the OnKeyDown, I would get several calls depending on how long the button was pressed. This is very annoying. If you don't believe me, move the code, add several items to the list and try it (it isn't pretty).
I also caught the ESC key so that I could cancel an edit. The return key is being used to end an edit and when it is on the last record, it insert a new one. Just don't forget to override the OnGetDlgCode() so that you can get the arrow keys and tabs.
gxEditCell::gxEditCell (gxListCtrl* pCtrl, int iItem, int iSubItem, CString sInitText)
: bEscape (FALSE)
{
pListCtrl = pCtrl;
Item = iItem;
SubItem = iSubItem;
InitText = sInitText;
}
void
gxEditCell::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags)
{
// Up and down are in the OnKeyDown so that the user can hold down the arrow
// keys to scroll through the entries.
BOOL Control = GetKeyState (VK_CONTROL) < 0;
switch (nChar)
{
case VK_UP :
{
if (Item > 0)
pListCtrl->EditSubItem (Item - 1, SubItem);
return;
}
case VK_DOWN :
{
pListCtrl->EditSubItem (Item + 1, SubItem);
return;
}
case VK_HOME :
{
if (!Control)
break;
pListCtrl->EditSubItem (0, SubItem);
return;
}
case VK_END :
{
if (!Control)
break;
int Count = pListCtrl->GetItemCount() - 1;
pListCtrl->EditSubItem (Count, SubItem);
return;
}
}
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}
void
gxEditCell::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
case VK_NEXT :
{
int Count = pListCtrl->GetItemCount();
int NewItem = Item + pListCtrl->GetCountPerPage();
if (Count > NewItem)
pListCtrl->EditSubItem (NewItem, SubItem);
else
pListCtrl->EditSubItem (Count - 1, SubItem);
return;
}
case VK_PRIOR :
{
int NewItem = Item - pListCtrl->GetCountPerPage();
if (NewItem > 0)
pListCtrl->EditSubItem (NewItem, SubItem);
else
pListCtrl->EditSubItem (0, SubItem);
return;
}
}
CEdit::OnKeyUp (nChar, nRepCnt, nFlags);
}
void
gxEditCell::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
{
BOOL Shift = GetKeyState (VK_SHIFT) < 0;
switch (nChar)
{
case VK_ESCAPE :
{
if (nChar == VK_ESCAPE)
bEscape = TRUE;
GetParent()->SetFocus();
return;
}
case VK_RETURN :
{
SetListText();
pListCtrl->EditSubItem (Item + 1, 0);
return;
}
case VK_TAB :
{
if (Shift)
{
if (SubItem > 0)
pListCtrl->EditSubItem (Item, SubItem - 1);
else
{
if (Item > 0)
pListCtrl->EditSubItem (Item - 1, 2);
}
}
else
{
if (SubItem < 2)
pListCtrl->EditSubItem (Item, SubItem + 1);
else
pListCtrl->EditSubItem (Item + 1, 0);
}
return;
}
}
CEdit::OnChar (nChar, nRepCnt, nFlags);
// Resize edit control if needed
// Get text extent
CString Text;
GetWindowText (Text);
CWindowDC DC (this);
CFont *pFont = GetParent()->GetFont();
CFont *pFontDC = DC.SelectObject (pFont);
CSize Size = DC.GetTextExtent (Text);
DC.SelectObject (pFontDC);
Size.cx += 5; // add some extra buffer
// Get client rect
CRect Rect, ParentRect;
GetClientRect (&Rect);
GetParent()->GetClientRect (&ParentRect);
// Transform rect to parent coordinates
ClientToScreen (&Rect);
GetParent()->ScreenToClient (&Rect);
// Check whether control needs to be resized and whether there is space to grow
if (Size.cx > Rect.Width())
{
if (Size.cx + Rect.left < ParentRect.right )
Rect.right = Rect.left + Size.cx;
else
Rect.right = ParentRect.right;
MoveWindow (&Rect);
}
}
UINT
gxEditCell::OnGetDlgCode()
{
return CEdit::OnGetDlgCode() | DLGC_WANTARROWS | DLGC_WANTTAB;
}
Download demo application - 11 KB

Comments
Organization Gossip : chanel Thought of as A Must In modern times
Posted by incockDak on 03/29/2013 08:03amThe Actual Key On the way to rule the longchamp-arena Is Quite Straight forward! [url=http://growth-management.alachua.fl.us/comprehensive_planning/gucci.html]ããã¯[/url] The Secret dominate the gucci-world Is Fairly Basic! [url=http://growth-management.alachua.fl.us/comprehensive_planning/saclongchamp.php]Sac longchamps[/url] EbrNssYcrDuu [url=http://running-nike0.seesaa.net/]ãã¤ã[/url]SdsAdkZmkXov [[url=http://free-nike-nikeo.seesaa.net/]free nike[/url]WviIftBniMps [url=http://xn--nike-ul4c5c5fyqb.seesaa.net/]ãã¤ãã¹ãã¼ã«ã¼[/url]RbqNgfYflRuw [url=http://nikejapan0.seesaa.net/]ãã¤ãã¹ãã¼ã«ã¼[/url]JdwKcwWgpKpt [url=http://nikesneakersjp.seesaa.net/]nike[/url]EvnDqyEjyZvp [url=http://nikegolf00.seesaa.net/]ãã¤ãã´ã«ã[/url]ZoeBrkAbgTbt [url=http://nikeshoes00.seesaa.net/]nike ã·ã¥ã¼ãº[/url]AaoHleJpbPla [url=http://sneaker-adidas-jp.seesaa.net/]ã¹ãã¼ã«ã¼ adidas[/url]KidSxwArgAui
ReplyThe most important bvlgari purse Company Dialog - Who loves pretty much nothing triumphs??
Posted by expopmerm on 03/22/2013 08:29pm[url=http://www.mcmoutletjpinoue.com]mcm åºè[/url] mcm Offers Fresh, New Life For An Old Topic- Defacto Requirements [url=http://www.mcmsalejapanoka.com]MCM 財å¸[/url] Stimulating Actions All mcm Admirer Really Should Try Out [url=http://www.mcmzankijpshop.com]mcm ããã°[/url] The Way To Stay Away From mcm Mishaps [url=http://www.mcmstorejpkodo.com]MCM 財å¸[/url] mcm Imitations . . . Ideal mcm Hack Which Fools 98% Of The Customers Reliable guidelines for bvlgari purse that can be used beginning straight away. [url=http://www.bvlgarishopjprie.com]ãã«ã¬ãª æè¨[/url] The fundamental principles of the bvlgari purse that you'll take advantage of getting started today. [url=http://www.bvlgarioutletshopjp.com]ãã«ã¬ãªãã«ã¬ãª[/url] Howdy! Together we are able to help make bvlgari purse considerably better ! [url=http://www.bvlgarisalekodojp.com]ãã«ã¬ãª[/url] Summary write-up reveal the unquestionable details about bvlgari purse and also the way it could may affect people. [url=http://www.bvlgarisakaijpsale.com]ãã«ã¬ãª 財å¸[/url] Fresh site exposes the low down around bvlgari purse and as well , reasons why need to take action straight away. [url=http://www.bvlgariaokisalejp.com]ãã«ã¬ãªã¤ã«ã«ãã§[/url] Current market Report : bvlgari purse Defined as A-must At this time End Up Being The 1st To Read What The Researchers Are Saying Around [url=http://www.mcmbagsjphadori.com]MCM åºè[/url] Probably The Most Unnoticed Detail Around mcm
ReplySource code
Posted by Legacy on 10/01/2003 12:00amOriginally posted by: kripa
Lee !!!! can i have the source code of the editable list view??
-
Replyjkj
Posted by huahuajin on 03/18/2008 10:24amdsfs
ReplyOne more fix to correct mouse wheel behavior...
Posted by Legacy on 09/02/2003 12:00amOriginally posted by: Chang
ReplyHandling arrows and tab in modeless dialog box?
Posted by Legacy on 01/08/2003 12:00amOriginally posted by: Eric Lepage
Hello,
This code sample is fabulous. I've been able to reproduce a spreadsheet-like behavior!!!
It works great in modal dialog box but modeless dialogs won't get the arrow and tab keys. I've tried catching them thru OnGetDlgCode() with no success.
Anyone has a suggestion?
Thanks!
Reply
Good but
Posted by Legacy on 07/09/2002 12:00amOriginally posted by: How to add columns?
ReplyInvalid handling of the ESC
Posted by Legacy on 12/11/2001 12:00amOriginally posted by: Stephane Stolz
The ESC is not properly handled.
In this implementation, the assumption made is that the edit will be cancelled only when the ESC key is pressed.
The correct way of handling the changes is to cancel the edit for as long as the text was not changed.
I have modified the code in the following way to fix this:
1. In the constructor, set the Escape to TRUE by default.
2. In OnChar, add a default in the switch statement to set the Escape to FALSE as soon as the user changes the value.
This makes a huge difference if you use this ListCtrl to edit a database. As you navigate through the columns, the database would be updated even though no value was changed.
By adding the above changes, the database will be update only when something was changed.
Other than that, this code is very useful.
ReplyThanks a lot.
I need to do the same but with list controls
Posted by Legacy on 08/14/2001 12:00amOriginally posted by: Nuno Rapaz
How can i do the same in list controls?
ReplyGood But.....
Posted by Legacy on 07/31/2001 12:00amOriginally posted by: Guru
Hi,
I ahve used in this my current project.
It is good.
But I ahve small problem.
For the second and 3rd cols I want to edit.
But the edit control should specify / allow only some particular characters.
Rest it should not accept.
When I tried to do the same by mapping EditCell's OnUpdate, it is throwing Application Error stating that m_hWnd == NULL.
Pls help me.
Regds
ReplyI don't know....
Posted by Legacy on 04/15/2001 12:00amOriginally posted by: Dark
First...
ReplyThanks for your sample project.
It's very useful sample..
Anyway....
I make Dialog Box, and put a List Box in it.
I want to use a member function in the List View, when the List Box is double clickked.
I don'w know how....
How can I do?
Loading, Please Wait ...