CTreeCtrl-derived object into CTreeView
Serge Wautier -- serge.wautier@ontonet.be Monday, October 21, 1996 Environment: Visual C++ 4.1 / Windows 95 Hi All, Just a short reflection about CTreeCtrl & CTreeView : I wrote a class derived from CTreeCtrl. Using this class, the treeview control fills according to a document passed at creation time and it has its own message-handler to react to UI. Also, it has its own data-members (BTW : Message reflection is a great mechanism). Since i talk of getting info from document, you'll say that i'd better use a CTreeView. Actually that's what i first did. But i wanted to be able to reuse my treeview in a dialog. So i moved the code from a CTreeView-derived class to a CTreeCtrl derived-class. This way, i get a reusable CTreeCtrl that i can put in a dlg or in a view. ..."or in a view" ? Well I first thought it would be peanuts to turn the treeview of a CTreeView into a CMyTreeCtrl : Just change the "m_TreeCtrl" of the CTreeView (the one returned by GetTreeCtrl()) into a CMyTreeCtrl and overide GetTreeCtrl to return the new type... Not so cool ! CTreeView doesn't have a "m_TreeCtrl" member. GetTreeCtrl() simply casts the view to a CTreeCtrl. Which means the view actually is a treeview control, and not, as i thought, a simple window which contains a control that "covers" it. Since the view is basically a tree control, i can hardly add the CMyTreeCtrl to it. (I tried to add a CMyTreeCtrl member to it and Attach() it to the control but it doesn't work too well). The only solution i found is to derive my view from CView instead of CTreeView and add a treeview control into it. CMyView::OnSize() resizes the control as well in order to make it fit the size of the view. This works fine. But i have the feeling that this reduces a lot the interest of a class such as CTreeView. Does anyone think of a "nicer" solution to solve this problem ? Any hint welcome. Serge Wautier, Techno Trade s.a. Belgium serge.wautier@ontonet.be http://www.tbox.fr
Randy Taylor -- drt@ebt.com Tuesday, October 22, 1996 [Mini-digest: 3 responses] Tip: always prefer to derive your enhancements to common control windows from CCtrlView if you wish to use your work in both dialogs and part of the MFC Doc/View architecture. (Or simply derive from the specific CCtrlView derivative which you are interested in like CTreeView). CView derivatives CAN be used on dialogs and as CView windows in the MFC Doc/View architecture, but the reverse is NOT true: classes which are not derived from CView can never become CView classes regardless of how many casts you try to use. A difference between CView derivatives and the common control wrapper classes (such as CTreeView) is that the CView::PostNcDestroy function assumes that the class is allocated on the heap and therefore uses the delete operator on itself (delete this). You'll need to override PostNCDestroy to check whether the object is heap or stack allocated. Only "delete this" if it's heap allocated. here's what I did: If somebody can tell me a better way to do this, I'd appreciate it. void MyBeautifulTreeViewDerivative::PostNcDestroy() { // default for views is to allocate them on the heap // the default post-cleanup is to 'delete this'. // never explicitly call 'delete' on a view // NOTE: How can I tell if I'm heap or stack based? // Maybe I'll just have to be re-written to be only allocated on EITHER heap or stack. if (GetSafeHwnd()) { CWnd* wndParent = GetTopLevelParent(); if (wndParent && wndParent->IsKindOf(RUNTIME_CLASS(CDialog)) == FALSE) delete this; } } randy_taylor@ebt.com >Environment: Visual C++ 4.1 / Windows 95 > >Hi All, > >Just a short reflection about CTreeCtrl & CTreeView : > >I wrote a class derived from CTreeCtrl. Using this class, the treeview >control fills according to a document passed at creation time and it has >its own message-handler to react to UI. Also, it has its own data-members >(BTW : Message reflection is a great mechanism). > >Since i talk of getting info from document, you'll say that i'd better use >a CTreeView. Actually that's what i first did. But i wanted to be able to >reuse my treeview in a dialog. So i moved the code from a CTreeView-derived >class to a CTreeCtrl derived-class. This way, i get a reusable CTreeCtrl >that i can put in a dlg or in a view. > >..."or in a view" ? Well I first thought it would be peanuts to turn the >treeview of a CTreeView into a CMyTreeCtrl : Just change the "m_TreeCtrl" >of the CTreeView (the one returned by GetTreeCtrl()) into a CMyTreeCtrl and >overide GetTreeCtrl to return the new type... > >Not so cool ! CTreeView doesn't have a "m_TreeCtrl" member. GetTreeCtrl() >simply casts the view to a CTreeCtrl. Which means the view actually is a >treeview control, and not, as i thought, a simple window which contains a >control that "covers" it. > >Since the view is basically a tree control, i can hardly add the >CMyTreeCtrl to it. (I tried to add a CMyTreeCtrl member to it and Attach() >it to the control but it doesn't work too well). > >The only solution i found is to derive my view from CView instead of >CTreeView and add a treeview control into it. CMyView::OnSize() resizes the >control as well in order to make it fit the size of the view. >This works fine. > >But i have the feeling that this reduces a lot the interest of a class such >as CTreeView. > >Does anyone think of a "nicer" solution to solve this problem ? >Any hint welcome. > > >Serge Wautier, >Techno Trade s.a. >Belgium >serge.wautier@ontonet.be >http://www.tbox.fr > > -----From: "Michael J. Morel"Your message could have been about me. I did the same thing with a = database-enabled CListCtrl, went through the exact same steps. I was = also surprised to find that CListView is actually just creating itself = as a tree control class, and casting itself to a CListCtrl. In the end, = I also created a CView-derived class and filled the client area with the = control. I guess I'm not helping you at all, but I'm at least verifying = that neither of us are nuts - or both of us are. Mike Morel Mushroom Software Home of MFC For Yourself http://www.mushroomsoft.com/mushroom -----From: James Durie You could try this: Have a CMyTreeView containing m_TreeCtrl which is an instance of your CMyTreeCtrl then in the OnCreate or maybe OnInitialUpdate do: m_TreeCtrl.SubclassWindow(GetTreeControl()->GetSafeHwnd()); I have done something similar for PropertySheets and my own tab control. -- James Durie | Atlas Products International Ltd, (james@apiltd.demon.co.uk) | Quay West, Trafford Wharf Road, "Smile, It's Tate & Lyle" | Manchester, M17 1HH, England. - Gary Rhodes | +44 161 872 2022, Fax +44 161 872 2024 Disclaimer: The views represented here are mine and not those of Atlas Products International Ltd.
Philip Shaffer -- shafferp@mindspring.com Sunday, October 27, 1996 The CCtrlView and it's derived subclasses (CTreeView and CListView) are = designed to use superclassed controls, not subclassed controls. If you = look at the CTreeView and CListView constructors, they pass in the = windows class name for their respective control types which is stored by = the CCtrlView constructor in an instance variable named m_szClassName = (or something similar). This is the class name used in the Create() = function to create the window used as the view. What you need to do is register your own window class that uses your = CTreeCtrl derived class as it's window procedure provider (search the = MSDN for details). Create a CCtrlView derived view class and in it's = constructor, pass in the name of your registered (e.g. in = InitInstance()) control to the CCtrlView constructor and proceed = normally. Although I'm sure you could derive from CTreeView, give it an instance = variable of your CTreeCtrl derived class and subclass the CTreeView = derived class using it, I'm not too sure the results would be what you = desire. =20 ---------- From: Serge Wautier[SMTP:serge.wautier@ontonet.be] Sent: Monday, October 21, 1996 2:32 PM To: mfc-l@netcom.com Subject: CTreeCtrl-derived object into CTreeView Environment: Visual C++ 4.1 / Windows 95 Hi All, Just a short reflection about CTreeCtrl & CTreeView : I wrote a class derived from CTreeCtrl. Using this class, the treeview control fills according to a document passed at creation time and it has its own message-handler to react to UI. Also, it has its own = data-members (BTW : Message reflection is a great mechanism). Since i talk of getting info from document, you'll say that i'd better = use a CTreeView. Actually that's what i first did. But i wanted to be able = to reuse my treeview in a dialog. So i moved the code from a = CTreeView-derived class to a CTreeCtrl derived-class. This way, i get a reusable CTreeCtrl that i can put in a dlg or in a view. ..."or in a view" ? Well I first thought it would be peanuts to turn = the treeview of a CTreeView into a CMyTreeCtrl : Just change the = "m_TreeCtrl" of the CTreeView (the one returned by GetTreeCtrl()) into a CMyTreeCtrl = and overide GetTreeCtrl to return the new type... Not so cool ! CTreeView doesn't have a "m_TreeCtrl" member. = GetTreeCtrl() simply casts the view to a CTreeCtrl. Which means the view actually is a treeview control, and not, as i thought, a simple window which contains = a control that "covers" it. Since the view is basically a tree control, i can hardly add the CMyTreeCtrl to it. (I tried to add a CMyTreeCtrl member to it and = Attach() it to the control but it doesn't work too well). The only solution i found is to derive my view from CView instead of CTreeView and add a treeview control into it. CMyView::OnSize() resizes = the control as well in order to make it fit the size of the view. This works fine. But i have the feeling that this reduces a lot the interest of a class = such as CTreeView. Does anyone think of a "nicer" solution to solve this problem ? Any hint welcome. Serge Wautier, Techno Trade s.a. Belgium serge.wautier@ontonet.be http://www.tbox.fr
| Вернуться в корень Архива |