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_3DFACE
或 COLOR_BTNFACE
)返回的标准系统颜色,或一些自定义的深色画笔。
我使用以下设置创建了一个项目。
+ 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_3DFACE
或 COLOR_BTNFACE
)返回的标准系统颜色,或一些自定义的深色画笔。