Quantcast
Channel: Programming - Embarcadero Community
Viewing all articles
Browse latest Browse all 167

C++Builder: Paralleles Scrollen von Memos (TMemo) in FireMonkey mit der ViewportPosition

$
0
0

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


Viewing all articles
Browse latest Browse all 167

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>