Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CSplitterWnd paint problems

167 views
Skip to first unread message

HeroOfSpielburg

unread,
Sep 6, 2004, 1:18:30 AM9/6/04
to
Hello,

I have an SDI doc/view app with two splitters, arranged as such:

------------
| | |
| | |
------------
| |
|__________|

The top left is my CView-derived class, the right is a dialog, and the
bottom is a custom control I made which is essentially a CWnd with a
preset amount of child windows and controls.

My problem is I can't get the custom control area to paint properly.
WM_PAINT messages are being received, my overridden message handler is
hit. I also call the base class in that function (CWnd::OnPaint).

However, the paint goes off improperly, and all I get are the contents
last behind that window (i.e. no redraw). I tried even a simple
rectangle over the client rect, but that didn't work. Disabling my
override to let the CWnd handle the drawing doesn't change anything
either. Did I initialize something improperly? Did I choose the
wrong style? Is it an ERASE_BKGRND thing? Please make a suggestion
if you can think of anything, I can't figure it out!

Here is how I create the splits:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
// create the first splitter which houses the custom control int
m_wndSplitter.CreateStatic(this, 2, 1);
m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS( CCustomCtrl ),
CSize(0,0), pContext );

// add the second splitter pane - which is a nested splitter with 2
rows
if (!m_wndSplitter2.CreateStatic( &m_wndSplitter, 1, 2, WS_CHILD |
WS_VISIBLE | WS_BORDER, m_wndSplitter.IdFromRowCol(0, 0)
))
{
TRACE0("Failed to create nested splitter\n");
return FALSE;
}

// now create the two views inside the nested splitter
int cyText = max( 70, 20 ); // height of text pane

if (!m_wndSplitter2.CreateView(0, 0, RUNTIME_CLASS(CSCEditView),
CSize(0, cyText), pContext))
{
TRACE0("Failed to create second pane\n");
return FALSE;
}
if (!m_wndSplitter2.CreateView(0, 1, RUNTIME_CLASS(CPropertyBarDlg),
CSize(0, 0), pContext))
{
TRACE0("Failed to create third pane\n");
return FALSE;
}

return TRUE;
}

Scott McPhillips [MVP]

unread,
Sep 6, 2004, 10:40:54 AM9/6/04
to
HeroOfSpielburg wrote:
> Hello,
>
> I have an SDI doc/view app with two splitters, arranged as such:
>
> ------------
> | | |
> | | |
> ------------
> | |
> |__________|
>
> The top left is my CView-derived class, the right is a dialog, and the
> bottom is a custom control I made which is essentially a CWnd with a
> preset amount of child windows and controls.
>
> My problem is I can't get the custom control area to paint properly.
> WM_PAINT messages are being received, my overridden message handler is
> hit. I also call the base class in that function (CWnd::OnPaint).
>
> However, the paint goes off improperly, and all I get are the contents
> last behind that window (i.e. no redraw). I tried even a simple
> rectangle over the client rect, but that didn't work. Disabling my
> override to let the CWnd handle the drawing doesn't change anything
> either. Did I initialize something improperly? Did I choose the
> wrong style? Is it an ERASE_BKGRND thing? Please make a suggestion
> if you can think of anything, I can't figure it out!

Try not calling CWnd::OnPaint
Post the simple OnPaint code that fails

--
Scott McPhillips [VC++ MVP]

HeroOfSpielburg

unread,
Sep 6, 2004, 10:15:10 PM9/6/04
to
"Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in message
> Try not calling CWnd::OnPaint
> Post the simple OnPaint code that fails

I think I figured it some of the problem. Part of it has to do with
the initialization of the pane.

m_wndSplitter.CreateStatic(this, 2, 1, WS_HSCROLL | WS_CHILD |
WS_VISIBLE);
m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS(CCustomCtrl),
CSize(0,0), pContext );

