MFC:使用CScrollView时如何访问滚动条?

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

我使用以下设置创建了一个项目。

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

我只修改了OnDraw来输出很多行。

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);
}

输出正常。当我展开 window 时,我可以看到更多行,但没有垂直或水平滚动条。

我认为你需要更仔细地阅读文档。 CScrollView class 定义了相对较少的附加方法(在其基础 class CView 中)。如果可滚动区域大于可见客户区域,它将自动显示滚动条。一些关键方法是 SetScrollSizes()GetScrollPosition()GetClientRect()(继承自 CWnd)。

在任何情况下都可能需要重新计算可滚动区域的大小(并调用 SetScrollSizes())- 例如 CDocument 中的数据发生变化,或者当用户更改某些 "View Options".

然后有两种方式来绘制(OnDraw())你的文档:

  • 绘制整个可滚动区域。这实现起来非常简单,但不知何故 "wasteful",因为它可能会绘制一个不可见的区域。
  • 只绘制可滚动区域的可见部分。调用 GetTotalSize()(或者只检查您之前传递给 SetScrollSizes() 的值 - 您必须存储它们)、GetClientRect()GetScrollPosition() 以确定您需要绘制的内容。您应该只绘制 GetClientRect() 返回的矩形(您需要根据 GetScrollPosition() 返回的滚动位置对其进行偏移)。

在任何一种情况下,您还必须检查可滚动大小是否比可见客户端矩形小),并且在水平和垂直方向上。如果是这样,用一些中性色填充其余部分,表示 "no-data" 或 "empty" 区域。最好使用由 GetSysColor()(例如 COLOR_3DFACECOLOR_BTNFACE)返回的标准系统颜色,或一些自定义的深色画笔。