Discussion:
OnPaint in child window paints over parent?
(too old to reply)
Henryk Birecki
2008-01-23 20:55:12 UTC
Permalink
As far as I know painting in child window in OnPaint using the DC
obtained from CPaintDC dc(this); should be limited to the child
window area. In my case it does not when the same code is compiled for
PC, but does seem to work on a WindowsCE device.

Specifically:
Code for PC and WinCE is the same. Child window is created in an MFC
extension dll. Handle to parent window is passed to dll from main
executable and child window is created as follows:

CTestWindow* p= new CTestWindow;
int size=120;
int w=size*2;

if( p->CreateEx(0,_T("STATIC"), _T("TEST"), WS_BORDER|WS_CHILD,
w-size, 0, size, size, hWnd, NULL ,NULL)) //hWnd is the parent window
handle passed from main executable
{
......
}
else
delete p;

......

CTestWindow paints itself by following code:

OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(&rect, 0xFFFFFF);

int x,y;
HICON hTestIcon;
do{
... some code that sets x, y, and hTestIcon

DrawIconEx(dc.m_hDC,x,y,hTestIcon,0,0,0,NULL, DI_NORMAL);
}while(some test);
}

On WindowsCE device icons are truncated at window boundary and do not
show up if they fall outside. On a PC they are drawn beyond the child
window boundary.

Any ideas what can cause this behaviour?
Thanks,
Henryk Birecki
AliR (VC++ MVP)
2008-01-23 21:58:13 UTC
Permalink
I guess that's the difference between windows and wince.
Add this to your code before you call DrawIconEx

CRgn Rgn;
Rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
dc.SelectClipRgn(&Rgn,RGN_COPY);

AliR.
Post by Henryk Birecki
As far as I know painting in child window in OnPaint using the DC
obtained from CPaintDC dc(this); should be limited to the child
window area. In my case it does not when the same code is compiled for
PC, but does seem to work on a WindowsCE device.
Code for PC and WinCE is the same. Child window is created in an MFC
extension dll. Handle to parent window is passed to dll from main
CTestWindow* p= new CTestWindow;
int size=120;
int w=size*2;
if( p->CreateEx(0,_T("STATIC"), _T("TEST"), WS_BORDER|WS_CHILD,
w-size, 0, size, size, hWnd, NULL ,NULL)) //hWnd is the parent window
handle passed from main executable
{
......
}
else
delete p;
......
OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(&rect, 0xFFFFFF);
int x,y;
HICON hTestIcon;
do{
... some code that sets x, y, and hTestIcon
DrawIconEx(dc.m_hDC,x,y,hTestIcon,0,0,0,NULL, DI_NORMAL);
}while(some test);
}
On WindowsCE device icons are truncated at window boundary and do not
show up if they fall outside. On a PC they are drawn beyond the child
window boundary.
Any ideas what can cause this behaviour?
Thanks,
Henryk Birecki
Henryk Birecki
2008-01-24 04:43:56 UTC
Permalink
Thanks. Yes, explicit definition of clipping region is an "obvious"
fix, but I wish I knew what other "gotchas" there are. A reverse
problem seems to be that on a PC doing a ::MoveWindow(....) in main
executable on a child CWnd created in DLL results in the child
receiving WM_SIZE message. On WinCE device I have to explicitly
::PostMessage(WM_SIZE...) to it. Well,... I am sure of the latter.
Only 99% sure of the former.

Cheers,
Henryk
Post by AliR (VC++ MVP)
I guess that's the difference between windows and wince.
Add this to your code before you call DrawIconEx
CRgn Rgn;
Rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
dc.SelectClipRgn(&Rgn,RGN_COPY);
AliR.
Post by Henryk Birecki
As far as I know painting in child window in OnPaint using the DC
obtained from CPaintDC dc(this); should be limited to the child
window area. In my case it does not when the same code is compiled for
PC, but does seem to work on a WindowsCE device.
Code for PC and WinCE is the same. Child window is created in an MFC
extension dll. Handle to parent window is passed to dll from main
CTestWindow* p= new CTestWindow;
int size=120;
int w=size*2;
if( p->CreateEx(0,_T("STATIC"), _T("TEST"), WS_BORDER|WS_CHILD,
w-size, 0, size, size, hWnd, NULL ,NULL)) //hWnd is the parent window
handle passed from main executable
{
......
}
else
delete p;
......
OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(&rect, 0xFFFFFF);
int x,y;
HICON hTestIcon;
do{
... some code that sets x, y, and hTestIcon
DrawIconEx(dc.m_hDC,x,y,hTestIcon,0,0,0,NULL, DI_NORMAL);
}while(some test);
}
On WindowsCE device icons are truncated at window boundary and do not
show up if they fall outside. On a PC they are drawn beyond the child
window boundary.
Any ideas what can cause this behaviour?
Thanks,
Henryk Birecki
AliR (VC++ MVP)
2008-01-24 16:17:08 UTC
Permalink
Honestly it's hard to tell, I have never done a cross platform application
(Windows/WinCE), so I haven't really noticed these inconsistencies. Maybe
you can do a write up for the rest of us, once you are done with your
project.

