gurly
asked on
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.
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
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.
ASKER
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.
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.
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-functi on.
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-functi
ASKER
But if the control is not owner-drawn the CompareItem method is never called.
That's why I was referring to OnCompareItem...
ASKER
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. "
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. "
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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 ?
By now I implemented something similar myself.
I have one problem, though.
The lpDrawItemStruct->itemData
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 ?
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.
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.
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...
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...
but for using CompareItem you have to use OWNERDRAW combo isn`t you?
And what is the big deal about it?
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
so if you will use your technique then you anyway will erase all elements and readd they again
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
so if you will use your technique then you anyway will erase all elements and readd they again
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
so if you will use your technique then you anyway will erase all elements and readd they again
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.
ASKER
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 ?
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 ?
did you try it by hand??
ASKER
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 ?
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 ?
ASKER
migel,
What do you mean ?
What do you mean ?
Since you called SetItemData, you would know what the DWORD_PTR points to.
ASKER
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.
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.
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(LPDR AWITEMSTRU CT lpDrawItemStruct)
{
LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData ;
// rest of code
}
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(LPDR
{
LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData
// rest of code
}
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.
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.
ASKER
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.
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.
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
you have no another choose
ASKER
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 ?
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 ?
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.
ASKER
Thanks for your help.
* 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.