【发布时间】:2019-11-11 11:32:18
【问题描述】:
谁能解释一下 Delphi FMX 10.3.1 中的游标是如何工作的?我有一个冗长的操作,我希望应用程序的光标显示为 动作执行时的 crHourglass。在下面的代码中,我介绍了 3 个用于将光标设置为 crHourglass 的选项。
procedure TFormMain.ActionFindExactMatchesExecute(Sender: TObject);
const
CCursorOption= 2;
var
IterationContextHits: TIterationContextHits;
begin
PanelResults.SendToBack;
PanelProgress.BringToFront;
case CCursorOption of
0: Self.Cursor:= crHourglass;
1: ButtonFindExactMatches.Cursor:= crHourglass;
2: CursorManager.SetCursor(crHourglass);
end;
{Create TIterationContextHits object to hold progress variables:}
IterationContextHits:= TIterationContextHits.Create;
try
{Lengthy code that searches multiple files for string matches}
{Report result of operation:}
ShowMessage('Number of matches found: ' + IntToStr(FHitCount));
{Update GUI:}
DataToControls;
PanelResults.BringToFront;
finally
IterationContextHits.Free;
case CCursorOption of
0: Self.Cursor:= crDefault;
1: ButtonFindExactMatches.Cursor:= crDefault;
2: CursorManager.RestorePrevCursor;
end;
end;
end;
在第一个选项中,我将 MainForm 的 Cursor 属性设置为 crHourGlass,期望在执行期间 应用程序将显示 InheritedCursor 属性,该属性应搜索组件 z 顺序堆栈的所有 回到光标值不是 crDefault 的第一个组件的主窗体。但这不起作用。
在第二个选项中,我设置了链接到操作的按钮的光标属性。如果单击按钮以启动操作, 光标更改有效。但如果该操作是从主菜单项启动的,则不会。
在第三个选项中,我使用我编写的类 TCursorManager 的对象来包装依赖于平台的服务 IFMXCursorService。 这主要是有效的,但并非总是如此。代码如下:
TCursorRecord= record
FCursor: TCursor;
FStartTime: integer;
end;
TCursorRecordArray= array of TCursorRecord;
TCursorManager= class
private
FCursorService: IFMXCursorService;
FCursorRecordStack: TCursorRecordArray;
FCursorRecordCount: integer;
protected
function GetCursorTickCount: integer;
public
constructor Create;
destructor Destroy; override;
function GetCursor: TCursor;
{Returns currently set cursor}
procedure SetCursor(Cursor: TCursor);
{Sets new cursor}
function RestorePrevCursor: TCursor;
{Restores cursor previously set using this object}
property Cursor: TCursor read GetCursor write SetCursor;
property CursorTickCount: integer read GetCursorTickCount;
end;
implementation
constructor TCursorManager.Create;
var
CurrCursorRecord: TCursorRecord;
begin
{Create platform-dependent cursor service:}
if TPlatformServices.Current.SupportsPlatformService(IFMXCursorService) then
FCursorService:= TPlatformServices.Current.GetPlatformService(IFMXCursorService)
as IFMXCursorService;
{Create current cursor record:}
CurrCursorRecord.FCursor:= FCursorService.GetCursor;
CurrCursorRecord.FStartTime:= GetTickCount;
{Put current cursor record onto CursorRecordStack:}
SetLength(FCursorRecordStack, 8);
FCursorRecordCount:= 1;
FCursorRecordStack[0]:= CurrCursorRecord;
end;
function TCursorManager.RestorePrevCursor: TCursor;
var
PrevCursorRecord: TCursorRecord;
begin
if Assigned(FCursorService) then
begin
if FCursorRecordCount>0 then
begin
{Remove current cursor record from stack:}
FCursorRecordCount:= FCursorRecordCount - 1;
PrevCursorRecord:= FCursorRecordStack[FCursorRecordCount-1];
{Reduce size of stack array if possible:}
if FCursorRecordCount mod 8 = 0 then
SetLength(FCursorRecordStack, FCursorRecordCount);
{Update start time of new curr cursor:}
PrevCursorRecord.FStartTime:= GetTickCount;
{Set previous cursor in system:}
FCursorService.SetCursor(PrevCursorRecord.FCursor);
{Return prev cursor:}
Result:= PrevCursorRecord.FCursor;
end;
end;
end;
procedure TCursorManager.SetCursor(Cursor: TCursor);
var
NewCursorRecord: TCursorRecord;
begin
if Assigned(FCursorService) then
begin
{Set up new CursorRecord:}
NewCursorRecord.FCursor:= Cursor;
NewCursorRecord.FStartTime:= GetTickCount;
{Add new cursor record to stack:}
if FCursorRecordCount= Length(FCursorRecordStack) then
SetLength(FCursorRecordStack, FCursorRecordCount + 8);
Inc(FCursorRecordCount);
FCursorRecordStack[FCursorRecordCount-1]:= NewCursorRecord;
{Call system procedure to set cursor:}
FCursorService.SetCursor(Cursor);
end;
end;
实现我想要实现的目标的最简单方法是什么?
【问题讨论】:
标签: user-interface delphi firemonkey