Re: What MFC Objects Can't be created on the Stack?




"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message
news:8dvfd21sutlsoavnq19atoels3d58i4aqc@xxxxxxxxxx
See below...
On Wed, 2 Aug 2006 18:42:36 -0500, "Peter Olcott" <olcott@xxxxxxx> wrote:


"Dan Bloomquist" <public21@xxxxxxxxxxx> wrote in message
news:4AaAg.6946$Oh1.3909@xxxxxxxxxxxxxxxx


Peter Olcott wrote:

I need to be able to change the currently selected font without creating
any
resource leak.
See if these assumptions are correct:
(1) The resource associated with a CFont is only destroyed when the CFont
object goes out of scope.

No, you can call DeleteObject( ) and then CFont becomes an empty shell.

That would make things simpler. What happens if you do this more than once in
a
row?
****
If you attempt to DeleteObject if there is no object, you might get an
assertion failure.
But as long as you DeleteObject before the next CreateFont[Indirect], you can
do this as
many times as you feel like, possibly hundreds of times in a loop for that
matter
****


(2) Calling NewFont.CreateFontIndirect() twice while keeping NewFont in
scope
creates one extra instance of NewFont that does not get properly destroyed.

No. Attach( ) will assert unless you have a previous DeleteObject( ).

I have no idea what this means.
****
This is a critical concept. You really need to understand it.

When you create a C++ object (wrapper), you may or may not get an associated
kernel object
that it wraps. It depends on the object and the meaning of its constructor.
Ultimately,
however, a function called Attach is called that takes as input a kernel
handle to a
kernel object, and binds it to the wrapper class. This tests to make sure
that an
existing object is not already wrapped by the C++ object, and if one is, there
is an
ASSERT statement that reports this fact.

There is a corresponding operation, Detach, which breaks the association
between the
kernel object and the C++ object, removing all knowledge of the kernel object
from the
wrapper. Following a Detach, which returns the kernel handle of an object,
the object
exists, but the C++ wrapper no longer knows about. Thus, if you Detach you
have
responsibility for tracking the handle in some way, but if the C++ wrapper
leaves scope
there is nothing for it to destruct, and its destructor will not delete the
kernel object
because it has no idea it exists.

Similarly, there are operations that can destroy the underlying kernel object,
such as
CGdiObject::DeleteObject (subclassed it is CFont::DeleteObject) or
CWnd::DestroyWindow.
These allow the C++ object to remain while breaking the connection with the
kernel object
and destroying the kernel object.

I only need to simplest possible way to attain the required functionality. It
seems that there are far too many nuances to pay attention to. Microsoft made a
big mistake by requiring one to fully understand all of the nuances of the
underlying infrastructure to accomplish what should otherwise be relatively
simple tasks. Its good that they finally got the Borland guys to untangle this
ungodly mess with the design of the .NET architecture.


Some constructors will both create a C++ object and its underlying kernel
object; for
example,

CBrush br(RGB(...));

declares a variable and also creates a kernel object to go with it; and is
equivalent to

CBrush br;
br.CreateSolidBrush(RGB(...));

but other than pens and brushes (at the moment I'm drawing a blank on other
types of
objects for which this might be true), most of these wrappers simply create a
C++ object
and you must create the kernel object later. You are free, of course, to
subclass one of
these and provide subclass constructors that will also create kernel objects,
but that's a
fine point.
******

So Microsoft did not design its wrapper classes to behave consistently?



Best, Dan.


Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm


.



Relevant Pages

  • Re: What MFC Objects Cant be created on the Stack?
    ... When you create a C++ object (wrapper), you may or may not get an associated ... kernel object, and binds it to the wrapper class. ... there are operations that can destroy the underlying kernel ... The nuances arise when you try to exercise paradigms outside the basic design ...
    (microsoft.public.vc.mfc)
  • Re: What MFC Objects Cant be created on the Stack?
    ... When you create a C++ object (wrapper), you may or may not get an associated ... kernel object, and binds it to the wrapper class. ... Similarly, there are operations that can destroy the underlying kernel object, ... Some constructors will both create a C++ object and its underlying kernel ...
    (microsoft.public.vc.mfc)
  • Re: What MFC Objects Cant be created on the Stack?
    ... you can call DeleteObject() and then CFont becomes an empty shell. ... When you create a C++ object (wrapper), you may or may not get an associated ... kernel object, and binds it to the wrapper class. ... big mistake by requiring one to fully understand all of the nuances of the ...
    (microsoft.public.vc.mfc)
  • Re: What MFC Objects Cant be created on the Stack?
    ... The resource associated with a CFont is only destroyed when the CFont ... When you create a C++ object (wrapper), you may or may not get an associated kernel object ... Similarly, there are operations that can destroy the underlying kernel object, such as ...
    (microsoft.public.vc.mfc)

Loading