You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FireMonkey中如何访问TComboBox与TComboEdit内TListBox的VScrollBar?

解决FMX中TComboBox/TComboEdit的ListBox滚动条Thumb事件自定义问题

方法一:直接枚举ListBox的所有子控件(推荐)

无需直接访问受保护的VScrollBar,利用EnumControls的递归枚举特性,直接在ListBox上调用该方法,即可遍历到嵌套在VScrollBar内的TThumb:

class TScrollThumb : public TCppInterfacedObject<TFunc__2<TControl*, TEnumControlsResult>> {
public:
    TEnumControlsResult __fastcall Invoke(TControl* Control) {
        if (Control->ClassNameIs("TThumb")) {
            Control->OnMouseEnter = MouseEnter;
            Control->OnMouseLeave = MouseLeave;
            Control->OnMouseDown = MouseDown;
            Control->OnMouseUp = MouseUp;
            return TEnumControlsResult::Stop;
        }
        return TEnumControlsResult::Continue;
    }
};

// 直接在ListBox上调用EnumControls,递归查找TThumb
if (ComboBox->ListBox) {
    ComboBox->ListBox->EnumControls(new TScrollThumb);
}

EnumControls默认会递归遍历所有子控件(包括VScrollBar及其内部的TThumb),因此无需提前获取VScrollBar实例,即可定位到目标控件。

方法二:通过RTTI访问受保护的VScrollBar成员

如果需要明确先获取VScrollBar再查找TThumb,可以利用RTTI(运行时类型信息)读取TCustomScrollBox的受保护成员VScrollBar:

#include <System.Rtti.hpp>

TScrollBar* GetScrollBoxVScrollBar(TCustomScrollBox* ScrollBox) {
    if (!ScrollBox) return nullptr;
    
    TRttiContext RttiCtx;
    TRttiType* RttiType = RttiCtx.GetType(ScrollBox->ClassType());
    TRttiField* VScrollBarField = RttiType->GetField("VScrollBar");
    
    if (VScrollBarField) {
        return static_cast<TScrollBar*>(VScrollBarField->GetValue(ScrollBox).AsObject());
    }
    return nullptr;
}

// 使用方式
TScrollBar* scrollBar = GetScrollBoxVScrollBar(ComboBox->ListBox);
if (scrollBar) {
    scrollBar->EnumControls(new TScrollThumb);
}

注意事项

  • 不建议修改FMX官方源码将VScrollBar或GetVScrollBar()改为公开,这会破坏封装性,且可能因编译依赖、版本更新等问题导致后续维护困难。
  • 两种方法均兼容TComboBox和TComboEdit的ListBox控件,原理与TVertScrollBox的场景一致,只是跳过了直接访问受保护成员的步骤。

内容的提问来源于stack exchange,提问作者Bruce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:12:04