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
| Вернуться в корень Архива
|