<p>Am 20.09.2013 16:48 schrieb "Graeme Geldenhuys" <<a href="mailto:graeme@geldenhuys.co.uk">graeme@geldenhuys.co.uk</a>>:<br>
><br>
> On 2013-09-20 15:03, Antonio Fortuny wrote:<br>
> > *Screen.*Cursor := crHourGlass;<br>
> > try<br>
> > ...<br>
> > finally<br>
> > *Screen.*Cursor := crDefault;<br>
> > end;<br>
><br>
><br>
> Another trick - slightly better that yours [I think] - is to use<br>
> interfaces instead. That way you can nest cursor changes, and know the<br>
> interfaces will unwind the correct previous cursor for you, be it<br>
> clHourGlass, clSQLWait, clDefault etc.<br>
><br>
><br>
><br>
> ----8<-------------8<-------------8<-------------8<-------------8<----<br>
> unit CodeToolbox;<br>
><br>
> interface<br>
><br>
> function tiAutoCursor(ACursor: TCursor = crHourglass): IUnknown;<br>
> function tiAutoWaitCursor: IUnknown;<br>
><br>
><br>
> implementation<br>
><br>
> type<br>
><br>
> TtiAutoCursor = class(TInterfacedObject)<br>
> private<br>
> public<br>
> constructor Create(ANewCursor: TCursor);<br>
> destructor Destroy; override;<br>
> end;<br>
><br>
> var<br>
> uCursorStack: TList;<br>
><br>
> function tiCursorStack: TList;<br>
> begin<br>
> if not Assigned(uCursorStack) then<br>
> uCursorStack := TList.Create;<br>
> Result := uCursorStack;<br>
> end;<br>
><br>
> constructor TtiAutoCursor.Create(ANewCursor: TCursor);<br>
> begin<br>
> inherited Create;<br>
> // push<br>
> tiCursorStack.Add(@(Screen.Cursor));<br>
> Screen.Cursor := ANewCursor;<br>
> end;<br>
><br>
> destructor TtiAutoCursor.Destroy;<br>
> begin<br>
> // pop<br>
> Screen.Cursor := TCursor(tiCursorStack.Last);<br>
> tiCursorStack.Delete(uCursorStack.Count-1);<br>
> inherited;<br>
> end;<br>
><br>
> function tiAutoCursor(ACursor: TCursor = crHourglass): IUnknown;<br>
> begin<br>
> if GetCurrentThreadId = MainThreadId then<br>
> Result := TtiAutoCursor.Create(ACursor);<br>
> end;<br>
><br>
> function tiAutoWaitCursor: IUnknown;<br>
> begin<br>
> if GetCurrentThreadId = MainThreadId then<br>
> Result := TtiAutoCursor.Create(crHourglass)<br>
> else<br>
> Result := nil;<br>
> end;<br>
><br>
><br>
> initialization<br>
><br>
> finalization<br>
> FreeAndNil(uCursorStack);<br>
><br>
> ----8<-------------8<-------------8<-------------8<-------------8<----<br>
><br>
><br>
> You can now use the above code as follows.<br>
><br>
><br>
> procedure Foo;<br>
> var<br>
> ms: IUnknown; // FPC requires this, Delphi doesn't.<br>
> begin<br>
> ms := tiAutoCursor;<br>
> // do something long<br>
><br>
> // Note: No need to reset the cursor. The Interface will do<br>
> // that automatically when it goes out of scope.<br>
> end;</p>
<p>Weren't you the one who asked some years ago why FPC behaves differently on that case? Because the time when an interface's reference count is decreased is an implementation detail...</p>
<p>Regards,<br>
Sven</p>