文字包装时Scintilla GetLineCount错误

时间:2018-08-21 22:14:39

标签: word-wrap scintilla line-count

我正在尝试用自定义滚动条替换内置的scintilla滚动条。我在设置滚动条的最大值时遇到了麻烦。我的垂直滚动条的Delphi代码是:

ALScrollBar1.Max := ((Scintilla1.GetLineCount * Scintilla1.TextHeight(0)) -
Scintilla1.ClientHeight + ALScrollBar2.Height); 

如果关闭了自动换行功能,效果很好,但是如果在自动换行功能上,则不考虑自动换行功能。从某种意义上讲,行数仍然是相同的,但是换行时实际可见的行数是错误的(就我的滚动信息而言)。我已经能够在其他一些控件中使用VisibleLineCount或EditRect或TopOffset之类的东西来实现此目的,但是scintilla没有它们。

如果有人遇到这个问题并想出答案,我肯定想知道!

使用SCILexer.dll 4.1.0.0

新信息:(注意:我的全部目的是用颜色替换那些标准的OS滚动条,以便它们在视觉上与我的表单和其他组件匹配。我喜欢“深色”主题和亮灰色(几乎白色)操作系统滚动条看起来很糟糕。另外,请注意,使用此行,它可以与VCL样式配合使用:

TStyleManager.Engine.RegisterStyleHook(DScintillaSRD.TSRDScintilla, TScrollingStyleHook);

但是,我不想在我的应用程序中使用VCL样式。)

我已经弄清楚了(无论如何还是令我满意!),所以我想补充一下我发现的内容。

基本上,我想出了3种方法。首先是将我的自定义滚动条(可以设置颜色)与要滚动的控件一起添加到窗体,然后设置控件和SB之间的通信。此自定义SB组件(ALCINOE组件)不是基于常规TScrollBar的,因此您不能仅将其传递给scrollinfo(如果您“关闭”控件的系统滚动条以“隐藏”它们,则该控件将无法工作)。只要控件具有TopOffset或YOffset和LeftOffset或XOffset属性(PlusMemo,VirtualStringTree,ScrollBox,ListBox),我就可以多次执行此操作。我在这里遇到的问题是Scintilla控件只有X偏移量可用。我很接近这种方法,但总是出现的一件事是所有滚动内容应该非常精确(位置,拇指大小等)。您可以使用一些“倾斜”来完成它(这是这种方法的工作原理),但是尝试依靠它总是很粗略的。

下一个方法是创建一个小窗口(TWinControl)以“覆盖”控件的系统SB,然后将TScrollBar添加到该窗口中。因为它是一个TScrollBar,所以您可以在SB和控件之间来回传递scrollinfo。通过此设置,您最终可以使用TWMCtlColorScrollbar消息为TScrollBar的背景(仅)着色(我从来没有能够使该消息直接与Scintilla一起使用)。这比完全浅灰色的SB更好,但是仅背景呈现颜色,并且拇指和箭头按钮都保持灰色,因此不理想。但是,它在位置,滚动等方面非常准确。

最后一种方法是使用小“覆盖”窗口来隐藏操作系统栏,并将自定义SB(ALCINOE)添加到该窗口,就像我使用TScrollBar一样。我再次遇到的问题是,即使我可以从Scintilla控件中获取scrollinfo,拇指和滚动位置仍处于“关闭”状态(因此,我知道拇指的大小,MAX和POS编号是固定的)。使用TScrollBar进行此操作非常精确,因此我知道滚动代码中缺少某些内容。我最后弄清楚这是我需要的PAGE数据。因此,在代码中从控件中定位SB,而不是:

ALVScrollBar.Max := SInfo.nMax;

我需要使用:

ALVScrollBar.Max := SInfo.nMax - integer(SInfo.nPage);

以便自定义SB拥有准确定位所需的所有信息(我还从scrollinfo中提取了MIN和POS号)。自定义VERT SB的滚动代码为:

sinfo.cbSize := SizeOf(sinfo);
SInfo.fMask := SIF_ALL;
//Control is the Scintilla control:
GetScrollInfo(Control.Handle, SB_VERT, SInfo);

if SInfo.nPos > ScrollPos then
    i := -((SInfo.nPos - ScrollPos))
else
    i := (ScrollPos - SInfo.nPos) ;

SendMessage(Control.Handle, EM_LINESCROLL, 0 , i);

定制HORZ SB的代码很简单:

TSRDScintilla(Control).SetXOffset(ScrollPos);

当然,您必须做各种事情,例如在适当的时候刷新控件和SB,以及其他内部管理工作,但是这些现在都可以正常工作,并且无论是否有定位和滚动,它都是精确自动换行,带或不带Scintilla批注,任何字体大小。

Screenshot of Custom SBs

0 个答案:

没有答案