AliR.
Post by Henryk Birecki
Thanks. Yes, explicit definition of clipping region is an "obvious"
fix, but I wish I knew what other "gotchas" there are. A reverse
problem seems to be that on a PC doing a ::MoveWindow(....) in main
executable on a child CWnd created in DLL results in the child
receiving WM_SIZE message. On WinCE device I have to explicitly
::PostMessage(WM_SIZE...) to it. Well,... I am sure of the latter.
Only 99% sure of the former.
Cheers,
Henryk
Post by AliR (VC++ MVP)
I guess that's the difference between windows and wince.
Add this to your code before you call DrawIconEx
CRgn Rgn;
Rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
dc.SelectClipRgn(&Rgn,RGN_COPY);
AliR.
Post by Henryk Birecki
As far as I know painting in child window in OnPaint using the DC
obtained from CPaintDC dc(this); should be limited to the child
window area. In my case it does not when the same code is compiled for
PC, but does seem to work on a WindowsCE device.
Code for PC and WinCE is the same. Child window is created in an MFC
extension dll. Handle to parent window is passed to dll from main
CTestWindow* p= new CTestWindow;
int size=120;
int w=size*2;
if( p->CreateEx(0,_T("STATIC"), _T("TEST"), WS_BORDER|WS_CHILD,
w-size, 0, size, size, hWnd, NULL ,NULL)) //hWnd is the parent window
handle passed from main executable
{
......
}
else
delete p;
......
OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(&rect, 0xFFFFFF);
int x,y;
HICON hTestIcon;
do{
... some code that sets x, y, and hTestIcon
DrawIconEx(dc.m_hDC,x,y,hTestIcon,0,0,0,NULL, DI_NORMAL);
}while(some test);
}
On WindowsCE device icons are truncated at window boundary and do not
show up if they fall outside. On a PC they are drawn beyond the child
window boundary.
Any ideas what can cause this behaviour?
Thanks,
Henryk Birecki
Joseph M. Newcomer
2009-04-29 01:06:06 UTC
Permalink
No, it isn't really. The clipping region of the DC can be the entire parent area,
because, as I point out in my article, due to what could most politely be called a
fundamental design blunder in Windows, all controls have CS_PARENTDC style. This was
FINALLY fixed in Vista! For some reason, if you invalidate the entire area, you actually
get a clipping region that encompasses the parent!

See my essay on "Inside the GradientFill Explorer" to see how I created a clipping region
to avoid this.

http://www.flounder.com/inside_the_gradientfill_explorer.htm

see the section about the OnPaint handler.
joe
Post by Henryk Birecki
As far as I know painting in child window in OnPaint using the DC
obtained from CPaintDC dc(this); should be limited to the child
window area. In my case it does not when the same code is compiled for
PC, but does seem to work on a WindowsCE device.
Code for PC and WinCE is the same. Child window is created in an MFC
extension dll. Handle to parent window is passed to dll from main
CTestWindow* p= new CTestWindow;
int size=120;
int w=size*2;
if( p->CreateEx(0,_T("STATIC"), _T("TEST"), WS_BORDER|WS_CHILD,
w-size, 0, size, size, hWnd, NULL ,NULL)) //hWnd is the parent window
handle passed from main executable
{
......
}
else
delete p;
......
OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
dc.FillSolidRect(&rect, 0xFFFFFF);
int x,y;
HICON hTestIcon;
do{
... some code that sets x, y, and hTestIcon
DrawIconEx(dc.m_hDC,x,y,hTestIcon,0,0,0,NULL, DI_NORMAL);
}while(some test);
}
On WindowsCE device icons are truncated at window boundary and do not
show up if they fall outside. On a PC they are drawn beyond the child
window boundary.
Any ideas what can cause this behaviour?
Thanks,
Henryk Birecki
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Loading...