在mfc应用程序中显示文本文件时滚动

时间:2012-07-04 05:46:11

标签: mfc cview

我有一个mfc应用程序,我必须在其中显示文本。每当我使用滚动条时,都会调用OnDraw()函数。这是我的OnDraw()函数:

CString fileText = pDoc->GetFileText();   //get text from file
CRect rect;
GetClientRect(&rect);

pDC->DrawText(fileText.GetString(), &rect, DT_LEFT|DT_NOCLIP);

这似乎效率低下,因为滚动需要永远。问题是我再次重新绘制整个文本文件。我想使用GetClipBox函数只重绘所需的。谁能给我建议如何继续?

感谢。

2 个答案:

答案 0 :(得分:1)

双缓冲在这里不会帮助你,因为你仍然将整个字符串绘制到屏幕外的位图。你想要的只是绘制实际显示的字符串部分,这说起来容易做起来难。

首先,如果每条线具有相同的高度,那么它会使它变得容易10倍(我还假设你没有像在线图像,格式,段落间距等有趣的东西)。基本上你想要做的是得出你的滚动条总线数有多远(假设你有1000行,你的滚动条是50%,这意味着你需要从第500行开始绘制)和您可以显示多少行文本(通过将控件的高度除以每行的高度来轻松计算)。

然后,从字符串中提取这些行,并将它们传递给DrawText()。最简单的方法是将总文本存储为一个字符串,但作为字符串向量,每个条目中包含一行。

现在仍然有很多细节可以做到正确,例如当你一直滚动到最后时显示什么,你是否允许看到半行等,但基本上上面是它归结为什么到。

此外,我希望您不是从每个OnDraw()上的文件中读取文本,因为仅此一项可能会导致速度减慢。

GetClipBox()在这里并不重要,因为即使你只滚动1个像素,你仍然想要重绘内容窗口的整个内容。关键是减少绘制的东西(传递给DrawText()),而不是限制绘制的屏幕空间量。

答案 1 :(得分:0)

我认为解决问题的最佳方法可能是双缓冲。基本上,你的绘画是一个离屏位图,然后当调用OnPaint()时,只需调用

CRect rcUpdate;
GetClipBox(rcUpdate);
pDC->BitBlt(rcUpdate.left, rcUpdate.top, rcUpdate.Width(), rcUpdate.Height(),
                        m_pMemDC, rcUpdate.left, rcUpdate.top, SRCCOPY);

这将只复制屏幕的更新部分,并且应该大大提高您的表现。

我发布了一些代码来帮助解决前一个问题here中的双缓冲区,这可能有所帮助。这还包括你实际上并不需要的GDI +代码,可以省略。