【问题标题】:scrollbox mouse wheel delphi滚动框鼠标滚轮delphi
【发布时间】:2018-10-31 14:18:22
【问题描述】:

如何将OnMouseWheel 添加到两个滚动框的同一个表单中?我将方法应用到ScrollBox1,但我不知道如何将方法添加到ScrollBox2

procedure TForm3.FormMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  LTopLeft, LTopRight, LBottomLeft, LBottomRight: SmallInt;
  LPoint: TPoint;
begin
   inherited;
  LPoint := ScrollBox1.ClientToScreen(Point(0,0));

  LTopLeft := LPoint.X;
  LTopRight := LTopLeft + ScrollBox1.Width;

  LBottomLeft := LPoint.Y;
  LBottomRight := LBottomLeft + ScrollBox1.Width;


  if (MousePos.X >= LTopLeft) and
    (MousePos.X <= LTopRight) and
    (MousePos.Y >= LBottomLeft)and
    (MousePos.Y <= LBottomRight) then
  begin
    ScrollBox1.VertScrollBar.Position :=
    ScrollBox1.VertScrollBar.Position - WheelDelta;

    Handled := True;
  end;
end;

【问题讨论】:

    标签: delphi vcl


    【解决方案1】:

    将相同的处理程序分配给两个 ScrollBox 组件,而不是分配给 Form,然后使用 Sender 参数知道哪个组件正在调用处理程序。

    procedure TForm3.ScrollBoxMouseWheel(Sender: TObject;
      Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
      var Handled: Boolean);
    var
      LTopLeft, LTopRight, LBottomLeft, LBottomRight: SmallInt;
      LPoint: TPoint;
      ScrollBox: TScrollBox;
    begin
      ScrollBox := TScrollBox(Sender);
      LPoint := ScrollBox.ClientToScreen(Point(0,0));
      LTopLeft := LPoint.X;
      LTopRight := LTopLeft + ScrollBox.ClientWidth;
      LBottomLeft := LPoint.Y;
      LBottomRight := LBottomLeft + ScrollBox.ClientWidth;
      if (MousePos.X >= LTopLeft) and
        (MousePos.X <= LTopRight) and
        (MousePos.Y >= LBottomLeft) and
        (MousePos.Y <= LBottomRight) then
      begin
        ScrollBox.VertScrollBar.Position := ScrollBox.VertScrollBar.Position - WheelDelta;
        Handled := True;
      end;
    end;
    

    【讨论】:

    • 谢谢,你能给我举个例子吗
    • 你完全复制了代码,没有工作。有名字要分配吗?我有 ScrollBox1 ,,,ScrollBox2
    • @Alhmam repeat 再读一遍代码前的文字 until understood; 然后仔细看看局部变量ScrollBox: TScrollBox;是怎么使用的。此行之后:ScrollBox := TScrollBox(Sender);ScrollBox 指的是触发事件的实际滚动框(您的ScrollBox1ScrollBox2)。因此设置了正确滚动框的滚动条位置。这是一个典型的例子,说明为什么以及如何避免在事件处理程序中直接引用触发控件。
    • @AlhmamAlhmam Sender 在这里很重要。如果用户将鼠标指向ScrollBox1 并滚动鼠标滚轮,则会触发此事件,Sender 将指向ScrollBox1。此事件处理程序中的代码进一步直接引用任何特定控件,而是使用在事件处理程序中作为Sender 传递的任何内容。只需将相同的事件处理程序分配给表单上的任何TScrollBox,它就会自动将此代码用于用户尝试滚动的任何滚动框。
    • 此代码仅在 ScrollBox 中没有控件时才有效。如果有,那么一旦这些控件之一位于鼠标指针下方,用户将无法滚动。
    【解决方案2】:
    Uses Math;
    
    procedure TMainForm.ScrollBoxMouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    var
      ScrollBox: TScrollBox;
      NewPos: Integer;
    begin
      ScrollBox := TScrollBox(Sender);
    
      NewPos:= ScrollBox.VertScrollBar.Position - WheelDelta div 10;  // sensitivity
      NewPos:= Max(NewPos, 0);
      NewPos:= Min(NewPos, ScrollBox.VertScrollBar.Range);
    
      ScrollBox.VertScrollBar.Position := NewPos;
      Handled := True;
    end;
    

    【讨论】:

    • 任何让提问者朝着正确方向前进的答案都是有帮助的,但请尝试在您的答案中提及任何限制、假设或简化。简洁是可以接受的,但更全面的解释会更好。
    猜你喜欢
    • 1970-01-01
    • 2011-09-29
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多