Changing a CComboBox style to CBS_SORT

Hi,

I'm trying to change the style of a CComboBox after it has been created.
I want to add & remove the CBS_SORT style.
I use the following code:
m_oCombo.ModifyStyleEx(0, CBS_SORT);
and
m_oCombo.ModifyStyleEx(CBS_SORT, 0);
But none of these lines seems to work.
Is the CBS_SORT style unchangeable after the combo has been created ?

If not, I guess I will have to implement an owner-draw combo-box, and override the CompareItem method.
Does anyone have an example of a DrawItem function for a regular combo-box ?

Thanks for your help.
LVL 1
gurlyAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
fl0ydConnect With a Mentor Commented:
You're right, I just found out myself. I guess I'm finally losing my sanity ;) Anyway, you can find information on the DRAWITEMSTRUCT as well as the CComboBox::DrawItem-function here:
http://msdn.microsoft.com/library/en-us/vcmfc98/html/_mfc_ccombobox.3a3a.drawitem.asp
0
 
fl0ydCommented:
A few things that need clarification:

* Use
m_oCombo.ModifyStyle( 0, CBS_SORT );
to add the CBS_SORT style. It's not an extended style so don't use ModifyStyleEx
* I'm not sure whether this newly set style yields an  immediate response or if it applies only if you add new strings to the combobox.
* You are confusing owner-drawn controls with a derived class. Owner-drawn controls give you the ability to do the drawing of the items yourself. Deriving your own class inherits the entire functionality from the parent and gives you the opportunity to customize every single aspect without changing the rest. So this is what you are looking for, when you want to only change the CompareItem-method.
0
 
gurlyAuthor Commented:
A. You are right about the ModifyStyleEx. I also tried it with ModifyStyle and it didn't work (just didn't notice I haven't changed it back when I put the sample code here).

B. I change the style right after I call ResetContent and just before I fill the combo-box with new strings, and still - it doesn't work.

C. I know the difference between owner-drawn controls and derived classes. The fact is that in order to override the CompareItem method I have to derive my own class from CComboBox and change the control style to owner-drawn.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
fl0ydCommented:
c.)

Where does it say so? The MSDN states that you have to implement CompareItem if you have an owner drawn combo-box. It doesn't say that you have to make it owner-drawn to override the CWnd::OnCompareItem-function.
0
 
gurlyAuthor Commented:
But if the control is not owner-drawn the CompareItem method is never called.
0
 
fl0ydCommented:
That's why I was referring to OnCompareItem...
0
 
gurlyAuthor Commented:
Still - the OnCompareItem is also not called if the control is not owner-drawn.
From MSDN:
"The system sends the WM_COMPAREITEM message to determine the relative position of a new item in the sorted list of an owner-drawn combo box or list box. "
0
 
gurlyAuthor Commented:
Thanks for the link.
By now I implemented something similar myself.
I have one problem, though.
The lpDrawItemStruct->itemData doesn't hold the item text in case I called SetItemData for that item.
I don't want my item data to be a complicated struct holding the item text along with other data I need.
I just need to hold a number with the item.

Any ideas on how I can get the item text in the DrawItem & CompareItem functions ?
0
 
migelCommented:
Hi!
CBS_SORT is the creation time style that is style that control use only during self creation and changing such styles after creation will not change control mode.
IMHO you need destroy existing control and recreate it again with needed style.
0
 
fl0ydCommented:
That's certainly not the way you want to go, migel. Deriving a class from CComcoBox, adding a private

BOOL m_bSort;

and a public member function

BOOL SetSort( BOOL b = TRUE ) { BOOL tmp = m_bSort; m_bSort = b; return tmp; }

will be clearly superior. In your CompareItem()-function add the following line at the very beginning:

if( !m_bSort )
    return;

This is definately a lot better concerning memory footprint, memory fragmentation and, possibly most important, runtime performance. Thinks about all those objects that have to be destroyed and recreated...
0
 
migelCommented:
but for using CompareItem you have to use OWNERDRAW combo isn`t you?
0
 
fl0ydCommented:
And what is the big deal about it?
0
 
migelCommented:
This methods called only when new item added into the combobox.
so if you will use your technique then you anyway will erase all elements and readd they again
0
 
migelCommented:
This methods called only when new item added into the combobox.
so if you will use your technique then you anyway will erase all elements and readd they again
0
 
migelCommented:
This methods called only when new item added into the combobox.
so if you will use your technique then you anyway will erase all elements and readd they again
0
 
fl0ydCommented:
Even if that were the case then at least the entire window isn't destroyed. Think about how your suggestion will flicker... I doubt, that there is the need to re-insert the items though. An InvalidateRect( NULL, FALSE ); should be sufficient.
0
 
gurlyAuthor Commented:
I understand I will have to use an owner-drawn combo-box.
The only question left is:
How can I get the item text in the DrawItem / CopareItem methods, when the item is an actual DWORD set with SetItemData ?
0
 
migelCommented:
did you try it by hand??
0
 
gurlyAuthor Commented:
I understand I will have to use an owner-drawn combo-box.
The only question left is:
How can I get the item text in the DrawItem / CopareItem methods, when the item is an actual DWORD set with SetItemData ?
0
 
gurlyAuthor Commented:
migel,
What do you mean ?
0
 
fl0ydCommented:
Since you called SetItemData, you would know what the DWORD_PTR points to.
0
 
gurlyAuthor Commented:
fl0yd,
You are correct, but as I said earlier, I don't want to save the item text in the data structure.
The DWORD_PTR is extra data for me, not an item identifier.
0
 
migelCommented:
oops my prefious post is for fl0yd
1. Is your combo created with CBS_HASSTRINGS?
if  with than you can use CComboBox::GetLBText(id);
2 or you can use itemData member of the DRAWITEMSTRUCT passed into the DrawItem this member hold data you pass in the SetItemData call

void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

   LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData;
// rest of code
}
0
 
fl0ydCommented:
gurly,
    I assume that itemData points to the actual data you have some means to evaluate the string from there. If you don't want the combobox to store the string for you (which I think is a good choice) it is somewhere stored in the structure/class that itemData points to.
0
 
gurlyAuthor Commented:
migel,

1. LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData;
want get me the item text since it holds the item data.

2. When my combo has the style CBS_HASSTRINGS the CompareItem function is not called.
0
 
migelCommented:
so you need define struct (as fl0yd) that hodls both item string and item data and store pointers to the structs in the item data
you have no another choose
0
 
gurlyAuthor Commented:
fl0yd,
I'm not sure I understand what you mean: how can the combo store the string for me ? Is it by the structure the item data points to (which I don't want to add the string to) ?
Or are you talking about something else ?
0
 
fl0ydCommented:
If you call CComboBox::AddString( LPCTSTR ), then the control stores the string for you. You can delete the c-string that you supplied for this function call after it returned since the control made a copy of it. I'm not sure, how you would get that string when doing the drawing. You will find information on that either from the link I provided above or you will have to look through this section in the msdn.
0
 
gurlyAuthor Commented:
Thanks for your help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.