- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个派生自 TScrollbox 的自定义滚动框,它的工作原理相同,只是当在客户区域中拖动滚动条之外时它会滚动。
我现在的问题是,当鼠标位于 CustomScrollbox 内的按钮或面板上时,我无法拖动滚动。
MouseDown、MouseUp、MouseMove 覆盖不会触发,因为它悬停在不同的控件中。
当我开始拖动时,如何继续跟踪 MouseDown、MouseUp、MouseMove 并防止触发 Button/Panels 事件(在我的 CustomScrollbox 内)?
这是我的视频 smooth CustomScrollbox
最佳答案
因此,您想要调整所有子项的鼠标按下行为,以便在启动拖动操作时,应忽略被单击子项的鼠标事件。但是,当不执行拖动时,则需要像往常一样触发子级的鼠标事件。
实际上这不是一个坏问题。由于大多数默认控件交互都与鼠标按钮的释放紧密相关(例如OnClick
在WM_LBUTTONUP
中处理),所以这仍然应该是以直观的方式实现。
我尝试了下面的代码,感觉确实不错。它涉及:
WM_PARENTNOTIFY
以捕获子控件被单击的情况,Child.OnMouseMove
和Child.OnMouseUp
,Mouse.DragThreshold
时,将控制转移到滚动框,unit Unit2;
interface
uses
Windows, Messages, Classes, Controls, Forms, StdCtrls, ExtCtrls;
type
TScrollBox = class(Forms.TScrollBox)
private
FChild: TControl;
FDragging: Boolean;
FPrevActiveControl: TWinControl;
FPrevScrollPos: TPoint;
FPrevTick: Cardinal;
FOldChildOnMouseMove: TMouseMoveEvent;
FOldChildOnMouseUp: TMouseEvent;
FSpeedX: Single;
FSpeedY: Single;
FStartPos: TPoint;
FTracker: TTimer;
function ActiveControl: TWinControl;
procedure ChildMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure ChildMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
function GetScrollPos: TPoint;
procedure SetScrollPos(const Value: TPoint);
procedure Track(Sender: TObject);
procedure WMParentNotify(var Message: TWMParentNotify);
message WM_PARENTNOTIFY;
protected
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer); override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer); override;
public
constructor Create(AOwner: TComponent); override;
property ScrollPos: TPoint read GetScrollPos write SetScrollPos;
end;
TForm2 = class(TForm)
ScrollBox1: TScrollBox;
...
end;
implementation
{$R *.dfm}
{ TScrollBox }
type
TControlAccess = class(TControl);
function TScrollBox.ActiveControl: TWinControl;
var
Control: TWinControl;
begin
Result := Screen.ActiveControl;
Control := Result;
while (Control <> nil) do
begin
if Control = Self then
Exit;
Control := Control.Parent;
end;
Result := nil;
end;
procedure TScrollBox.ChildMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if (Abs(FChild.Left + X - FStartPos.X) > Mouse.DragThreshold) or
(Abs(FChild.Top + Y - FStartPos.Y) > Mouse.DragThreshold) then
begin
MouseCapture := True;
TControlAccess(FChild).OnMouseMove := FOldChildOnMouseMove;
TControlAccess(FChild).OnMouseUp := FOldChildOnMouseUp;
MouseDown(mbLeft, Shift, FChild.Left + X, FChild.Top + Y);
FChild := nil;
if FPrevActiveControl <> nil then
FPrevActiveControl.SetFocus;
end
else
if Assigned(FOldChildOnMouseMove) then
FOldChildOnMouseMove(Sender, Shift, X, Y);
end;
procedure TScrollBox.ChildMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if FChild <> nil then
begin
if Assigned(FOldChildOnMouseUp) then
FOldChildOnMouseUp(Sender, Button, Shift, X, Y);
TControlAccess(FChild).OnMouseMove := FOldChildOnMouseMove;
TControlAccess(FChild).OnMouseUp := FOldChildOnMouseUp;
FChild := nil;
end;
end;
constructor TScrollBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FTracker := TTimer.Create(Self);
FTracker.Enabled := False;
FTracker.Interval := 15;
FTracker.OnTimer := Track;
end;
function TScrollBox.GetScrollPos: TPoint;
begin
Result := Point(HorzScrollBar.Position, VertScrollBar.Position);
end;
procedure TScrollBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
FDragging := True;
FPrevTick := GetTickCount;
FPrevScrollPos := ScrollPos;
FTracker.Enabled := True;
FStartPos := Point(ScrollPos.X + X, ScrollPos.Y + Y);
Screen.Cursor := crHandPoint;
inherited MouseDown(Button, Shift, X, Y);
end;
procedure TScrollBox.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
if FDragging then
ScrollPos := Point(FStartPos.X - X, FStartPos.Y - Y);
inherited MouseMove(Shift, X, Y);
end;
procedure TScrollBox.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
FDragging := False;
Screen.Cursor := crDefault;
inherited MouseUp(Button, Shift, X, Y);
end;
procedure TScrollBox.SetScrollPos(const Value: TPoint);
begin
HorzScrollBar.Position := Value.X;
VertScrollBar.Position := Value.Y;
end;
procedure TScrollBox.Track(Sender: TObject);
var
Delay: Cardinal;
begin
Delay := GetTickCount - FPrevTick;
if FDragging then
begin
if Delay = 0 then
Delay := 1;
FSpeedX := (ScrollPos.X - FPrevScrollPos.X) / Delay;
FSpeedY := (ScrollPos.Y - FPrevScrollPos.Y) / Delay;
end
else
begin
if (Abs(FSpeedX) < 0.005) and (Abs(FSpeedY) < 0.005) then
FTracker.Enabled := False
else
begin
ScrollPos := Point(FPrevScrollPos.X + Round(Delay * FSpeedX),
FPrevScrollPos.Y + Round(Delay * FSpeedY));
FSpeedX := 0.83 * FSpeedX;
FSpeedY := 0.83 * FSpeedY;
end;
end;
FPrevScrollPos := ScrollPos;
FPrevTick := GetTickCount;
end;
procedure TScrollBox.WMParentNotify(var Message: TWMParentNotify);
begin
inherited;
if Message.Event = WM_LBUTTONDOWN then
begin
FChild := ControlAtPos(Point(Message.XPos, Message.YPos), False, True);
if FChild <> nil then
begin
FPrevActiveControl := ActiveControl;
FOldChildOnMouseMove := TControlAccess(FChild).OnMouseMove;
TControlAccess(FChild).OnMouseMove := ChildMouseMove;
FOldChildOnMouseUp := TControlAccess(FChild).OnMouseUp;
TControlAccess(FChild).OnMouseUp := ChildMouseUp;
end;
end;
end;
end.
注意:当没有启动拖动时(鼠标移动<Mouse.DragThreshold
),被单击子项的所有鼠标和单击事件保持不变。否则只有 Child.OnMouseDown
会触发!
出于测试目的,this answer已合并到上面的代码中。
感谢 @TLama 建议使用 WM_PARENTNOTIFY
。
关于delphi - TScrollbox MouseDown 覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9595166/
当我使用 resharper 时,他总是说 有什么区别? 任何细节都会很好 谢谢大家。 最佳答案 较短的语法已在 C# 2.0 中引入,它只是较长形式的语法糖。 无论你写什么,结果总是一样的。但是,更
我需要在网页中捕获一些数据,然后用户创建 mousedown 事件或在用户按页面元素上的 TAB 键时模拟它。对于 mousedown 我使用标准代码,例如: $('*').on('mousedown
我有一个 html 表格,其中包含拖放列、可调整大小的行以及根据 mousedown、mousemove 和 mouseup 进行更改的可调整大小的列。为了获得更好的性能,我应该让文档在鼠标移动期间不
所以我还没有开始写这些,所以为了清楚起见,我会尽我最大的努力把一些伪代码放在一起——但这里的想法是用户会点击并按住一个“按钮” (最终可能不会成为一个实际的按钮),然后生成一个可移动的 DIV。一旦创
如何在 JQuery 中创建鼠标按下并移动时触发的事件?并且每次 mousedown + mousemove 只触发一次? 最佳答案 更新: 因此,看起来如果您的鼠标不再位于绑定(bind) onmo
我正在使用 NSView 进行拖放操作。 在要拖动的对象(NSView 的子类)中,我实现了 mouseDown: 方法,如下所示: @try { NSPoint location;
我有一个包含 2 个事件的 TPanel: procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shif
我的应用程序一直表现不佳。在删除越来越多的代码后,我设法找到了问题的核心,但这对我来说毫无意义。 一点背景。我的网络编辑器应用程序对击键使用react,例如当按下 Alt 时,调整大小的处理程序将被隐
我希望按钮在单击时更改其颜色(鼠标按下时颜色较深,鼠标松开时原始颜色)并且它可以工作,但仅在第二次单击时有效。这是为什么?我该如何解决这个问题? 按钮 ID 为 1 到 10(按钮 1、按钮 2...
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 3 年前。 有没有办法在动态添加的元素上使用 mouse
我正在尝试向 DIV 添加一个简单的 mousedown 事件监听器。 DIV 有一个子节点,即 IMG。但是,当 mousedown 事件触发时,该事件的 target 和 srcElement 属
嗨,我有这个 HTML 代码 Passengers 并且有这个JS代码 $("Table tr th").mousedown(function (e) { /*mouse
我有一个 mousedown 事件可以更改 Canvas 中对象的图像。但是,在第一次单击期间,除非我添加超时,否则更新功能不会更新图像。此外,我什至尝试 promise 在新图像链接之后等待,然后再
我已经创建了过渡链接,但是当应该使用 onmousedown 事件调用该函数时,我得到了一个未捕获的未定义函数。显然我的功能已定义。我还在学习代码,所以我看不到或不明白它是什么。任何提示将不胜感激。
我正在使用一个名为 circliful 的 jquery 库: https://github.com/pguso/jquery-plugin-circliful 我用它来创建“触觉加载”效果。 在这个
在下面的代码片段中,只有“mousemove”事件有效。 'mousedown' 没有效果,我无法解释为什么会这样。如果我将“mousedown”替换为“click”,它确实有效,但是我想使用 mou
当你使用方法的时候 public boolean mouseDown(Event e, int x, int y) 在Java中,Event对象是干什么的,有什么用?我正在尝试编写一个程序,让某人点击
我正在尝试像这样加载我的导航栏: $.get("nav.html",function(menuData){ $("body").html(menuData); )}; 在“nav.html”中我们
我的问题是,当右键发生 mousedown 事件时,我需要检查是否有 div 如果没有,那么我的 flag 全局 variable 变为 false 但我没有得到该条件。 我的 jQuery 脚本如下
我正在尝试编写一个可移动的对话框,但出现问题。有时当我想通过移动对话框上方的某个位置来移动对话框时,而不是对话框本身,标题文本正在移动,如下所示: 标题文本的 CSS: .arg-dialog-tit
我是一名优秀的程序员,十分优秀!