Resource limit?  
Author Message
lfisk01





PostPosted: Tue Jan 27 00:28:27 CST 2004 Top

MFC >> Resource limit? I am having a really weird issue that I can't figure out...

I am getting a unhandled exception in my application. Also a "a resource is
unavailable..." error. It appears to be related to opening a large number
of resources. I'm not sure.

I have a CDialog derived class that is embedded in a tabbed dialog type
control which is all part of a CFormView. This dialog view has a custom
control/grid that uses CStatic controls for the cells. Each instance of
the class creates around 250 CStatic controls. This has always worked
well, but recently I modified my code so that more than one of these
CFormViews can be open at a time.

On opening the 6th instance (they all use the same MDI template), the app
blows up. I can't track it down to a single line and I think that's
because it's an application-wide issue.

I don't think it's necessarily a problem with this particular CDialog over
the other ones in the tab dialog view. I think it causes the problem
because it creates so many controls. In fact it's not even this type of
view that is the problem. After opening 5 views, if I open a normal
CDialog that embeds the same grid control it blows. I'm pretty sure the
grid isn't specifically the problem just the source of the problem.

If I debug deep into MFC code it appears the CreateCompatibleDC is failing
in different places.

Is there a limit to the number of controls that can be opened at one time
(that would be odd). Is there a conflict between using the same resource
IDs over and over between views?

I have debugged for hours on this and am baffled. Any clues or direction
would be greatly appreciated!

Thanks much.

Eric

Visual Studio380  
 
 
Johan





PostPosted: Tue Jan 27 00:28:27 CST 2004 Top

MFC >> Resource limit? Eric,

That CreateCompatibleDC fails implies a GDI-problem. This might or might not
be related to your code - you might want to start checking that
GDI-resources are deleted correctly.

I assume that the grid is a class over which source code you have control.
Personally, I would have rewritten this class not to use CStatics, but keep
a list of strings used for this purpose instead. If you create a small
class, derived from CObject, you could add relevant members (such as
SetWindowText), making it possible to replace the CStatics with this
"SyntheticStatic" class without changing the implementation of the grid.
Then, you'll only have to modify the drawing code of the grid, or add
drawing code to the grid perhaps, to loop the SyntheticStatics and paint
them using the normal GDI-calls.

Johan Rosengren
Abstrakt Mekanik AB

"Eric Margheim" <EMail@HideDomain.com> a écrit dans le message de
news:EMail@HideDomain.com...
> I am having a really weird issue that I can't figure out...
>
> I am getting a unhandled exception in my application. Also a "a resource
is
> unavailable..." error. It appears to be related to opening a large
number
> of resources. I'm not sure.
>
> I have a CDialog derived class that is embedded in a tabbed dialog type
> control which is all part of a CFormView. This dialog view has a custom
> control/grid that uses CStatic controls for the cells. Each instance of
> the class creates around 250 CStatic controls. This has always worked
> well, but recently I modified my code so that more than one of these
> CFormViews can be open at a time.
>
> On opening the 6th instance (they all use the same MDI template), the app
> blows up. I can't track it down to a single line and I think that's
> because it's an application-wide issue.
>
> I don't think it's necessarily a problem with this particular CDialog over
> the other ones in the tab dialog view. I think it causes the problem
> because it creates so many controls. In fact it's not even this type of
> view that is the problem. After opening 5 views, if I open a normal
> CDialog that embeds the same grid control it blows. I'm pretty sure the
> grid isn't specifically the problem just the source of the problem.
>
> If I debug deep into MFC code it appears the CreateCompatibleDC is failing
> in different places.
>
> Is there a limit to the number of controls that can be opened at one time
> (that would be odd). Is there a conflict between using the same resource
> IDs over and over between views?
>
> I have debugged for hours on this and am baffled. Any clues or direction
> would be greatly appreciated!
>
> Thanks much.
>
> Eric
>
>


 
 
Eric





PostPosted: Tue Jan 27 10:24:43 CST 2004 Top

MFC >> Resource limit?
"Johan Rosengren" <EMail@HideDomain.com> wrote in message
news:u8eTB%EMail@HideDomain.com...
> Eric,
>
> That CreateCompatibleDC fails implies a GDI-problem. This might or might
not
> be related to your code - you might want to start checking that
> GDI-resources are deleted correctly.

What type of thing should I be checking?

> I assume that the grid is a class over which source code you have control.
> Personally, I would have rewritten this class not to use CStatics, but
keep
> a list of strings used for this purpose instead. If you create a small
> class, derived from CObject, you could add relevant members (such as
> SetWindowText), making it possible to replace the CStatics with this
> "SyntheticStatic" class without changing the implementation of the grid.
> Then, you'll only have to modify the drawing code of the grid, or add
> drawing code to the grid perhaps, to loop the SyntheticStatics and paint
> them using the normal GDI-calls.

The code for the grid is definitely not optimal. I wrote it a few years ago
and did what I knew. It would be too much of an effort to rewrite it at
this time. Hopefully I can figure out the issue without recoding this.

Thanks


 
 
Eric





PostPosted: Tue Jan 27 10:49:58 CST 2004 Top

MFC >> Resource limit?
"Johan Rosengren" <EMail@HideDomain.com> wrote in message
news:u8eTB%EMail@HideDomain.com...
> Eric,
>
> That CreateCompatibleDC fails implies a GDI-problem. This might or might
not
> be related to your code - you might want to start checking that
> GDI-resources are deleted correctly.

Johan,

