怎样实现两个Grid之间的滚动轴拖动事件响应
既是左边的Grid滚动轴拖动,右边的Grid的滚动轴也跟着移动。

解决方案 »

  1.   

    两个Grid的同步滚动    在实际制作一个项目当中,有时候需要几个grid一起同步滚动以减少用户的操作量。希望下面那段代码对您有一定的参考价值。{1.}unit SyncStringGrid;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids;type
      TSyncKind = (skBoth, skVScroll, skHScroll);
      TSyncStringGrid = class(TStringGrid)private
      FInSync: Boolean;
      FsyncGrid: TSyncStringGrid;
      FSyncKind: TSyncKind;
    { Private declarations }
      procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL;
      procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;protected
    { Protected declarations }public
    { Public declarations }
      procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;published
    { Published declarations }
      property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
      property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
    end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('Samples', [TSyncStringGrid]);
    end;procedure TSyncStringGrid.WMVScroll(var Msg: TMessage);
    begin
      if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then
        FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam);
      inherited;
    end;procedure TSyncStringGrid.WMHScroll(var Msg: TMessage);
    begin
      if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then
        FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam);
      inherited;
    end;procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);
    begin
      FInSync := True;
      Perform(Msg, wParam, lParam);
      FinSync := False;
    end;end.{****************************************}{2.}
    private
      OldGridProc1, OldGridProc2: TWndMethod;
      procedure Grid1WindowProc(var Message: TMessage);
      procedure Grid2WindowProc(var Message: TMessage);public
    {...}procedure TForm1.Grid1WindowProc(var Message: TMessage);begin
      OldGridProc1(Message);
      if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then
      begin
        OldGridProc2(Message);
      end;
    end;procedure TForm1.Grid2WindowProc(var Message: TMessage);
    begin
      OldGridProc2(Message);
      if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
      begin
        OldGridProc1(Message);
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      OldGridProc1 := StringGrid1.WindowProc;
      OldGridProc2 := StringGrid2.WindowProc;
      StringGrid1.WindowProc := Grid1WindowProc;
      StringGrid2.WindowProc := Grid2WindowProc;
    end;
      

  2.   

    meiqingsong(阿飛)  老兄,你这个用 ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) 的方法好复杂,暂时还看不懂。我目前就是找不到,什么事件是反映鼠标拖动了滚动轴。
    我下面这个方法是使用鼠标点击来实现数据指针的移动的。
    可是不尽如人意。procedure TFormTwoGrid.FormShow(Sender: TObject);
    begin      
      YDBGrid1.OnCellClick := OneCellClick;
      YDBGrid2.OnCellClick := TwoCellClick;
    end;procedure TFormTwoGrid.OneCellClick(Column: TColumnEh);
    var
      Row,MaxRow: Integer;
    begin
      if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then
      begin
        MaxRow := DatasetOne.RecordCount;
        Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow;
        DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定右边
        Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow;
        DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定左边
      end;
    end;procedure TFormTwoGrid.TwoCellClick(Column: TColumnEh);
    var
      Row,MaxRow: Integer;
    begin
      if (DatasetOne.RecordCount = DatasetTwo.RecordCount) then
      begin
        MaxRow := DatasetOne.RecordCount;
        Row := StrToInt(DatasetTwo.FieldByName('IdentPart').AsString) - MaxRow;
        DatasetOne.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //确定左边
        Row := StrToInt(DatasetOne.FieldByName('IdentPart').AsString) + MaxRow;
        DatasetTwo.Locate('IdentPart',IntToStr(Row),[loCaseInsensitive]); //重新确定右边
      end;
    end;
      

  3.   

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      OldGridProc1 := StringGrid1.WindowProc;  //保存StringGrid1的窗口处理过程
      OldGridProc2 := StringGrid2.WindowProc;  //保存StringGrid2的窗口处理过程
      StringGrid1.WindowProc := Grid1WindowProc; //设置StringGrid1的窗口处理为Grid1WindowProc
      StringGrid2.WindowProc := Grid2WindowProc; //设置StringGrid2的窗口处理为Grid2WindowProc
    end;WindowProc过程 处理该控件的各种消息
    ((Message.Msg = WM_VSCROLL)   垂直滚动条滚动产生的消息
     or (Message.Msg = WM_HSCROLL) 水平滚动条滚动产生的消息
     or Message.msg = WM_Mousewheel)) 鼠标的滑轮滚动产生的消息
      

  4.   

    meiqingsong(阿飛) 老兄:
      你只给出了滚动条的消息代码是:WM_VSCROLL,WM_HSCROLL,WM_Mousewheel
    要实现完美,还要鼠标“点击”,和按“上下键”的代码。
      

  5.   

    要实现完美,还要鼠标“点击”,和按“上下键”的代码
    1。鼠标“点击”,
       鼠标“点击”滚动条会产生滚动条的滚动消息,无需再处理
    2。
    按“上下键”的代码
    --你把
      procedure TForm1.Grid1WindowProc(var Message: TMessage); 和
      procedure TForm1.Grid2WindowProc(var Message: TMessage); 中的  if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
    改为
      if ((Message.Msg = WM_VSCROLL)
        or (Message.Msg = WM_HSCROLL)
        or (Message.msg = WM_Mousewheel)
        or ((Message.Msg = wm_keydown) and
           (TWMKeyDown(Message).CharCode in[VK_DOWN, VK_UP, VK_LEFT, VK_RIGHT]))) then
    就可以了