|
I am trying to create a complicated MFC tree control that has the edit and combobox control capabilities that this tutorial has. However, I found that this sample is not flexible enough to actually use.
1) The one combobox example initializes the box with hard coded strings and cannot be used for more than one box in the tree.
2) The placement of the initialization of the data in the DoDataExchange function doesn't make sense to me. I don't want the entire control to have to reinitialize everything every time there is a UdateData call.
3) I could not add the combobox and edit items as children, because there is no InsertItem function that will take an image index and the handle to the parent.
4) The image indexes are all hard coded, as is the resource ID of the actual tree.bmp file for the icons. It would take modifications to make this work as a more flexible class that could be used for more than one tree control in a project.
Now, in all fairness, my understanding of MFC is still rudimentary. I am impressed with the author's ability to even write this. I did learn some things from this sample.
I would be much more impressed if this class could be used to support more than one type of tree control.
Thanks.
|
|
|
|
|
I was able to use/modify the code to work for combo boxes and edit controls the way I wanted them to, without any icons.
So, Thanks for the code. With a little effort it really does work.
|
|
|
|
|
I would like to use CTreeOptionsCtrl in a splitter window in a Doc/View app.
The MFC CTreeCtrl is created automatically and accessed through CTreeView::GetTreeCtrl(), how do I get a CTreeOptionsCtrl created instead?
|
|
|
|
|
Tick-boxes ungray themselves if I change their state, I have fixed the problem mainly by moving all the bitmaps up by one, and some fixes to the code. anywone want it, just mail me. I am mailing it to author:JP Naughter.
I did not like the "edit-box" and combo-box mechanism, and instead put the edit control just below the tree, with a prompt, this is less messy, since the edit-box sometimes appears chopped off if the tree is wide, + the tree's own tooltip gets in the way!!!
I also have a problem with parent window notification, but worked around it in a nasty way, using sendmessage to the control parent since the parent dialog never got the TVN_SELCHANGED, and I wanted it in the parent, messy way to do lots of NOTIFY messages. MFC is at fault this time I know.
Conrad - conradb@adroit.co.za
Always do badly to start off, that way when you get the hang of it suddenly, everyone is surprised.
|
|
|
|
|
I'd suggest you pull down the latest version from my web site at www.naughter.com as there has been numerous updates since I posted this article to codeproject (27 updates in fact since it was posted on codeproject).
|
|
|
|
|
TA, will do.
Conrad - conradb@adroit.co.za
Always do badly to start off, that way when you get the hang of it suddenly, everyone is surprised.
|
|
|
|
|
i want to add icons for items of tree control .please tell me what's the problems of this code.
CImageList m_imgList;
CWinApp* papp=AfxGetApp();
if(papp!=0) {
HICON hicon1,hicon2;
hicon1=papp->LoadIcon(IDI_ICON1);
hicon2=papp->LoadIcon(IDI_ICON2);
m_imgList.Add(hicon1);
m_imgList.Add(hicon2);
m_tree.SetImageList(&m_imgList,TVSIL_NORMAL);
HTREEITEM chapter;
chapter=m_tree.InsertItem("country",0,0);
m_tree.InsertItem("canada",1,1,chapter);
chapter=m_tree.InsertItem("person",0,0);
m_tree.InsertItem("sonya",1,1,chapter);}
|
|
|
|
|
I'd check the return value from the functions: LoadIcon, CImageList::Add, SetImageList and InsertItem. I'd also suggest that your create a bitmap resource and use that as your image list. See the sample app for how this is done. Also don't forget to pull down the latest version from my web site at www.naugter.com.
|
|
|
|
|
Hi there. I am looking to be able to load the contents of combo boxes at runtime. For example, in our code when we want to populate a combo box, we fill in a vector of strings and pass it to the GUI code, which then adds them.. (Our GUI is localized; there are two versions of everything: "external" for the GUI, "internal" to be stored internally. We also use plugins, where the available settings from plugin to plugin might be different.)
How hard would it be to rewrite/adapt the code (assuming I do it) to make this possible? One method that comes to mind would be to change the code so that rather than store a class type in the dialog data, we store an abstract id, that can be resolved to a class type plus a specific instance of that class, which we could invoke to add strings directly (using an extended interface)..
|
|
|
|
|
To add strings at runtime to a combo box just use CComboBox::AddString. If you mean in combination with my TreeOptionsctrl, then look at the sample which comes with it, specifically the "CDowComboBox" class.
As regards localisation, all the strings which the class uses are taken from string table resources, so you should just need to translate these.
|
|
|
|
|
Don't worry about localisation; I was just mentioning it in passing.
As to CDowComboBox , in the example the strings are hard-coded into the Create() member function. At the moment, when you add a combo box, it looks like this:
AddComboBox(HTREEITEM, RUNTIME_CLASS(CDowComboBox))
I want to be able to reuse CDowComboBox for two completely different combo boxes, each with different available settings. So imagine I add a parameter to the constructor (or whereever), passing a vector of strings, which would then be consumed in the Create() function to build the combo box content. Can this be done?
Bonus question: How would I completely clear out the strings from an existing combo box, and readd different strings? (Some controls filter the content displayed in other controls.)
|
|
|
|
|
Here is an example of what I'm looking to do:
vector<string> strings1;
strings1.push_back("Option #1");
strings1.push_back("Option #2");
CTreeOptionsCombo myCombo1(strings1);
m_ctrlTree.AddComboBox(HTREEITEM, myCombo1.GetRuntimeClass());
vector<string> strings2;
strings2.push_back("Option A");
strings2.push_back("Option B");
strings2.push_back("Option C");
CTreeOptionsCombo myCombo2(strings2);
m_ctrlTree.AddComboBox(HTREEITEM, myCombo2.GetRuntimeClass()); Where CTreeOptionsCombo has been modified as follows: (some changes not listed)
CTreeOptionsCombo::CTreeOptionsCombo(const vector<imn_string> & strings)
: m_pTreeCtrl(NULL), m_strings(strings)
{
}
int CTreeOptionsCombo::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
vector<imn_string>::iterator iter;
for (iter=m_strings.begin(); iter!=m_strings.end(); iter++)
{
AddString(iter->c_str());
}
return 0;
} Note that the CTreeOptionsCombo object would be owned by the caller, not by the CTreeOptionsCtrl . At the moment, this blows up because the CTreeOptionsCtrl is still expecting to create the object. It would be best if I could take ownership of the object, though, so I can invoke the normal MFC combo box API when I need to. (To add or remove strings, change the selection, change the drop width, etc.)
Perhaps instead of this:
m_ctrlTree.AddComboBox(HTREEITEM, myCombo1.GetRuntimeClass());
do this instead (after the necessary changes, of course)?
m_ctrlTree.AddComboBox(HTREEITEM, &myCombo1);
|
|
|
|
|
You can do this quite easily by using something like:
AddComboBox(nCurrentIndex, RUNTIME_CLASS(CDowComboBox), (DWORD)&some_stack_based_CStringArray);
Then in:
int CDowComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//Let the base class do its thing
if (CListOptionsCombo::OnCreate(lpCreateStruct) == -1)
return -1;
//Get the ListOptionsCtrl item data
CListOptionsItemData* pItemData = (CListOptionsItemData*)m_pListCtrl->GetItemData(m_nListCtrlIndex);
//Cast this controls item data back to a CStringArray
CStringArray* pNames = (CStringArray*)pItemData->m_dwItemData;
ASSERT(pNames)
{
for (int nIndex = 0; nIndex < pNames->GetSize(); nIndex++)
AddString(pNames->GetAt(nIndex));
}
return 0;
}
Bonus Question Answer: If you use the above mechanism then whenever you change what is in "some_stack_based_CStringArray" somewhere else in your code, then these changes will be reflected into the combo box when it is recreated.
|
|
|
|
|
Can you change the code a little bit to allow the radio group span over two or more parent nodes. I need a tree control that shows radio options under different categories. Something like this:
Category A:
Radio1
Radio2
Radio3
...
Category B:
Radio4
Radio5
...
All these raido buttons belong to one group. Thanks!
|
|
|
|
|
I'm not sure this is a very useful addition. It's definitely a non - standard UI and IMHO would confuse end users. You are free of course to derive your own class from mine and modify it to suit your means.
|
|
|
|
|
I use your source in my project,but compile failure,the cause is "LNK erro can
not open file 'mfc42u.lib'",I do not know in your source where the mfc42u.lib is
used, I look into msdn ,but can not find it.
merry chrismtas!
thanks!
|
|
|
|
|
Try building the "Win32 Debug" or "Win32 Release" configuration as you are trying to build the Unicode Debug version and do not have the appropiate libraries installed.
|
|
|
|
|
Thank you very much. My project has this error,too.
I was try follow your instruction and successful.
dai dien
|
|
|
|
|
You need to install Service Pack1 in order to fix his error.
This pack contains this lib.
Leonardo X. T. Cardoso
|
|
|
|
|
Sorry but I think you are incorrect on this. As I have already pointed out, you need to do a custom install of VC 6 to get the Unicode MFC libraries installed. It has nothing to do with the version of OS service pack or compiler service pack you have installed.
|
|
|
|
|
I tried to extend the control for supporting multiline editboxes. There is a structure called TVITEMEX. I used iIntegral to increase the height of the items. This height is in increments of the standard item height (see TVM_SETITEMHEIGHT). By default, each item gets one increment of item height. Setting this member to 2 will give the item twice the standard height; setting this member to 3 will give the item three times the standard height; and so on. So far so good. The trouble is that scrolling of the tree don't works well any more. Has anybody an idea? T hanx.
|
|
|
|
|
Instead of trying it this way, why did use the existing support for edit boxes and instead specify ES_MULTILINE and ensure the edit box is created with the height you want. Just like the way normal drop down combos work.
|
|
|
|
|
The idea is that the text (contents) of the edit box should appear as item label in the tree after destroying the box by losing the focus. But there is too few space between the items for more than one row of text. In a combo box you select only one row. Therefore it isn't a problem to draw the text selected as item in the tree.
|
|
|
|
|
When you have multiple levels of checkboxes, and change the state of a checkbox, the state is updated only for the immediately parent and the childs of this checkbox.
This update should be completely recursive.
I've made the changes for my needs, and for the moment, I don't have enough time to post it.
If someone wants the code to do that, please mail me.
|
|
|
|
|
Yes I would,I have fixed a different bug, and encountered the same need to be able to gray out an entire branch in one call.
I fixed a problem where graying a tick-box, and then turning it on/off was ungraying it. I consequently fixed a couple of errors in that regard.
I also have a problem with parent window notification, but worked around it in a nasty way, using senmessage to the control parent since the parent dialog never got the TVN_SELCHANGED, and I wanted it in the parent, ....how do I get it to echo? did U fix this?
I want to post my fix all-together to JP Naughter, since I am currently working on this all.
Conrad - conradb@adroit.co.za
Always do badly to start off, that way when you get the hang of it suddenly, everyone is surprised.
|
|
|
|