|
-
June 23rd, 2004, 11:42 PM
#1
WM_PAINT handler in dlg: cpu usage of 100%
good morning everybody!
in my about dialog i need to draw a string dynamically on a bitmap (static control).
to achieve this, i created a WM_PAINT handler for that dialog and in it i draw the string...
so problem is, whenever the WM_PAINT handler is there, regardless if anything is done in it, even if it has an empty body, the cpu usage rises to 100%.
and after a few seconds i get a i/o exception.
i spy(ed)++ the dialog, and if there is a handler for WM_PAINT it will recieve thousands of WM_PAINT msgs.
i don't get what i'm doing wrong... can't i implement a WM_PAINT handler in a dialog?
and if no, how can i draw my string in an other way?
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 23rd, 2004, 11:54 PM
#2
Post some code. You seem to be invoking WM_PAINT message using InvalidateRect or UpdateWindow in your WM_PAINT handler.
-
June 24th, 2004, 12:04 AM
#3
as i said: even if OnPaint has an empty body...
but here the two versions i tried:
v1
Code:
void CAboutDlg::OnPaint()
{
CWnd* pwndPic = GetDlgItem(IDC_ABOUT_BMP);
CDC* pDC = pwndPic->GetDC();
CRect rcPic;
pwndPic->GetClientRect(rcPic);
pDC->SelectObject(&m_font);
pDC->SetBkMode(TRANSPARENT);
pDC->DrawText(AfxGetAppName(), -1, rcPic, DT_CENTER|DT_VCENTER);
pwndPic->ReleaseDC(pDC);
}
v2: draws the text smoother
Code:
void CAboutDlg::OnPaint()
{
CWnd* pwndPic = GetDlgItem(IDC_ABOUT_BMP);
PAINTSTRUCT ps;
CDC* pDC = pwndPic->BeginPaint(&ps);
CRect rcPic;
pwndPic->GetClientRect(rcPic);
pDC->SelectObject(&m_font);
pDC->SetBkMode(TRANSPARENT);
pDC->DrawText(AfxGetAppName(), -1, rcPic, DT_CENTER|DT_VCENTER);
pwndPic->EndPaint(&ps)
}
and even if i have this:
Code:
void CAboutDlg::OnPaint()
{
}
cpu usage goes up to 100%, and after some time... error
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 24th, 2004, 12:10 AM
#4
About without any body, i just checked it. I think you must provide default handling if you are not repainting the dialog itself(removing the CPaintDC dc(this) also) as CPaintDC constructor calls BeginPaint
Code:
CPaintDC::CPaintDC(CWnd* pWnd)
{
ASSERT_VALID(pWnd);
ASSERT(::IsWindow(pWnd->m_hWnd));
if (!Attach(::BeginPaint(m_hWnd = pWnd->m_hWnd, &m_ps)))
AfxThrowResourceException();
}
I don't now details of BeginPaint and EndPaint what it seems either they should be handled once WM_PAINT is called or else default called which is CDialog::OnPaint().
Hope this helps.
Note: you can do your painting on a dialog, that's what WM_PAINT is ment for.
-
June 24th, 2004, 12:16 AM
#5
You must handle the message one or the other way or tell windows you don't want to handle it (Call default CDialog::OnPaint()).
Originally posted by bigBA
and even if i have this:
Code:
void CAboutDlg::OnPaint()
{
}
cpu usage goes up to 100%, and after some time... error
-
June 24th, 2004, 12:21 AM
#6
hm.. yes. default handling... that was the point.
i added this line at the end of OnPaint and all went ok:
Code:
Default(); //as done in all default handles of mfc classes
allright 
now i have to figure out how to draw text an a static control, without making the control to discard its contents... (the bitmap isn't drawn if i do BeginPaint/EndPaint)
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 24th, 2004, 12:27 AM
#7
Hi,
Your calls to BeginPaint and EndPaint are pertaining to a child control why don't you handle the WM_PAINT handler of this control itself, just need to declare a new class and subclass your control from it.
-
June 24th, 2004, 12:42 AM
#8
simple answer: i don't want to write a new class.. already have about 50 classes in the project 
my idea for drawing the text:
place a static text control above the static bitmap control..
and make a CPaintDC from the text control... but this doesn't work...
when i do nothing (only Default()) the static text is above the bitmap, but when i get a CPaintDC from the text control it disappears.
actually then it is below the bitmap control (when i set this to invisible my drawn text shows up)...
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 24th, 2004, 09:00 AM
#9
Originally posted by bigBA
simple answer: i don't want to write a new class.. already have about 50 classes in the project
Strange reasoning... There are projects with thousands of classes. 
Originally posted by bigBA
my idea for drawing the text:
place a static text control above the static bitmap control..
and make a CPaintDC from the text control... but this doesn't work...
when i do nothing (only Default()) the static text is above the bitmap, but when i get a CPaintDC from the text control it disappears.
actually then it is below the bitmap control (when i set this to invisible my drawn text shows up)...
A few things:- The inifinite repaints in your original code were caused by the fact that your WM_PAINT handler didn't call BeginPaint() / EndPaint(). If EndPaint() is not called, the WM_PAINT message will be sent over and over again. The standard way to do this with MFC is to create a local CPaintDC object in your OnPaint() implementation: Its ctor will call BeginPaint(), and its dtor calls EndPaint().
- You can't create a CPaintDC for a child window in the parent window's OnPaint() - BeginPaint() and EndPaint() must be called exclusively in response to a WM_PAINT message. However, while in your dialog's OnPaint(), you are currently processing the WM_PAINT message sent to the dialog, not the control.
- It is generally never a good idea to implement your own WM_PAINT handler in a dialog: The dialog's WM_PAINT does a lot of things, like scaling the controls from dialog units to screen units, drawing the controls etc. The results when overwriting a control in a dialog's OnPaint() handler are undefined - it might even seem to work, but fail with another Windows version. To do custom drawing in a dialog, you usually create your own control and do the drawing in the control's WM_PAINT handler. In your case, it is probably best to derive your control from CStatic, in other cases (more complex controls which require interaction and scrolling) you create a custom control derived directly from CWnd.
Last edited by gstercken; June 24th, 2004 at 09:03 AM.
-
June 24th, 2004, 09:04 AM
#10
hm... the point with the logical units... don't know.
i'm just waiting for the error-responses
i did it this way now, and it worked fine:
Code:
CWnd* pwndPic = GetDlgItem(IDC_ABOUT_BMP);
//CPaintDC dc(pwndPic);
//CPaintDC* pDC = &dc;
PAINTSTRUCT ps;
CDC* pDC = pwndPic->BeginPaint(&ps);
CRect rcPic;
pwndPic->GetClientRect(rcPic);
HBITMAP hBmp = ((CStatic*)pwndPic)->GetBitmap();
if( hBmp )
{
pDC->DrawState(CPoint(0,0),CSize(rcPic.Width(), rcPic.Height()),hBmp, DST_BITMAP|DSS_NORMAL);
}
CRect rcText(20,115,380,205);
pDC->SelectObject(&m_fontBig);
pDC->SetBkMode(TRANSPARENT);
int iHeight = pDC->DrawText(AfxGetAppName(), -1, rcText, DT_CENTER|DT_VCENTER);
if( !m_strComments.IsEmpty() )
{
rcText.top += iHeight + 5;
pDC->SetTextColor(RGB(255,0,0));
pDC->SelectObject(&m_fontSmall);
pDC->DrawText(m_strComments, -1, rcText, DT_CENTER|DT_VCENTER);
}
pwndPic->EndPaint(&ps);
CDialog::OnPaint();
//Default(); //without this cpu usage: 100%
if it won't work on other windows versions, i will go to the solution with deriveing cstatic and subclassing the control.
i know that my excuse with "i already have about 50 classes" is a bit weak, but we are upgrading an very old app and the next release is about tomorrow, and i have alot of other things to do as well (more essential things)
Last edited by bigBA; June 24th, 2004 at 09:07 AM.
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 24th, 2004, 09:13 AM
#11
Originally posted by bigBA
i did it this way now, and it worked fine:
As I said: It might seem to work, by pure luck. It is likely to fail under other circumstances, like another machine or another Windows version. A problem with your code is that you are calling the control's BeginPaint() without that it received a WM_PAINT message. A second problem is that you call CDialog::OnPaint() yourself, that's another thing which is strongly discouraged. And BTW, I really wonder that this code seems to work: When you call CDialog::OnPaint(), I would expect that the original bitmap control is redrawn, overwriting what you previously painted.
-
June 24th, 2004, 09:19 AM
#12
Originally posted by bigBA
i know that my excuse with "i already have about 50 classes" is a bit weak, but we are upgrading an very old app and the next release is about tomorrow, and i have alot of other things to do as well (more essential things)
But that shouldn't force you into sloppy coding practices... The code you posted wouldn't pass any code review, especially if it's for a release, I would never accept that a developer knowingly introduces code which is definitely plain wrong.
-
June 25th, 2004, 01:34 AM
#13
-
June 25th, 2004, 03:24 AM
#14
now i use this approach, also avoiding new class&subclassing.
i'm setting the Static control to SS_OWNERDRAW
and in OnDrawItem of my Dlg i paint it.
works. and i don't see any problems are there any?
there are 10 kinds of people. those who understand binary and those who don't...
rate a post if you find it usefull, thx
check out my Firefox/Mozilla Extension: http://urlparams.blogwart.com/
-
June 25th, 2004, 07:35 AM
#15
Originally posted by bigBA
now i use this approach, also avoiding new class&subclassing.
i'm setting the Static control to SS_OWNERDRAW
and in OnDrawItem of my Dlg i paint it.
works. and i don't see any problems  are there any?
No, that's the "cheap" approach, but it's fine...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|