- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经实现了 log viewer using a TListBox
in virtual mode .
它工作正常(对于我编写的所有代码),按预期显示内容(我什至轻松添加了水平滚动条),但我想我已经达到了垂直滚动条的某种限制。
也就是说,当我从上到下滚动垂直条时,它不会将内容滚动到列表末尾,而只会滚动到某个限制。
你知道有什么办法可以摆脱这个限制吗?我尝试使用 SetScrollInfo
,但它不起作用,因为限制听起来不在滚动条中,而是在 TListBox
本身中。
我知道创建专用TCustomControl
的解决方案:在这种情况下,SetScrollInfo
将按预期工作。但是有人知道仍然使用 TListBox
的解决方案/技巧吗?
编辑:说清楚 - 我不要求(第三方)组件解决方案,但要知道是否有一些低级 GDI 消息要发送到标准 TListBox
来覆盖此限制。如果没有,我将使用专用的 TCustomControl
解决方案。
这是使用 TSCROLLINFO 的代码:
procedure ScrollVertHuge(Handle: HWND; count: integer);
var Scroll: TSCROLLINFO;
begin
Scroll.cbSize:= sizeof(Scroll);
Scroll.fMask := SIF_DISABLENOSCROLL or SIF_RANGE;
Scroll.nMin := 0;
Scroll.nMax := count;
SetScrollInfo(Handle,SB_VERT,Scroll,false);
end;
准确地说:添加和绘制当然都可以(我的工具按预期工作),但不起作用的是垂直滚动条拖动。我重命名了问题的标题,并删除了已弃用的 MSDN 文章,这些文章令人困惑。
最佳答案
下面的内容可能应该被视为有缺陷的操作系统行为的解决方法,因为除非启用主题,否则列表框控件的默认窗口过程可以很好地处理拇指跟踪。由于某种原因,当启用主题时(此处测试显示的是 Vista 及更高版本),该控件似乎依赖于 WM_VSCROLL
的 Word 大小滚动位置数据。
首先,一个复制问题的简单项目,下面是一个所有者绘制虚拟 (lbVirtualOwnerDraw
) 列表框,其中包含大约 600,000 个项目(由于项目数据未缓存,因此不需要花一点时间填充该框)。高列表框有利于轻松跟踪行为:
type
TForm1 = class(TForm)
ListBox1: TListBox;
procedure ListBox1Data(Control: TWinControl; Index: Integer;
var Data: string);
procedure ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
procedure FormCreate(Sender: TObject);
end;
[...]
procedure TForm1.FormCreate(Sender: TObject);
begin
ListBox1.Count := 600000;
end;
procedure TForm1.ListBox1Data(Control: TWinControl; Index: Integer;
var Data: string);
begin
Data := IntToStr(Index) + ' listbox item number';
end;
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
// just simple drawing to be able to clearly see the items
if odSelected in State then begin
ListBox1.Canvas.Brush.Color := clHighlight;
ListBox1.Canvas.Font.Color := clHighlightText;
end;
ListBox1.Canvas.FillRect(Rect);
ListBox1.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, ListBox1.Items[Index]);
end;
要查看问题,只需用拇指跟踪滚动条,您会注意到项目如何从头开始包装,每个 65536 个项目如 Arnaud 在问题评论中所述。当您松开拇指时,它将捕捉到顶部 High(Word)
中的项目。
下面的解决方法拦截控件上的 WM_VSCROLL
并手动执行拇指和项目定位。为了简单起见,该示例使用插入器类,但任何其他子类方法都可以:
type
TListBox = class(stdctrls.TListBox)
private
procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL;
end;
[...]
procedure TListBox.WMVScroll(var Msg: TWMVScroll);
var
Info: TScrollInfo;
begin
// do not intervene when themes are disabled
if ThemeServices.ThemesEnabled then begin
Msg.Result := 0;
case Msg.ScrollCode of
SB_THUMBPOSITION: Exit; // Nothing to do, thumb is already tracked
SB_THUMBTRACK:
begin
ZeroMemory(@Info, SizeOf(Info));
Info.cbSize := SizeOf(Info);
Info.fMask := SIF_POS or SIF_TRACKPOS;
if GetScrollInfo(Handle, SB_VERT, Info) and
(Info.nTrackPos <> Info.nPos) then
TopIndex := TopIndex + Info.nTrackPos - Info.nPos;
end;
else
inherited;
end;
end else
inherited;
end;
关于delphi - 如何摆脱TListBox垂直滚动限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7144966/
我正在使用 Delphi XE4,下面是我的示例应用程序。 unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.S
如果您的列表框包含许多项目并且您需要选择例如项目,则项目的选择会变得很痛苦。通过手动单击和选择 400 个项目。 有没有一种优雅的方法可以使用某个“ 通过模式函数 选择项目”从列表框中选择项目? 最佳
我在我的数据库中用 MYDAC 组件创建了一个表并添加了数据。我如何从该表中提取列中的这些值? 我试过了,但没用; MyQuery1.Close; MyQuery1.SQL.Text :='SEL
当选择一个项目(按住鼠标左键)并将鼠标移到列表框之外时,我需要更改列表框滚动的速度。要复制该行为,请执行以下操作: 将列表框拖放到表单上(+- 250 x 200 奇数)。不要让它太大,否则滚动条在底
我一直在尝试使用 TListBox 控件、绘制图像和更改字体样式等。我想稍微加强一下,并尝试通过缩进和多级缩进来更多地操作项目。 看看这张图片以获得更好的想法: 这个想法是列表中位于起始项和结束项之间
我在 Delphi 中为 TListBox 有一个自定义 style,我可以在其中简单地更改 Text 属性喜欢 lb_item.StylesData['location'] := 'New Text
我正在使用 TListBox 组件来显示带有 CheckBoxes 的列表。 它在 iOS 上运行良好,但在 Android 上滚动时会产生小的延迟。 乍一看,我认为这是因为每个 TListBoxIt
我有一个TListBox,每个项目都有控件,例如TEdit、TComboBox、TSwitch等, 右对齐。此列表中有大约 20 项,因此它超出了屏幕,因此用户需要滚动(通过滑动手指)才能到达底部。
我想通过将列表框与其他两个列表框进行比较来清理列表框。 Listbox1 将包含项目的大列表 Listbox2 会有我想从 listbox1 中删除的词 Listbox3 将包含必须存在的强制性单词才
我正在 Lazarus 上开发一个电子书管理器,但我在使用一个我从未使用过的组件 (TListBox) 时遇到了一些麻烦。在名为 CategoryList 的 TListBox 上,我有这些项目: L
我正在使用 XE7 和 FMX。 我的问题是 TListbox 的 OnChange-Event 无法正确处理多选(它不会在每次发生更改时触发)。 重现步骤: 创建一个 FMX 应用程序并将 TLis
我正在创建一个多设备 FireMonkey 应用程序,我想在选择 TListBox 项目时更改其颜色。 如何在 Rad Studio XE7 中完成此操作? 最佳答案 打开位图样式设计器(请参阅 RA
查看代码: function ShowItem(MyData: TMyData): TListItem; var vListItem: TListItem; begin vListItem :
我有一种记录类型。我想在 TListbox 中添加该记录类型的变量,并在 TListbox 的单击事件上检索它。是否可以?如果是的话怎么办? 我使用添加它 lstbox.AddItem(data,my
我正在将 ListBox.Style := lbOwnerDrawFixed 与 OnDrawItem 一起使用: procedure TForm1.ListBox1DrawItem(Control:
简短版本:有没有办法单独控制或修改LisBox项目?例如,分别将其 Visible 属性设置为 False。我在搜索时在Fire Monkey中发现了TListBoxItem类,但我不想使用Fire
是否有使用 TListBox 获得“OnChange”类型功能的技巧?我可以对组件进行子类化并添加属性等,然后仅在索引更改时执行 OnClick 代码...我还可以使用表单级别变量来破解它以存储当前索
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwner
在 DelphiXE 中,我使用 tFileOpenDialog 选择一个文件夹,然后在 tListBox 中列出该文件夹中的所有 *.jpg 文件。我允许将列表项拖放到列表中进行自定义排序,以便稍后
这就是我从本地服务器上的列表中获取一些项目的方法。 我认为它仍然需要一些重构(抱歉,我是 Delphi 的初学者),但是我想更好地理解为什么 ListItem colors 没有被改变。 我做了一些调
我是一名优秀的程序员,十分优秀!