From: David Connet on
"Bill Brehm" <don't want spam> wrote in
news:ueXDrItrIHA.3632(a)TK2MSFTNGP04.phx.gbl:

> Joe,
>
> Good point about the zero sized row.
>
> I already provide all the data to the list control via the callback
> OnGetdispinfoList(). I set the Owner Data attribute without changing
> anything else. Apparently the lParam is no longer stored in the item
> so my program displays the first item in each location. I can use the
> iItem number instead to solve that and it looks correct. Sorting gives
> an ASSERT now but that depends on lParam too so it's not surprising.
> However, how do I solve that because I can't get at the iItem number
> in the compare function.
>
> Also, how do I deal with the number of items in the list control? I
> could imagine I just set the size of the list to the total number of
> items I should be displaying. It should be fast to do that - the
> control just allocates or deallocates memory. Is that correct?

In addition to what others have commented, another thing you can do is
allocate a data structure containing your data and set that as the list
item's data. Now lParam is set, and you can use the listctrl's sorting.
The key here is to handle the LVN_DELETEITEM message and delete your
data.

My data hasn't grown so large that I need a virtual list yet.

> Lastly, is it possible to edit a list control subitem in place? If
> not, what is the purpose of EditLabel()? Oh wait. I set Edit Labels.
> Now I can get an in place edit of the first column. How can I do the
> other columns?

I modified my list control to be able to do this using
http://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/arti
cle.php/c923/ as a starting point. I remember there were a couple things
I had to add that weren't handled well - like when you use the mouse
wheel to scroll (so the edit box doesn't lose focus) [in the parent
control, I set focus to that to cause the edit control to lose focus].
You can also use other controls (like a combo box).

If you want to take a look at mine, it's at
http://sourceforge.net/projects/agilitybook (specifically, the
ListCtrl.cpp file - look at the SVN code, the released source zip doesn't
have that functionality yet - I'm still working on the workflow in the
program to make use of it)

Dave Connet
From: "Bill Brehm" don't want on
I was wondering if there is a way to display something other than text in a
subitem. Two things come to mind.

1. Could I put a checkbox in as one of the items? I would like to use it to
display a boolean value and also to allow that value to be editted.
2. Could I use one column to display the tree control type of + and - (and
maybe lines) that I could click and expand groups of items. What i'm looking
for is something like Excel's grouping capability, rather than a tree
control next to a list control, as in File Explorer. If not, what do you
think about putting a tree control next to or on top of a column of a list
control?

Thanks,

Bill

