In früheren C++Builder/Delphi Versionen hat man innerhalb von FireMonkey ein paralleles Scrollen von ListBoxen (oder anderen, visuellen Komponenten) zumeist über die Position der Scrollbars erreichen können.
Ein kleines Video dazu:
[YoutubeButton url='https://youtu.be/zrJnNyYQ-ig']
Dazu eine eigene Klasse definiert, um die Werte der horizontalen und vertikalen Scrollbar zu bekommen):
class MyMemo : public TMemo
{
private:
float gHScrollBarValue() {return HScrollBar->Value;}
float gVScrollBarValue() {return VScrollBar->Value;}
void sHScrollBarValue(float value) {HScrollBar->Value=value;}
void sVScrollBarValue(float value) {VScrollBar->Value=value;}
public:
MyMemo(TForm *form):TMemo(form) {}
float getHScrollBarValue() {return gHScrollBarValue();}
float getVScrollBarValue() {return gVScrollBarValue();}
void setHScrollBarValue(float value) {sHScrollBarValue(value);}
void setVScrollBarValue(float value) {sVScrollBarValue(value);}
};
Und die passenden Methoden definiert (hier am Beispiel von 2 GUI TMemo Komponenten, die sich gegenseitig scrollen sollen. Berücksichtig werden dabei ScrollBar (Horizontal/Vertikal), MouseWheel Events (H/V), wie auch Tastatur-Events (H/V):
void __fastcall TForm5::MyScrollBarHChangeMemo1(TObject *Sender)
{
myMemo2->setHScrollBarValue(myMemo1->getHScrollBarValue());
}
void __fastcall TForm5::MyScrollBarVChangeMemo1(TObject *Sender)
{
myMemo2->setVScrollBarValue(myMemo1->getVScrollBarValue());
}
void __fastcall TForm5::MyScrollBarHChangeMemo2(TObject *Sender)
{
myMemo1->setHScrollBarValue(myMemo2->getHScrollBarValue());
}
void __fastcall TForm5::MyScrollBarVChangeMemo2(TObject *Sender)
{
myMemo1->setVScrollBarValue(myMemo2->getVScrollBarValue());
}
void __fastcall TForm5::MyMouseWheel1(TObject *Sender, TShiftState Shift, int WheelDelta, bool &Handled)
{
myMemo2->setHScrollBarValue(myMemo1->getHScrollBarValue());
myMemo2->setVScrollBarValue(myMemo1->getVScrollBarValue());
}
void __fastcall TForm5::MyMouseWheel2(TObject *Sender, TShiftState Shift, int WheelDelta, bool &Handled)
{
myMemo1->setHScrollBarValue(myMemo2->getHScrollBarValue());
myMemo1->setVScrollBarValue(myMemo2->getVScrollBarValue());
}
void __fastcall TForm5::MemoKeyDown1(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift)
{
myMemo2->setHScrollBarValue(myMemo1->getHScrollBarValue());
myMemo2->setVScrollBarValue(myMemo1->getVScrollBarValue());
}
void __fastcall TForm5::MemoKeyDown2(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift)
{
myMemo1->setHScrollBarValue(myMemo2->getHScrollBarValue());
myMemo1->setVScrollBarValue(myMemo2->getVScrollBarValue());
}
Jetzt gibt es nur ein kleines Problem: In C++Builder 10.1 Berlin hat ein TMemo keine HScrollBar/VScrollBar mehr.
Die gute Nachricht ist, daß man das leicht umstellen kann. Jedes visuelle GUI Element, welches Scrollbars darstellen kann, kennt einen "ViewportPosition", der X- und Y-Positionen zur Verfügung stellt (TPointF)... dadurch wird der Quelltext auch einfacher und übersichtlicher:
NEU:
class MyMemo : public TMemo
{
private:
System::Types::TPointF gScrollBarValue() {return ViewportPosition;}
void sScrollBarValue(System::Types::TPointF value) {ViewportPosition=value;}
public:
MyMemo(TForm *form):TMemo(form) {}
System::Types::TPointF getScrollBarValue() {return gScrollBarValue();}
void setScrollBarValue(System::Types::TPointF value) {sScrollBarValue(value);}
};
Und die Methoden (auch wieder für Tastatur, Maus und Scrollbar-Events):
void __fastcall TForm5::MyScrollBarChangeMemo1(TObject *Sender, const TPointF &OldViewportPosition, const TPointF &NewViewportPosition, const bool ContentSizeChanged)
{
myMemo2->setScrollBarValue(myMemo1->getScrollBarValue());
}
void __fastcall TForm5::MyScrollBarChangeMemo2(TObject *Sender, const TPointF &OldViewportPosition, const TPointF &NewViewportPosition, const bool ContentSizeChanged)
{
myMemo1->setScrollBarValue(myMemo2->getScrollBarValue());
}
void __fastcall TForm5::MyMouseWheel1(TObject *Sender, TShiftState Shift, int WheelDelta, bool &Handled)
{
myMemo2->setScrollBarValue(myMemo1->getScrollBarValue());
}
void __fastcall TForm5::MyMouseWheel2(TObject *Sender, TShiftState Shift, int WheelDelta, bool &Handled)
{
myMemo1->setScrollBarValue(myMemo2->getScrollBarValue());
}
void __fastcall TForm5::MemoKeyDown1(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift)
{
myMemo2->setScrollBarValue(myMemo1->getScrollBarValue());
}
void __fastcall TForm5::MemoKeyDown2(TObject *Sender, WORD &Key, System::WideChar &KeyChar, TShiftState Shift)
{
myMemo1->setScrollBarValue(myMemo2->getScrollBarValue());
}
Beispielanwendung (Source, C++Builder 10.1 Berlin) hier:
ScrollDemoViewPort