如何在Delphi FMX中实现始终指向指定按钮的手型光标效果?
在Delphi FMX中实现始终指向特定按钮的自定义光标效果
FMX没有内置功能直接实现这种「始终指向特定元素」的自定义光标,需要通过隐藏系统光标+自定义可视化组件模拟光标+实时计算旋转角度来实现,以下是具体方案:
核心思路
- 隐藏系统默认光标,用
TImage/TSVGImage组件绘制自定义手型光标 - 监听鼠标移动事件,实时更新自定义光标的位置
- 通过三角函数计算光标中心到目标按钮中心的角度,让光标始终指向按钮
- 处理鼠标进入/离开窗体的显示/隐藏逻辑
具体实现步骤
1. 准备资源
- 将参考示例中的手型SVG转换成FMX支持的图像格式(如PNG),或直接用
TSVGImage组件加载SVG文件 - 在窗体上添加一个
TImage(命名为CustomCursorImg)并加载光标图像;添加一个目标TButton(命名为TargetBtn)
2. 初始化设置
procedure TForm1.FormCreate(Sender: TObject); begin // 隐藏系统光标 Screen.Cursor := crNone; // 配置自定义光标:置于最上层,初始隐藏,允许事件穿透 CustomCursorImg.BringToFront; CustomCursorImg.Visible := False; CustomCursorImg.HitTest := False; // 锚点值需根据你的光标图像调整,确保旋转中心在指尖位置 CustomCursorImg.AnchorPoint := TPointF.Create(0.5, 0.8); end;
3. 鼠标事件处理
显示/隐藏光标
procedure TForm1.FormMouseEnter(Sender: TObject); begin CustomCursorImg.Visible := True; end; procedure TForm1.FormMouseLeave(Sender: TObject); begin CustomCursorImg.Visible := False; end;
实时更新位置与旋转角度
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); var CursorCenter, TargetCenter: TPointF; begin // 更新光标位置为当前鼠标坐标 CustomCursorImg.Position.X := X; CustomCursorImg.Position.Y := Y; // 计算光标中心与按钮中心的坐标(相对于窗体Client区) CursorCenter := TPointF.Create(X, Y); TargetCenter := TPointF.Create( TargetBtn.Position.X + TargetBtn.Width / 2, TargetBtn.Position.Y + TargetBtn.Height / 2 ); // 应用计算好的旋转角度 CustomCursorImg.RotationAngle := CalculateRotationAngle(CursorCenter, TargetCenter); end;
4. 角度计算函数
function TForm1.CalculateRotationAngle(const CursorCenter, TargetCenter: TPointF): Single; var DeltaX, DeltaY: Single; Radians: Double; begin // 计算光标到按钮的向量差 DeltaX := TargetCenter.X - CursorCenter.X; DeltaY := TargetCenter.Y - CursorCenter.Y; // 将弧度转换为角度(FMX旋转顺时针为正,需调整方向) Radians := ArcTan2(DeltaY, DeltaX); Result := Radians * 180 / Pi; // 根据光标图像初始朝向调整偏移值(参考示例中加了20度,按需修改) Result := Result + 20; end;
关键注意事项
- 锚点设置:必须将
AnchorPoint设置在光标指尖位置,否则旋转时会偏离指向目标 - 角度偏移:不同光标图像的初始朝向不同,需调整
CalculateRotationAngle中的偏移值,确保指向正确 - 事件穿透:设置
CustomCursorImg.HitTest := False,避免光标拦截下层按钮的点击事件 - 跨平台适配:代码支持Windows、macOS、移动平台,部分平台可能需要调整光标隐藏逻辑(如iOS)
内容的提问来源于stack exchange,提问作者Martin Kakhuis
相关产品推荐
相关产品推荐