"Tom Serface" <tom.nospam(a)camaswood.com> wrote in message
news:EE4BFD17-0635-434D-BDE3-6AF0603E1E05(a)microsoft.com...
>I typically sort the items in my memory list (the one the list control is
>calling on to get it's value line by line). Of course the memory list can
>be just about anything, but for me it's typically a vector of CObList of
>objects so sorting is usually based off of one of the items in the object.
>For example, I typically have a list of items that I just call a routine on
>like:
>
> bool CDialogWithList::CompareAndSwapString1(int pos, bool bAscending)
> {
> CMyObjectInfo *temp;
> int posFirst = pos;
> int posNext = pos + 1;
>
> if(!bAscending) {
> if (((CMyObjectInfo *)GetAt(posFirst))->m_csString1 <
> ((CMyObjectInfo *)GetAt(posNext))->m_csString1) {
> temp = (CMyObjectInfo *)GetAt(posFirst);
> SetAt(posFirst, GetAt(posNext));
> SetAt(posNext, temp);
> return TRUE;
> }
> }
> else if (((CMyObjectInfo *)GetAt(posFirst))->m_csString1 >
> ((CMyObjectInfo *)GetAt(posNext))->m_csString1) {
> temp = (CMyObjectInfo *)GetAt(posFirst);
> SetAt(posFirst, GetAt(posNext));
> SetAt(posNext, temp);
> return TRUE;
> }
> return FALSE;
> }
>
> bool CDataFileArray::CompareAndSwapDate(int pos, bool bAscending)
> {
> CMyObjectInfo *temp;
> int posFirst = pos;
> int posNext = pos + 1;
> if(!bAscending) {
> if (((CMyObjectInfo *)GetAt(posFirst))->m_cDate <
> ((CMyObjectInfo *)GetAt(posNext))->m_cDate) {
> temp = (CMyObjectInfo *)GetAt(posFirst);
> SetAt(posFirst, GetAt(posNext));
> SetAt(posNext, temp);
> return TRUE;
> }
> }
> else if (((CMyObjectInfo *)GetAt(posFirst))->m_cDate >
> ((CMyObjectInfo *)GetAt(posNext))->m_cDate) {
> temp = (CMyObjectInfo *)GetAt(posFirst);
> SetAt(posFirst, GetAt(posNext));
> SetAt(posNext, temp);
> return TRUE;
> }
> return FALSE;
> }
>
> Then I call a routine to Sort the object list like:
>
> void CMyDialogWithList::Sort(MY_DATA_SORT_ITEMS nSort, bool bAscending)
> {
> bool bNotDone = TRUE;
> int pos = 0;
>
> while (bNotDone) {
> bNotDone = FALSE;
> switch(nSort) {
> case MY_DATA_SORT_NONE:
> break;
> case MY_DATA_SORT_STRING1:
> for(pos = 0;pos < GetUpperBound();pos++)
> bNotDone |= CompareAndSwapString1(pos, bAscending);
> break;
> case MY_DATA_SORT_STRING2:
> for(pos = 0;pos < GetUpperBound();pos++)
> bNotDone |= CompareAndSwapString2(pos, bAscending);
> break;
> case MY_DATA_SORT_DATE:
> for(pos = 0;pos < GetUpperBound();pos++)
> bNotDone |= CompareAndSwapDate(pos, bAscending);
> break;
> default:
> break;
> };
> }
> }
>
> So I don't use the sort mechanism in the list control at all. When the
> column wants to sort I just sort the list then refresh the current screen
> and only the items on the screen are drawn. I also move it back to the
> top of the list when someone sorts one of the columns. I think is sort of
> expected behavior. This is may not be the most efficient method for doing
> sorting, but it works well and keeps the object list in an order that I
> can write out and read back in the same order as the user last sorted.
>
> Also, you can edit sub-items, but you have create your own edit control or
> trick it into think it is colums 0. For example:
>
> http://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/article.php/c4175/
>
> It's not that difficult once you get it implemented.
>
> Tom
>
> "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
> news:cllu14ti1a6i5oebn448d47l9rpbga6gfs(a)4ax.com...
>> See below..
>
>>>program displays the first item in each location. I can use the iItem
>>>number
>>>instead to solve that and it looks correct. Sorting gives an ASSERT now
>>>but
>>>that depends on lParam too so it's not surprising. However, how do I
>>>solve
>>>that because I can't get at the iItem number in the compare function.
>> ****
>> Tom Serface is our virtual-CListCtrl guru, perhaps he can answer this.
>> I've not used
>> virtual controls because I typically have a small number of items to
>> store, and there are
>> only a few cases where I *should* have used one, but because it was not a
>> "product
>> deliverable" but a personal hobby project, I didn't bother.
>> ****
>>>
>>>Also, how do I deal with the number of items in the list control? I could
>>>imagine I just set the size of the list to the total number of items I
>>>should be displaying. It should be fast to do that - the control just
>>>allocates or deallocates memory. Is that correct?
>> ****
>> For a virtual control, there is no allocation at all, which is why you
>> get the
>> performance.
>> ***
>>>
>>>Lastly, is it possible to edit a list control subitem in place? If not,
>>>what
>>>is the purpose of EditLabel()? Oh wait. I set Edit Labels. Now I can get
>>>an
>>>in place edit of the first column. How can I do the other columns?
>> ****
>> Due to fundamental failures of design, a CListCtrl only allows the
>> editing of the 0th
>> elment, making it nearly useless for anything that has sophisiticated
>> constraints (for
>> example, I'd like the 0th element to be the index, but now I have to get
>> into manipulating
>> the column order to make the one-and-only-editable-field be the logical
>> column 0 while
>> displaying some other column in the leftmost position, a real pain). I
>> think there are
>> some articles in www.codeproject.com on creating a CListCtrl subclass in
>> which any column
>> can be edited, and I would consider looking there first.
>> joe
>> ****
>


From: Tom Serface on
You may just want to try something like this:

http://69.10.233.10/KB/list/xlistctrl.aspx

Even if you don't use the class you can look at the code to see how some of
the stuff is done. It was updated pretty recently.

Tom

"Bill Brehm" <don't want spam> wrote in message
news:%23euE8xWsIHA.4392(a)TK2MSFTNGP03.phx.gbl...
>I was wondering if there is a way to display something other than text in a
>subitem. Two things come to mind.
>
> 1. Could I put a checkbox in as one of the items? I would like to use it
> to display a boolean value and also to allow that value to be editted.
> 2. Could I use one column to display the tree control type of + and - (and
> maybe lines) that I could click and expand groups of items. What i'm
> looking for is something like Excel's grouping capability, rather than a
> tree control next to a list control, as in File Explorer. If not, what do
> you think about putting a tree control next to or on top of a column of a
> list control?
>
> Thanks,
>
> Bill
>

From: Joseph M. Newcomer on
Use custom-draw and you can display anything you want. I've displayed a check box,
although I was too lazy to write the code to detect the OnLButtonDown in the check box to
allow it to be changed, but that was because it was a personal project.

I've done expanding controls like list controls in CListBox, and I did it by using a
variable-height box (the limit is 255 pixels, and the nature of the data was that there
were between 1 and 5 subitems if the user wanted to see them, so we were within the 255
pixel limit). I do not know if there is a similar height restriction on CListCtrl items.

However, it sounds more like you want a custom grid control than a custom CListCtrl.
joe

On Fri, 9 May 2008 08:34:44 +0800, "Bill Brehm" <don't want spam> wrote:

>I was wondering if there is a way to display something other than text in a
>subitem. Two things come to mind.
>
>1. Could I put a checkbox in as one of the items? I would like to use it to
>display a boolean value and also to allow that value to be editted.
>2. Could I use one column to display the tree control type of + and - (and
>maybe lines) that I could click and expand groups of items. What i'm looking
>for is something like Excel's grouping capability, rather than a tree
>control next to a list control, as in File Explorer. If not, what do you
>think about putting a tree control next to or on top of a column of a list
>control?
>
>Thanks,
>
>Bill
>
>"Tom Serface" <tom.nospam(a)camaswood.com> wrote in message
>news:EE4BFD17-0635-434D-BDE3-6AF0603E1E05(a)microsoft.com...
>>I typically sort the items in my memory list (the one the list control is
>>calling on to get it's value line by line). Of course the memory list can
>>be just about anything, but for me it's typically a vector of CObList of
>>objects so sorting is usually based off of one of the items in the object.
>>For example, I typically have a list of items that I just call a routine on
>>like:
>>
>> bool CDialogWithList::CompareAndSwapString1(int pos, bool bAscending)
>> {
>> CMyObjectInfo *temp;
>> int posFirst = pos;
>> int posNext = pos + 1;
>>
>> if(!bAscending) {
>> if (((CMyObjectInfo *)GetAt(posFirst))->m_csString1 <
>> ((CMyObjectInfo *)GetAt(posNext))->m_csString1) {
>> temp = (CMyObjectInfo *)GetAt(posFirst);
>> SetAt(posFirst, GetAt(posNext));
>> SetAt(posNext, temp);
>> return TRUE;
>> }
>> }
>> else if (((CMyObjectInfo *)GetAt(posFirst))->m_csString1 >
>> ((CMyObjectInfo *)GetAt(posNext))->m_csString1) {
>> temp = (CMyObjectInfo *)GetAt(posFirst);
>> SetAt(posFirst, GetAt(posNext));
>> SetAt(posNext, temp);
>> return TRUE;
>> }
>> return FALSE;
>> }
>>
>> bool CDataFileArray::CompareAndSwapDate(int pos, bool bAscending)
>> {
>> CMyObjectInfo *temp;
>> int posFirst = pos;
>> int posNext = pos + 1;
>> if(!bAscending) {
>> if (((CMyObjectInfo *)GetAt(posFirst))->m_cDate <
>> ((CMyObjectInfo *)GetAt(posNext))->m_cDate) {
>> temp = (CMyObjectInfo *)GetAt(posFirst);
>> SetAt(posFirst, GetAt(posNext));
>> SetAt(posNext, temp);
>> return TRUE;
>> }
>> }
>> else if (((CMyObjectInfo *)GetAt(posFirst))->m_cDate >
>> ((CMyObjectInfo *)GetAt(posNext))->m_cDate) {
>> temp = (CMyObjectInfo *)GetAt(posFirst);
>> SetAt(posFirst, GetAt(posNext));
>> SetAt(posNext, temp);
>> return TRUE;
>> }
>> return FALSE;
>> }
>>
>> Then I call a routine to Sort the object list like:
>>
>> void CMyDialogWithList::Sort(MY_DATA_SORT_ITEMS nSort, bool bAscending)
>> {
>> bool bNotDone = TRUE;
>> int pos = 0;
>>
>> while (bNotDone) {
>> bNotDone = FALSE;
>> switch(nSort) {
>> case MY_DATA_SORT_NONE:
>> break;
>> case MY_DATA_SORT_STRING1:
>> for(pos = 0;pos < GetUpperBound();pos++)
>> bNotDone |= CompareAndSwapString1(pos, bAscending);
>> break;
>> case MY_DATA_SORT_STRING2:
>> for(pos = 0;pos < GetUpperBound();pos++)
>> bNotDone |= CompareAndSwapString2(pos, bAscending);
>> break;
>> case MY_DATA_SORT_DATE:
>> for(pos = 0;pos < GetUpperBound();pos++)
>> bNotDone |= CompareAndSwapDate(pos, bAscending);
>> break;
>> default:
>> break;
>> };
>> }
>> }
>>
>> So I don't use the sort mechanism in the list control at all. When the
>> column wants to sort I just sort the list then refresh the current screen
>> and only the items on the screen are drawn. I also move it back to the
>> top of the list when someone sorts one of the columns. I think is sort of
>> expected behavior. This is may not be the most efficient method for doing
>> sorting, but it works well and keeps the object list in an order that I
>> can write out and read back in the same order as the user last sorted.
>>
>> Also, you can edit sub-items, but you have create your own edit control or
>> trick it into think it is colums 0. For example:
>>
>> http://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/article.php/c4175/
>>
>> It's not that difficult once you get it implemented.
>>
>> Tom
>>
>> "Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message
>> news:cllu14ti1a6i5oebn448d47l9rpbga6gfs(a)4ax.com...
>>> See below..
>>
>>>>program displays the first item in each location. I can use the iItem
>>>>number
>>>>instead to solve that and it looks correct. Sorting gives an ASSERT now
>>>>but
>>>>that depends on lParam too so it's not surprising. However, how do I
>>>>solve
>>>>that because I can't get at the iItem number in the compare function.
>>> ****
>>> Tom Serface is our virtual-CListCtrl guru, perhaps he can answer this.
>>> I've not used
>>> virtual controls because I typically have a small number of items to
>>> store, and there are
>>> only a few cases where I *should* have used one, but because it was not a
>>> "product
>>> deliverable" but a personal hobby project, I didn't bother.
>>> ****
>>>>
>>>>Also, how do I deal with the number of items in the list control? I could
>>>>imagine I just set the size of the list to the total number of items I
>>>>should be displaying. It should be fast to do that - the control just
>>>>allocates or deallocates memory. Is that correct?
>>> ****
>>> For a virtual control, there is no allocation at all, which is why you
>>> get the
>>> performance.
>>> ***
>>>>
>>>>Lastly, is it possible to edit a list control subitem in place? If not,
>>>>what
>>>>is the purpose of EditLabel()? Oh wait. I set Edit Labels. Now I can get
>>>>an
>>>>in place edit of the first column. How can I do the other columns?
>>> ****
>>> Due to fundamental failures of design, a CListCtrl only allows the
>>> editing of the 0th
>>> elment, making it nearly useless for anything that has sophisiticated
>>> constraints (for
>>> example, I'd like the 0th element to be the index, but now I have to get
>>> into manipulating
>>> the column order to make the one-and-only-editable-field be the logical
>>> column 0 while
>>> displaying some other column in the leftmost position, a real pain). I
>>> think there are
>>> some articles in www.codeproject.com on creating a CListCtrl subclass in
>>> which any column
>>> can be edited, and I would consider looking there first.
>>> joe
>>> ****
>>
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm