<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>