Delphi中如何完全隐藏组件鼠标光标?相关疑问解析
问题背景
我原本以为FMX组件的Cursor属性里会有crNone选项,但在对象检视器的Cursor列表里找不到,手动输入还提示“'crNone' is not a valid integer value”。
查看System.UITypes的代码时,确实能找到crNone的常量定义:
const crDefault = TCursor(0); crNone = TCursor(-1); crArrow = TCursor(-2); crCross = TCursor(-3); crIBeam = TCursor(-4); crSize = TCursor(-22); crSizeNESW = TCursor(-6); crSizeNS = TCursor(-7); crSizeNWSE = TCursor(-8); crSizeWE = TCursor(-9); crUpArrow = TCursor(-10); crHourGlass = TCursor(-11); crDrag = TCursor(-12); crNoDrop = TCursor(-13); crHSplit = TCursor(-14); crVSplit = TCursor(-15); crMultiDrag = TCursor(-16); crSQLWait = TCursor(-17); crNo = TCursor(-18); crAppStart = TCursor(-19); crHelp = TCursor(-20); crHandPoint = TCursor(-21); crSizeAll = TCursor(-22);
但用代码Panel1.Cursor := crNone;设置后,光标没隐藏,反而变成带问号的默认光标。
疑问解答
1. 为什么crNone未出现在对象检视器中?
对象检视器的Cursor选项列表是FMX框架筛选后的可用光标集合,crNone并非实际可渲染的光标类型,只是一个兼容性保留的标记值,因此没有被加入可视化编辑的选项。同时,对象检视器对Cursor属性的输入校验只认可对应实际光标的预定义值,crNone不在校验范围内,所以手动输入会触发无效值提示。
2. crNone实际是什么,为何无法隐藏光标?
crNone是从VCL框架继承过来的常量,在VCL中它确实用于隐藏光标,但FMX框架并未实现该常量的隐藏逻辑,仅保留定义以兼容旧代码。当你设置crNone时,FMX找不到对应的光标资源,就会 fallback 到系统的“未知光标”(带问号的箭头),自然无法实现隐藏效果。
3. 若crNone不可用,如何完全隐藏组件上的鼠标光标?
有两种可靠方案可以实现FMX组件的光标隐藏:
方案一:使用透明自定义光标
制作一个完全透明的光标文件(.cur格式,尺寸建议与系统光标一致,如32x32),通过LoadCursorFromFile加载后赋值给组件:var TransparentCursor: TCursor; begin TransparentCursor := LoadCursorFromFile('你的透明光标路径.cur'); Panel1.Cursor := TransparentCursor; // 程序退出时记得释放资源 // DestroyCursor(TransparentCursor); end;方案二:Windows平台拦截鼠标消息
针对Windows平台,可以通过继承组件并重写消息处理,拦截WM_SETCURSOR消息来阻止光标绘制:type TPanelEx = class(TPanel) protected procedure WndProc(var Message: TMessage); override; end; procedure TPanelEx.WndProc(var Message: TMessage); begin if Message.Msg = WM_SETCURSOR then begin Message.Result := 1; // 告诉系统已处理,无需绘制光标 Exit; end; inherited; end;这种方式无需额外资源,仅适用于Windows平台的FMX应用。
内容的提问来源于stack exchange,提问作者Shaun Roselt

