user180574
user180574

Reputation: 6084

MFC: how to access scroll bar when CScrollView is used?

I create a project with the following settings.

  + Application type: Single document
  + Use Unicode libraries: NO
  + Project style: MFC standard
  + Use of MFC: Use MFC in a shared DLL
  + Base class: CScrollView

I only modify OnDraw to output lots of lines.

void CMRCView::OnDraw(CDC* pDC)
{
    CMRCDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here

    CFont font;
    int font_pixels_height;

    /* set up font and figure out its height, omit here ... */

    CRect rect;
    GetClientRect(&rect);

    rect.bottom = font_pixels_height;

    CFont *old_font = pDC->SelectObject(&font);

    for (int i = 0; i < 10000; ++i)
    {
        pDC->DrawText("hello world 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789 0123456789",
                      -1, &rect, DT_LEFT);
        rect.top += font_pixels_height;
        rect.bottom += font_pixels_height;
    }

    pDC->SelectObject(old_font);
}

The output is OK. When I expand the window I can see more lines, but there is no scroll bar either vertical or horizontal.

Upvotes: 0

Views: 641

Answers (1)

Constantine Georgiou
Constantine Georgiou

Reputation: 3401

I think you need to read more carefully the documentation. The CScrollView class defines relatively few additional (to its base class CView) methods. It will automatically display scroll-bars if the scrollable area is bigger than the visible client area. Some key methods are SetScrollSizes(), GetScrollPosition() and GetClientRect() (inherited from CWnd).

Recalculate the scrollable area's size (and call SetScrollSizes()) in any case this may be needed - for example a change in the data in your CDocument, or when the user changes some "View Options".

Then there are two ways to paint (OnDraw()) your document:

  • Paint the whole scrollable area. This is very simple to implement, but somehow "wasteful", as it may paint an area that is not visible.
  • Paint only the visible part of the scrollable area. Call GetTotalSize() (or just check the values you previously passed to SetScrollSizes() - you will have to store them), GetClientRect() and GetScrollPosition() to determine what you need to paint. You should only paint the rectangle returned by GetClientRect() (you need to offset it by the scroll position, returned by GetScrollPosition()).

In either case you must also check if the scrollable size is rather smaller than the visible client rectangle), and in both the horizontal and vertical directions. If so, fill the rest with some neutral color, indicating a "no-data" or "empty" area. Better use a standard system color, returned by GetSysColor() (eg COLOR_3DFACE or COLOR_BTNFACE), or some custom darker brush.

Upvotes: 2

Related Questions