Asset when exiting OnPaint event

I am trying to draw sample text in a Picture control in MFC Dialog.  Following is the code I am using in order to draw the text, which changes as I change the colour and the text of the font.  

Therefore I have written a separate function to draw the text (DrawSampleText()) and OnPaint event calls that function.

<PRE>
void NotesDlg::OnPaint()
{
     CPaintDC dc(this);
     DrawSampleText();
} // <- Assert at this point

void NotesDlg::DrawSampleText()
{
     HFONT     hFont;

     hFont = CreateFont( 30,     0, 0, 0, FW_NORMAL,
               FALSE, FALSE, FALSE, DEFAULT_CHARSET,
               OUT_STROKE_PRECIS, CLIP_DEFAULT_PRECIS,
               DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE,
               FontName);

     CDC* cdc = m_sampleText.GetDC();
     RECT     rect;

     ::GetClientRect(m_sampleText.m_hWnd, &rect);

     m_sampleText.InvalidateRect(NULL, true);
     m_sampleText.UpdateWindow();

     cdc->SetTextColor(GetNoteColourVal());
     cdc->SelectObject(hFont);
     cdc->DrawText(FontName, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
     m_sampleText.ReleaseDC(cdc);
}
</PRE>

When I run the DEBUG version of the program and open the NotesDlg few times, program comes up with the Assert Message:<BR>
     Debug Assertion Failed!
     File: winhand.cpp
     Line: 199

I have highlighted above in the code where the Assert fail.  It happens when OnPaint is trying to exit the function.  Assert fail in the RemoveHandle() function defined in the winhand.cpp file with

the code....<BR>
          if (m_nHandles == 2)
               ASSERT(ph[1] == h);     //<- This Assert fail (value of ph[1] = NULL, but h != NULL)

I have tried number of different things such as removing the "CPaintDC dc(this)" line from the OnPaint() event, this caused and infinite loop of OnPaint event and eventually crashed the program.  

The only solution I could come up with was to turn off assert messages as shown below in the code.

<PRE>
void NotesDlg::OnPaint()
{
#ifdef _DEBUG
     int nPrevMode = _CrtSetReportMode(_CRT_ASSERT,0);
#endif
     if (PrydaTest)
     {
          CPaintDC dc(this);
          DrawSampleText();
     }
#ifdef _DEBUG
     _CrtSetReportMode(_CRT_ASSERT,nPrevMode);
#endif
}
</PRE>

This program occurs on Windows 98 machines with about 128MB or less memory.  I was not able to reproduce this in Win2K with 256+MB RAM.  Does anybody know why this could be happening or how I could

correct my code to fix this Assert fail.

Btw, I do not have many points and I have allocated all the points I have for this question.
LVL 11
supunrAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cmaryusCommented:
In the last line from DrawSampleText():

m_sampleText.ReleaseDC(cdc);

but ReleaseDC needs a pointer:

m_sampleText.ReleaseDC(&cdc);
0
KurtVonCommented:
To be honest, I don't have a clue why it is happening either.  It's obvious that the program thinks you have two PaintDCs, but not why it thinks that.

However, here's a possible solution.  Instead of creating a CPaintDC, call the base class CDialog::OnPaint().  You may want to call it after your own painting, though.  If it still happens your problem is really somewhere else, and you need to find where the DC handles are getting corrupted.

By the way, don't forget to select the original font into the DC in your function DrawSampleText.  I don't think that is the problem, but it's always good practice to destroy a DC with its original objects.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
supunrAuthor Commented:
cmaryus, cdc is already a pointer.  Therefore I have to use it as m_sampleText.ReleaseDC(cdc);, but not the way you suggested.  I have tried the way you mensioned, but then I got the compiler error saying it can not convert CDC** to CDC*.

KurtVon, I will copy the original font back to the sample.  Thanks for that comment.  One thing I forgot to mension is that the same problem happen in not just one, but 3 different dialogs, where all of them has very similar code, that is, OnPaint event calls some other function to draw a sample line and another to draw a preview of a selected picture.  They all come up with the same assert error.  Again, I was not able to produce the error on Windows 98 (same machine) with 512MB RAM, but it happens when I put 128MB RAM in.  May be with 512 MB RAM, it takes long time for that to happen, I don't know.   I have tried your suggestion and it seems to have worked fine.   Thanks for a quick response.  I am giving you all the points for your valuable comments a working solutions.  Thanks once again
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.