Ho 2 TTrevisioni. Entrambi hanno lo stesso numero di oggetti. Mi piacerebbe essere in grado di sincronizzare loro barre di scorrimento ... Se mi muovo uno di loro, l'altra si muove anche ...Come sincronizzare lo scorrimento di 2 TTrevisualizza?
Per l'orizzontale, funziona come mi aspetto ... per verticale, funziona se uso le frecce della barra di scorrimento, ma non se trascinare il pollice o se uso la rotellina del mouse ...
Ecco un esempio ho scritto per illustrare il mio problema:
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StrUtils;
type
TForm1 = class(TForm)
tv1: TTreeView;
tv2: TTreeView;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
originalTv1WindowProc : TWndMethod;
originalTv2WindowProc : TWndMethod;
procedure Tv1WindowProc (var Msg : TMessage);
procedure Tv2WindowProc (var Msg : TMessage);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 10 do
begin
tv1.Items.AddChild(nil, DupeString('A', 20) + IntToStr(i));
tv2.Items.AddChild(nil, DupeString('B', 20) + IntToStr(i));
end;
originalTv1WindowProc := tv1.WindowProc;
tv1.WindowProc := Tv1WindowProc;
originalTv2WindowProc := tv2.WindowProc;
tv2.WindowProc := Tv2WindowProc;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
tv1.WindowProc := originalTv1WindowProc;
tv2.WindowProc := originalTv2WindowProc;
originalTv1WindowProc := nil;
originalTv2WindowProc := nil;
end;
procedure TForm1.Tv1WindowProc(var Msg: TMessage);
begin
originalTv1WindowProc(Msg);
if ((Msg.Msg = WM_VSCROLL)
or (Msg.Msg = WM_HSCROLL)
or (Msg.msg = WM_Mousewheel)) then
begin
// tv2.Perform(Msg.Msg, Msg.wparam, Msg.lparam);
originalTv2WindowProc(Msg);
end;
end;
procedure TForm1.Tv2WindowProc(var Msg: TMessage);
begin
originalTv2WindowProc(Msg);
if ((Msg.Msg = WM_VSCROLL)
or (Msg.Msg = WM_HSCROLL)
or (Msg.msg = WM_Mousewheel)) then
begin
// tv1.Perform(Msg.Msg, Msg.wparam, Msg.lparam);
originalTv1WindowProc(Msg);
end;
end;
end.
Il DFM:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 113
ClientWidth = 274
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object tv1: TTreeView
Left = 8
Top = 8
Width = 121
Height = 97
Indent = 19
TabOrder = 0
end
object tv2: TTreeView
Left = 144
Top = 8
Width = 121
Height = 97
Indent = 19
TabOrder = 1
end
end
Ho provato anche la creazione di una sottoclasse da TTreeView, ma senza successo (stesso comportamento) ... ho provato con un TMemo, e funziona come previsto ...
Cosa mi sono perso?
Cheers,
W.
Durante le mie prove, ho pensato di togliere il tema VCL, ma non ho provato, senza temi di runtime ... BTW, ho testato con successo il tuo codice e la risposta è chiaramente accettata in quanto fa esattamente quello che stavo cercando ... – Whiler
@ sertac-akyuz: In effetti, WM_MOUSEWHEEL continua a non funzionare come previsto ... poiché l'altra anteprima non è focalizzata, non sono sicuro che l'inoltro di TMessage sia sufficiente per fare ciò che voglio veramente ... qualsiasi idea ? – Whiler
Ok, gestisco la rotellina del mouse con questo: 'procedura TForm1.FormMouseWheelDown (Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin tv1.Perform (WM_VSCROLL, 1, 0); gestito: = True; fine; procedure TForm1.FormMouseWheelUp (Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin tv1.Perform (WM_VSCROLL, 0, 0); gestito: = True; fine; ' – Whiler