The CStatic control I use is actually a CLabel control (code I found on the
Internet). Below is the constructor and desctructor code. If I comment
out the CreateSolidBrush and CreateFontIndirect lines, I'm able to open
another 3 views before it blows. Of course the font looks bad. I use
this CLabel class all over the place as a replacement for CStatic. Does
this give you any clues? This one stupid fix is holding up our next
release. Thanks much.


CLabel::CLabel()
{
m_crText = GetSysColor(COLOR_WINDOWTEXT);
m_hBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));

::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);

m_font.CreateFontIndirect(&m_lf);
m_bTimer = FALSE;
m_bState = FALSE;
m_bLink = TRUE;
m_hCursor = NULL;
m_Type = None;

m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
}


CLabel::~CLabel()
{
m_font.DeleteObject();
::DeleteObject(m_hBrush);
::DeleteObject(m_hwndBrush);
}


 
 
Johan





PostPosted: Tue Jan 27 11:37:00 CST 2004 Top

MFC >> Resource limit? Eric,

Comments below

"Eric Margheim" <EMail@HideDomain.com> a écrit dans le message de
news:EMail@HideDomain.com...
>
> "Johan Rosengren" <EMail@HideDomain.com> wrote in message
> news:u8eTB%EMail@HideDomain.com...
> > Eric,
> >
> > That CreateCompatibleDC fails implies a GDI-problem. This might or might
> not
> > be related to your code - you might want to start checking that
> > GDI-resources are deleted correctly.
>
> Johan,
>
> The CStatic control I use is actually a CLabel control (code I found on
the
> Internet). Below is the constructor and desctructor code. If I comment
> out the CreateSolidBrush and CreateFontIndirect lines, I'm able to open
> another 3 views before it blows. Of course the font looks bad. I use
> this CLabel class all over the place as a replacement for CStatic. Does
> this give you any clues? This one stupid fix is holding up our next
> release. Thanks much.
>
>
> CLabel::CLabel()
> {
> m_crText = GetSysColor(COLOR_WINDOWTEXT);
> m_hBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
>
> ::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
>
> m_font.CreateFontIndirect(&m_lf);
> m_bTimer = FALSE;
> m_bState = FALSE;
> m_bLink = TRUE;
> m_hCursor = NULL;
> m_Type = None;
>
> m_hwndBrush = ::CreateSolidBrush(GetSysColor(COLOR_3DFACE));
> }
>
>
> CLabel::~CLabel()
> {
> m_font.DeleteObject();
> ::DeleteObject(m_hBrush);
> ::DeleteObject(m_hwndBrush);
> }

What might be the problem is that m_font, m_hBrush and m_hwndBrush are not
selected out of a CDC when they are deleted. DeleteObject will then not
remove the GDI-object. Make sure that m_font, m_hBrush and m_hwndBrush are
selected out of the CDC after being selected with SelectObject. You might
also want to check that those objects are not recreated elsewhere in the
code, without being deleted first, that is for example, if there are any
other CreateSolidBrush, the brush must be deleted first. Feeling that my
explanatory powers lack somewhat, let me exemplify:

xxx::ChangeBrushColor( COLORREF clr )
{
m_hBrush = ::CreateSolidBrush(....); // BAD, BAD, BAD
}

Do this instead:

xxx::ChangeBrushColor( COLORREF clr )
{
if( m_hBrush )
::DeleteObject(m_hBrush);
m_hBrush = ::CreateSolidBrush(....);
}

Feel free to mail the CLabel source code to me, and I'll have a look at it.

As this does not completely remove the problem, it's a strong indication
that there might be more GDI-leaks in the app. I can't stress the enormous
benefit of using a tool such as BoundsChecker enough. The cost for this tool
should be compared to the time it takes to hunt down GDI- and other leaks -
it quickly earns its money :-)))

Johan Rosengren
Abstrakt Mekanik AB


 
 
Johan





PostPosted: Tue Jan 27 11:38:36 CST 2004 Top

MFC >> Resource limit? Eric,

See my other reply to this.

Johan Rosengren
Abstrakt Mekanik AB

"Eric Margheim" <EMail@HideDomain.com> a écrit dans le message de
news:EMail@HideDomain.com...
>
> "Johan Rosengren" <EMail@HideDomain.com> wrote in message
> news:u8eTB%EMail@HideDomain.com...
<snip>
>
> The code for the grid is definitely not optimal. I wrote it a few years
ago
> and did what I knew. It would be too much of an effort to rewrite it at
> this time. Hopefully I can figure out the issue without recoding this.
>
> Thanks
>
>


 
 
Eric





PostPosted: Tue Jan 27 13:08:49 CST 2004 Top

MFC >> Resource limit? > if( m_hBrush )
> ::DeleteObject(m_hBrush);
> m_hBrush = ::CreateSolidBrush(....);
> }
>
> Feel free to mail the CLabel source code to me, and I'll have a look at
it.
>
> As this does not completely remove the problem, it's a strong indication
> that there might be more GDI-leaks in the app. I can't stress the enormous
> benefit of using a tool such as BoundsChecker enough. The cost for this
tool
> should be compared to the time it takes to hunt down GDI- and other
leaks -
> it quickly earns its money :-)))
>

Johan, I've actually just installed Boundschecker but need to upgrade to get
it to work. Hopefully, that'll help me out.

I changed the grid to use CStatic instead of CLabel. This allowed me to
open several more views but it is eventually crashing still so there must be
something else going on elsewhere. I'll email you the code for my grid.