Click here to Skip to main content
15,666,183 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm trying to dynamically create a CCheckListBox in C++ MFC, but for some reason it automatically sorts the entries alphabetically, which affects the subsequent code. The code used to create it is:

m_List = new(CCheckListBox);
m_List->Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_CHILD | BS_CHECKBOX | WS_VISIBLE , CRect(20, 20, 180, 180), this, 1248);

and the following function adds strings to the checklistbox from a CEdit.

void CCheckListBoxDlg::addEntry()
	CString strTemp;

Note that this does not have the LBS_SORT or LBS_STANDARD properties, yet is sorting anyway. The same code uses CListBox (from which CCheckListBox inherits) without this problem.

What I have tried:

I have recreated this from a blank MFC app to confirm that nothing else in the code is responsible for this, and that the CCheckListBox is sorting at the point of entry.

EDIT: GitHub link. Contains a form with a CCheckListBox, a CEdit and a CButton that adds the contents of the CEdit to the CCheckListBox.

I have also tried to use ModifyStyle/Ex to remove the LBS_SORT property that it shouldn't have, but this has no effect.
Updated 28-Oct-20 14:41pm
Shao Voon Wong 27-Oct-20 20:44pm    
Can you upload your blank MFC app (that reproduce the problem) to GitHub and we'll take a look.
Spam78 28-Oct-20 11:23am
Rick York 27-Oct-20 21:50pm    
A question for you : does CCheckListBox render itself correctly for you? For many years it never would for me and it was annoying enough that I bagged its use entirely a while ago. I write a custom, resizable dialog with a derived CListCtrl that included the checkboxes and this works much better for me.
Spam78 28-Oct-20 11:24am    
It seems to work fine for me. I haven't played around with fonts or anything like that, but the default style renders correctly.

Often sorting a list is preferred behavior by the user and it's easy enough to deal with that. When you call AddString it returns an index. You can then call SetItemData and pass it a pointer or value to associate with that entry in the list. With this association made, when the user clicks OK or double clicks or what ever other event you monitor to select an item occurs you can call GetCurSel to get the current selection and then, with that index, you can call GetItemData to obtain the value or pointer you previously associated with that list item. Using this method allows you to sort a list or not and your code doesn't have to care because you have associated your data with the items in the list.

I do this so often that I made little wrappers to add a string and a data value with one call. It pairs the two calls mentioned above, AddString and SetItemData together as one call - AddStringData. I also made a corresponding function to obtain the selected string and its data : GetSelectedStringData, which wraps GetCurSel, GetItemData, and GetString (I think it is) together.
Share this answer
Rick York 28-Oct-20 13:22pm    
BTW - you might note I mentioned above that I stopped using CCheckListBox a while ago and I have. As also mentioned, it is derived from CListBox. The things I mentioned in my post all pertain to CListBox specifically but because of the derivation they work with a CCheckListBox also.
After removing BS_CHECKBOX from Create(), it does not sort now.
m_List->Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE , CRect(20, 20, 180, 180), this, 1248);
Share this answer
Spam78 29-Oct-20 12:18pm    
Excellent. I can't seem to remember why I put that there in the first place, but it all seems to work without it. Thanks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900