firemonkeyc++builder

How do I access the VScrollBar of a ListBox in ComboBox and ComboEdit in FireMonkey?


I need to access the VScrollBar of a TListBox in TComboBox and TComboEdit in order to find a TThumb inside of it (using the EnumControls method) and set custom OnMouseEnter, OnMouseLeave, OnMouseDown and OnMouseUp events, like this:

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;

    }

};

if (ComboBox->ListBox->VScrollBar) ComboBox->ListBox->VScrollBar->EnumControls(new TScrollThumb);

// TScrollBar *scrollbar = ComboBox->ListBox->GetVScrollBar();
// if (scrollbar) scrollBar->EnumControls(new TScrollThumb);

The VScrollBar property is a protected member of Fmx::Layouts::TCustomScrollBox and GetVScrollBar() is a private member of Fmx::Layouts::TCustomScrollBox, but even making them public does nothing, I still can't access the VScrollBar.

The same approach works great for TThumb inside a TVertScrollBox. What can I do in this case?


Solution

  • I seem to have found a solution myself. A bit tricky, but it works like a charm. So I'll just post it here as is:

    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;
    
        }
    
    };
    
    void __fastcall ListBoxMouseEnter(TObject *Sender) {
    
        ((TControl*)Sender)->EnumControls(new TScrollThumb);
        // The tricky part: working with a ListBox inside of its own event handler;
    
    }
    
    ComboBox->ListBox->OnMouseEnter = ListBoxMouseEnter;
    // Assign an auxiliary event handler to a ListBox that has already been displayed;
    
    ComboEdit->Presentation->ListBox->OnMouseEnter = ListBoxMouseEnter;
    // Same trick for ComboEdit;