Link to home
Start Free TrialLog in
Avatar of pschimpf
pschimpf

asked on

CScrollView in a static CSplitterWnd pane

I am trying to put a CScrollView-derived view in
the lower right pane of a CSplitterWnd with 4 static
panes, using MSVC 4.0.  The other three panes are
derived from CView.

This worked fine in my last 16-bit app (MSVC 1.52)
but with MSVC 4.0, calling ResizeParentToFit() from
the OnSize() method of CScrollView only works properly
if both dimensions of the pane are smaller than the
logical view size (and both the horiz and vert
scrollbars appear).  If only one dimension is smaller,
then 1 scrollbar should appear, but it doesn't.

Stepping through the OnSize() code, the scrollbar actually
does appear, but disappears shortly thereafter (I believe
that it disappears when the View background is erased).  
The scrollbar disappears sometime after all OnSize()
methods have been processed by the four views, the
CSplitterWnd, and the enclosing CFrameWnd.  It is gone by
the time CScrollView::OnDraw() is called.  I don't know
what else to trap to narrow down the problem.
Avatar of pschimpf
pschimpf

ASKER

Adjusted points to 100
If you read your Visual C++ docs carefully under the topic ResizeParentToFit() it says, this call should be used in the OnInitialUpdate() functions and guarantees no rational behaviour if misused. There might lie the answer for your problem.
The Visual C++ on-line references state that you should call
ResizeParentToFit() from OnInitialUpdate(), but NOT that this
is the ONLY place it should be called from.  In fact, if you
look at the help for SetScrollSizes() you will see an example
implementation of OnUpdate() that calls ResizeParentToFit().
This is the same place that I am calling it from, so there is
no reason to conclude that I am misusing it.
Adjusted points to 200
Edited text of question
Sorry, I am actually calling ResizeParentToFit() from OnSize(),
not OnUpdate(), but I still see no reason that this is a
misuse of ResizeParentToFit().  It is actually the logical
place to call it from, because I wish the view window to be
no larger than the actual size of the document.  If the user
resizes the window to be larger (which results in a call to
OnSize()), then a call to ResizeParentToFit() should reduce
the view window back down to the proper size, and it does!
Its just that under the right circumstances, it also removes
a scroll bar, which it should not do.
Try the following in OnSize() instead of calling the CScrollView::OnSize()

CView::OnSize(nType, cx, cy);
ResizeParentToFit();
UpdateBars();
Interesting (because MSVC 4.0 has no help entry for
UpdateBars(), but it did compile).  Unfortunately,
it didn't help.  I do have a new clue, however:
I normally run with:
 
Control Panel/Display/Plus!/Show Window Contents while Dragging
turned off (not checked)

But if I turn it on, my Splitter window flickers as the Window
is being resized.  You can see it draw the scrollbar at the
stretched out size and then snap back to the ResizeWindowToFit()
size - without the ScrollBars being redrawn!  AND, a final
snap back to the ResizeParentToFit() size doesn't happen when
the mouse button is released - although it DOES when Show
Window Contents while Dragging is off!

It seems like the OnSize() method is being called while the
window is being resized, but the documentation says that it
should be called when the resizing is complete (i.e., when
you release the mouse button).  The documentation also discusses
another member function:  OnSizing() as opposed to OnSize().
But guess what?  The class wizard won't let you connect
OnSizing()!  Is the message map calling OnSize() when it should
be calling OnSizing()?  If so, is there a fix?  

If someone wants to play with this, I would be glad to email them
a small project that illustrates the problem.  Contact me at
Paul_Schimpf@atk.com.  If you find a fix, I will give you an
Excellent score, no matter how kludgy the fix is.  I'm convinced
that this is a hard one.  I'll increase the points as they become
available to me.

OK, I have an answer:

Do NOT call ResizeParentToFit() from inside OnSize().
Instead, use PostMessage() to post a user-defined message.
Create a handler for that user-defined message that calls
ResizeParentToFit().

This works, although I have no satisfactory explanation for
why calling ResizeParentToFit() from OnSize() directly doesn't,
and neither does Microsoft Tech support, although they have
aknowledged the problem and suggested this fix.

They also suggested creating my own ResizeToFit at the frame
window level.  At this level though, you have to account for
the width of scrollbars and splitter bars, etc.  Any easy way
to do that might be to start by maximizing everything by calling
ResizeParentToFit(FALSE) in the OnInitialUpdate() method of
the CScrollView-derived class, then recording the size of the
frame window client area, and then not allow the frame window
area to be stretched beyond that size in the OnSizing() method
of the frame window.  Of course, if you have zoom levels (like
I do), it gets a little more complicated...

ASKER CERTIFIED SOLUTION
Avatar of cathys
cathys

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial