CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Sprzężenie scrollbar'ów

Sprzężenie scrollbar'ów

dział ogólny

Sprzężenie scrollbar'ów

Nowy postprzez Pitek » poniedziałek, 21 marca 2011, 19:45

Witam!
Mam pytanie, jak zrobić aby ruszając jednym scrollbar'em w ListBox1, ruszał się także ten w ListBox2, najlepiej w czasie rzeczywistym.
Scrollbar'ów może być więcej.
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Cyfrowy Baron » poniedziałek, 21 marca 2011, 21:05

Po kliknięciu w Button:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 SCROLLINFO lpsi;
 lpsi.fMask = SIF_ALL;

 GetScrollInfo(ListBox1->Handle, SB_VERT, &lpsi);

 PostMessage(ListBox2->Handle, WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nPos), 0);
}


Jednoczesne przesuwanie:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:
        TWndMethod Sc;
        void __fastcall MoveScroll(TMessage &Msg);


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 Sc = ListBox1->WindowProc;
 ListBox1->WindowProc = MoveScroll;
}
//--------------------------------
void __fastcall TForm1::MoveScroll(TMessage &Msg)
{
 if(Msg.Msg == WM_VSCROLL)
 {
  SCROLLINFO lpsi;
  lpsi.fMask = SIF_ALL;

  GetScrollInfo(ListBox1->Handle, SB_VERT, &lpsi);

  PostMessage(ListBox2->Handle, WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nPos), 0);
 }
 Sc(Msg);
}


Przedstawiony sposób pozwala na przesuwanie paska pionowego, dla paska poziomego należy zmienić SB_VERT na SB_HORZ, a WM_VSCROLL na WM_HSCROLL, może to wyglądać tak:

KOD cpp:     UKRYJ  
void __fastcall TForm1::MoveScroll(TMessage &Msg)
{
 if(Msg.Msg == WM_VSCROLL | WM_HSCROLL)
 {
  SCROLLINFO lpsi, hpsi;
  lpsi.fMask = SIF_ALL;
  hpsi.fMask = SIF_ALL;
 
  GetScrollInfo(ListBox3->Handle, SB_VERT, &lpsi);
  GetScrollInfo(ListBox3->Handle, SB_HORZ, &hpsi);

  PostMessage(ListBox2->Handle, WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nPos), 0);
  PostMessage(ListBox2->Handle, WM_HSCROLL, SB_THUMBTRACK + (0x10000 * hpsi.nPos), 0);
 }
 Sc(Msg);
}

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Pitek
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Pitek » poniedziałek, 21 marca 2011, 21:18

Wszystko jest OK!
Jednak pojawia się pewien bug. Mianowicie index w stosunku do pierwszej listy w drugiej jest o 2 większy. Czyli mając na samej górze na liście pierwszej np. pozycję 30 to na drugiej liście jest 32. Po puszczeniu myszki to się niweluje jednak w mojej aplikacji głównie chodzi o to aby pozycje były równo bez puszczania myszki. Jak to naprawić ? Oraz jak zastosować ten kod do 3 list ?
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Cyfrowy Baron » poniedziałek, 21 marca 2011, 23:02

pitek3010 napisał(a):Jednak pojawia się pewien bug. Mianowicie index w stosunku do pierwszej listy w drugiej jest o 2 większy.


Jeżeli na obydwu listach ItemIndex ma ten sam numer i w chwili rozpoczęcia przesuwania obie listy mają suwaki w tej samej pozycji oraz maja taki sam rozmiar to powinno działać prawidłowo.



pitek3010 napisał(a):Oraz jak zastosować ten kod do 3 list ?


To pytanie mnie załamało, gdyż oznacza, że nie rozumiesz kodu.

KOD cpp:     UKRYJ  
void __fastcall TForm1::MoveScroll(TMessage &Msg)
{
 if(Msg.Msg == WM_VSCROLL | WM_HSCROLL)
 {
  SCROLLINFO lpsi, hpsi;
  lpsi.fMask = SIF_ALL;
  hpsi.fMask = SIF_ALL;
 
  GetScrollInfo(ListBox1->Handle, SB_VERT, &lpsi);
  GetScrollInfo(ListBox1->Handle, SB_HORZ, &hpsi);

  PostMessage(ListBox2->Handle, WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nPos), 0);
  PostMessage(ListBox2->Handle, WM_HSCROLL, SB_THUMBTRACK + (0x10000 * hpsi.nPos), 0);

  PostMessage(ListBox3->Handle, WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nPos), 0);
  PostMessage(ListBox3->Handle, WM_HSCROLL, SB_THUMBTRACK + (0x10000 * hpsi.nPos), 0);
 }
 Sc(Msg);
}


a wystarczyło pomyśleć... :x
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Pitek » wtorek, 22 marca 2011, 00:50

Cyfrowy Baron napisał(a):Jeżeli na obydwu listach ItemIndex ma ten sam numer i w chwili rozpoczęcia przesuwania obie listy mają suwaki w tej samej pozycji oraz maja taki sam rozmiar to powinno działać prawidłowo.

Jest dokładnie tak jak Pan napisał jednak nie działa to prawidłowo dalej jest o 2 za dużo w drugim w stosunku do pierwszego. W dodatku zauważyłem że jeżeli elementów na liście jest więcej niż 1000 to jest różnica o 3 i analogicznie 2000 o 4... a o 2 zaczyna się od 544 pozycji.... trochę dziwne. :zawiedziony:
Cyfrowy Baron napisał(a):To pytanie mnie załamało, gdyż oznacza, że nie rozumiesz kodu.

