如何在Delphi的VCL框架中实现跟随鼠标的手电筒光标效果?
在Delphi VCL中实现跟随鼠标的手电筒效果
核心思路
手电筒效果的本质是在窗体上叠加一层半透明遮罩,仅在鼠标位置保留一块透明的圆形区域,以此模拟光线照射的视觉效果。
实现步骤
1. 窗体基础设置
将目标窗体的DoubleBuffered属性设置为True,避免重绘时出现闪烁问题。
2. 变量声明与初始化
在窗体类的私有区域添加变量声明:
private FMousePos: TPoint; // 记录鼠标位置 FLightRadius: Integer; // 手电筒光圈半径
在窗体的OnCreate事件中完成初始化:
procedure TForm1.FormCreate(Sender: TObject); begin FMousePos := Point(0, 0); FLightRadius := 100; // 可根据需求自定义光圈大小 DoubleBuffered := True; end;
3. 鼠标位置跟踪
实现窗体的OnMouseMove事件,实时记录鼠标位置并触发重绘:
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin FMousePos := Point(X, Y); Invalidate; // 通知窗体重绘 end;
4. 绘制遮罩与光圈
在窗体的OnPaint事件中完成核心绘制逻辑:
procedure TForm1.FormPaint(Sender: TObject); var Bmp: TBitmap; Rgn: HRGN; begin Bmp := TBitmap.Create; try Bmp.SetSize(ClientWidth, ClientHeight); // 绘制半透明黑色遮罩(前两位为透明度,CC对应80%不透明) Bmp.Canvas.Brush.Color := $CC000000; Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height)); // 创建圆形区域作为光圈范围 Rgn := CreateEllipticRgn(FMousePos.X - FLightRadius, FMousePos.Y - FLightRadius, FMousePos.X + FLightRadius, FMousePos.Y + FLightRadius); try // 从遮罩中裁剪出圆形透明区域 CombineRgn(Rgn, Rgn, 0, RGN_DIFF); Bmp.Canvas.ClipRgn := Rgn; Bmp.Canvas.Brush.Color := clBlack; Bmp.Canvas.FillRect(Rect(0, 0, Bmp.Width, Bmp.Height)); finally DeleteObject(Rgn); end; // 将处理后的遮罩绘制到窗体 Canvas.Draw(0, 0, Bmp); finally Bmp.Free; end; end;
5. 效果优化
- 若需要柔化光圈边缘,可以使用
GradientFill函数实现渐变遮罩,让光线过渡更自然。 - 如果窗体包含大量控件,可通过
TForm.PaintTo方法先捕获窗体整体内容,再叠加遮罩层,确保所有控件都被覆盖。
内容的提问来源于stack exchange,提问作者Çağatay KAYA
相关产品推荐
相关产品推荐