if (!m_wndSplitter2.CreateStatic( &m_wndSplitter, 1, 2, WS_CHILD |
WS_VISIBLE | WS_BORDER, m_wndSplitter.IdFromRowCol(0, 0) ))
{
TRACE0("Failed to create nested splitter\n");
return FALSE;
}

The problem seems to be here:
m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS(CCustomCtrl),
CSize(0,0), pContext );

The CSize parameter passed in is zero, so no actual space is given to
the pane contents (though you may resize the splitters all you want).
I copied this out of an example for VIEWEX, and I didn't pay attention
to the parameters closely enough. I thought that from resizing the
splitter, the panes would update in turn and receive actual space
equivalent to the area between the splitter borders. Is this not the
case?

So, as a work around, I changed the CSize parameter to:

CRect r;
GetClientRect( &r );
m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS(CCustomCtrl),
CSize(r.Width(),r.Height()), pContext );

Now the control draws its child elements, but the background of the
actual control/pane doesn't seem to want to paint. :( So I end up
getting unpainted space where the default window background color
should be. I suppose I'm still doing something wrong here. Also, it
doesn't seem as if I should need to pass in the entire client space of
the mainframe for the pane's initialization.

I am using a CMemDC from one of my control's base classes
(http://www.codeproject.com/miscctrl/uhrulerctrl.asp) for
double-buffering to eliminate flicker on the child controls, which
involves overriding their OnEraseBkgrnd, but the problem here is with
the parent window (the one in the pane) that just houses them. So I
don't think their painting should affect the parent, since their DCs
are indepedent of the window I'm having trouble with.

Here is my OnPaint() for the CCustomCtrl that goes in the pane:
{
CWnd::OnPaint();

CDC* pDC = GetDC();
m_vecpWFC[0]->OnDraw( pDC );
}

The OnDraw is just for a custom child object that gets drawn on top,
enabling or disabling this code has no affect other than drawing or
not drawing the child control. This is pretty simple, so maybe I'm
doing something wrong still with my CSplitterWnd
initialization/management? It seems like either that or I'm mangling
the paintable space of the window somewhere. I have this same control
in a dialog-based app and the background draws fine, so I'm inclined
to believe it has to do with the control's creation in relation to
this splitterwnd.

Thanks for your time and advice.

Scott McPhillips [MVP]

unread,
Sep 7, 2004, 12:33:04 AM9/7/04
to

Of course resizing the splitter bars resizes the pane windows! That's
what splitters are for. The CSize passed to CreateView doesn't matter:
the splitter will resize its panes when RecalcLayout is called.

As I understand it, your question is why is the background not getting
painted. What do you think your OnPaint does? There is no code there
to paint the background. You have also said you override OnEraseBkgnd,
which is perhaps the source of the problem.

But, the OnPaint code also has multiple problems. The child control
should paint itself in its own OnPaint, using CPaintDC.

Joseph M. Newcomer

unread,
Sep 7, 2004, 5:41:37 AM9/7/04
to
I agree with Scott. The OnPaint handler is bizarre. For example, there is no reason to get
another DC, since you already have a DC, and since you are merely calling OnDraw, the code
would be in the OnDraw handler. But as he points out, there is no sense to having a
control "draw its child elements", since child windows draw themselves, and are not in any
way drawn by the parent window.

Windows draw themselves. The statement


m_vecpWFC[0]->OnDraw( pDC );

doesn't make any sense. For one thing, you have not defined what m_vecpWF is, so it is
sort of hard to guess what is going on here, but calling some other window's OnDraw method
is even more nonsensical than calling your own. An OnDraw method requires the framework
has initialized the DC, and you would not use the DC of the parent to draw the contents of
a child window. This causes the drawing logic of the child to draw the image on the
parent, which means it is going to be clipped by the area occupied by the child window,
that is, the function will do nothing at all.
joe

On Mon, 06 Sep 2004 23:33:04 -0500, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
wrote:

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

0 new messages