Kod rozumiem, na to wpadłem ale kod działa tylko wtedy gdy zaczynam od pierwszego suwaka. Mi chodziło o to aby one były połączone każdym suwakiem nie ważne którym bym przesuwał. Da się to jakoś krótko zrobić, czy trzeba dla każdego suwaka osobno wszystko deklarować ?
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Cyfrowy Baron » wtorek, 22 marca 2011, 09:39

pitek3010 napisał(a):Jest dokładnie tak jak Pan napisał jednak nie działa to prawidłowo dalej jest o 2 za dużo w drugim w stosunku do pierwszego. W dodatku zauważyłem że jeżeli elementów na liście jest więcej niż 1000 to jest różnica o 3 i analogicznie 2000 o 4... a o 2 zaczyna się od 544 pozycji.... trochę dziwne. :zawiedziony:


Należy zmienić parametr lpsi.nPos na lpsi.nTrackPos:

KOD cpp:     UKRYJ  
void __fastcall TForm1::MoveScroll(TMessage &Msg)
{
 if(Msg.Msg == WM_VSCROLL)
 {
  SCROLLINFO lpsi;
  lpsi.fMask = SIF_ALL;

  GetScrollInfo(ListBox1->Handle, SB_VERT, &lpsi);

  PostMessage(ListBox2->Handle,
    WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nTrackPos), 0);
 }
 Sc(Msg);
}


Zauważ jednak, że w przypadku list o różnej długości synchronizacja będzie przebiegać prawidłowo tylko do czasu, gdy elementy listy się zgadzają, potem suwak np. na liście dłuższej zejdzie niżej, a na liście krótszej już się zatrzyma, więc scrollbar'y się rozsynchronizują.



pitek3010 napisał(a):Kod rozumiem, na to wpadłem ale kod działa tylko wtedy gdy zaczynam od pierwszego suwaka. Mi chodziło o to aby one były połączone każdym suwakiem nie ważne którym bym przesuwał. Da się to jakoś krótko zrobić, czy trzeba dla każdego suwaka osobno wszystko deklarować ?


Z tym jest problem, gdyż nie da się już korzystać z przechwytywania komunikatów o przesunięciu suwaków dlatego należy użyć obiektu TTimer.
Dla pierwszej listy ListBox1 tworzymy zdarzenia OnMouseActivate oraz OnMouseLeave, a w pliku nagłówkowym deklarujemy obiekt typu TComponent. Umieszczamy na formularzu komponent Timer1 typu TTimer i ustawiamy mu właściwość Enabled = false; Interval = 10. Tworzymy również zdarzenie OnTimer dla obiektu Timer1 i umieszczamy w nim kod sterujący suwakami.

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:        // User declarations
        TComponent *Comp;


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
void __fastcall TForm1::ListBox1MouseActivate(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y, int HitTest, TMouseActivate &MouseActivate)

{
 Comp = reinterpret_cast<TComponent *>(Sender);
 Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ListBox1MouseLeave(TObject *Sender)
{
 Timer1->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  SCROLLINFO lpsi;
  lpsi.fMask = SIF_ALL;

  GetScrollInfo(reinterpret_cast<TWinControl *>(Comp)->Handle, SB_VERT, &lpsi);

  int iLbCount = 3; /* liczba obiektów ListBox na formularzu, którymi sterujemy */
  for(int i = 1; i <= iLbCount; i++)
  {
   TComponent *tLbComp = FindComponent("ListBox" + (String)i);

   if(Comp->Name != tLbComp->Name)
   {
    PostMessage(reinterpret_cast<TWinControl *>(tLbComp)->Handle,
      WM_VSCROLL, SB_THUMBTRACK + (0x10000 * lpsi.nTrackPos), 0);
   }
  }
}


Na razie tylko ListBox1 jest obiektem sterującym, by to zmienić trzeba pozostałe ListBox'y podłączyć pod zdarzenia OnMouseActivate oraz OnMouseLeave obiektu ListBox1. Dla pozostałych ListBox'ów w Object inspector na zakładce Evensts w polu OnMouseActivate wybieramy ListBox1MouseActivate . W polu OnMouseLeave wybieramy ListBox1MouseLeave. Postępujemy tak z każdym ListBox'em, który chcemy podłączyć pod wybrane zdarzenia obiektu ListBox1.
oobject_inspector.png
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Pitek
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Sprzężenie scrollbar'ów

Nowy postprzez Pitek » wtorek, 22 marca 2011, 15:05

Cyfrowy Baron napisał(a):Należy zmienić parametr lpsi.nPos na lpsi.nTrackPos:

Rewelacja! Wszystko działa!

Cyfrowy Baron napisał(a):Zauważ jednak, że w przypadku list o różnej długości synchronizacja będzie przebiegać prawidłowo tylko do czasu, gdy elementy listy się zgadzają, potem suwak np. na liście dłuższej zejdzie niżej, a na liście krótszej już się zatrzyma, więc scrollbar'y się rozsynchronizują.

Tak tak, wiem jednak u mnie nie ma i nie będzie sytuacji w której ilość pozycji na którejkolwiek z list będzie różna, tak więc jest OK!

Jeszcze raz dziękuję za pomoc!

Pozdrawiam
Komputer służy do tego aby ułatwić Ci pracę, której bez niego w ogóle byś nie miał.
E.Murphy
http://piotrekprogramy.pl
Avatar użytkownika
Pitek
Kreacjusz
Kreacjusz
 
Posty: 290
Dołączył(a): środa, 14 października 2009, 14:53
Lokalizacja: Rybnik/Wrocław
Podziękował : 43
Otrzymał podziękowań: 5
System operacyjny: Win 7 Ultimate 64bit SP1 / Ubuntu 19.04 LTS 64bit
Kompilator: Embarcadero RAD Studio XE2
SKYPE: pitek3010
Gadu Gadu: 7060047
    Windows XPFirefox


Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 6 gości