TScrollBox控件之页面滚动

利用TScrollBox控件在OnMouseWheel事件中滑轮滚动事件。

方法一:

模拟人工操作:

    if  WheelDelta < 0 then
      ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + 5
    else
      ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - 5;

优点:对于程序员容易理解,容易想到;

缺点:重影很明显;

方法二:

调用Windows发送消息方法:

  //Windows API
  //如果鼠标不在当前控件之上,则不处理鼠标滚动事件
  if not (IsChild(ScrollBox1.Handle, WindowFromPoint(MousePos)) or
     (ScrollBox1.Handle = WindowFromPoint(MousePos))) then Exit;
     
  if WheelDelta < 0 then
    SendMessage(ScrollBox1.Handle, WM_VSCROLL, SB_LINEDOWN, 0)
  else
    SendMessage(ScrollBox1.Handle, WM_VSCROLL, SB_LINEUP, 0);

优点:重影有所缓解,原因在于SendMessage机制:如果消息连续重复则执行一次,并且是轮旋机制处理;

缺点:刷新速度级别对于某些特殊要求下不能满足;

方法三:

Delphi 控件的Perform方法:

  if WheelDelta < 0 then
    ScrollBox1.Perform(WM_VSCROLL, SB_LINEDOWN, 0)
  else
    ScrollBox1.Perform(WM_VSCROLL, SB_LINEUP, 0);

优点:能看到源代码,直到汇编语言执行内容;

缺点:同上

在执行发送消息之后需要调用控件的重新绘制命令,方法有二:

法一:控件.Update    抖动明显

法二:控件.Repaint   抖动不那么明显

所有代码如下:

procedure TMyTestFrm.ScrollBox1MouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
  var Handled: Boolean);
begin

    //模拟人工操作
  //  if  WheelDelta < 0 then
  //    ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position + 5
  //  else
  //    ScrollBox1.VertScrollBar.Position := ScrollBox1.VertScrollBar.Position - 5;

  //Windows API
  //如果鼠标不在当前控件之上,则不处理鼠标滚动事件
  if not (IsChild(ScrollBox1.Handle, WindowFromPoint(MousePos)) or
     (ScrollBox1.Handle = WindowFromPoint(MousePos))) then Exit;
     
  if WheelDelta < 0 then
    SendMessage(ScrollBox1.Handle, WM_VSCROLL, SB_LINEDOWN, 0)
  else
    SendMessage(ScrollBox1.Handle, WM_VSCROLL, SB_LINEUP, 0);
    
  //Delphi 方法
//  if WheelDelta < 0 then
//    ScrollBox1.Perform(WM_VSCROLL, SB_LINEDOWN, 0)
//  else
//    ScrollBox1.Perform(WM_VSCROLL, SB_LINEUP, 0);

   //Update 与 Repaint 比较
//  ScrollBox1.Parent.Update; //采用Update方法比不用滚动重影没那么明显,但是还是存在;
  ScrollBox1.Parent.Repaint;
end;

2022-07-22补充:

对于重影与连续滑动的问题,设置Handled:=True会有比较明显的改善;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值