Vladimir Ulchenko wrote:
> wrote: > > >manually adjusting stack pointer and exception frame. I don't see how > >this could be achieved in plain Delphi. > > that was my impression as well.
FWIW, I had to read earlier in the thread to see what the expansion was supposed to be in order to understand what was meant:
> > Allen's blog post describing Using but still having troubles figuring > out what analog of mine one-liner DISABLE_ENABLE_CONTROLS(SomeDataset) > will look like? right now I have to type the following > SomeDataSet.DisableControls(); > try > .... > finally > SomeDataset.EnableControls(); > end;
But on the other hand, it is easy enough to do in Delphi, after the definition of some utilities. The only "gotcha" is that Delphi scopes are flat, they cannot be nested like C++ with extra {}. But if you're going to waste extra lines on the '{' and '}', then the anonymous method technique will work just as well.
uses SysUtils;
type TScopeNotifier = class(TInterfacedObject) private FProc: TProc; public constructor Create(const AProc: TProc); destructor Destroy; override; end;
constructor TScopeNotifier.Create(const AProc: TProc); begin FProc := AProc; end;
destructor TScopeNotifier.Destroy; begin if Assigned(FProc) then FProc; inherited; end;
// Utility function to guarantee conversion to interface function MakeScopeNotifier(const AProc: TProc): IInterface; begin Result := TScopeNotifier.Create(AProc); end;
function EnableDisableControls(const AControl: string): IInterface; begin Writeln('Disable controls on ', AControl); Result := MakeScopeNotifier(procedure begin Writeln('Enable controls on ', AControl); end); end;
procedure P; begin EnableDisableControls('Foo'); Writeln('Controls are disabled now'); end;
begin P; end.
Output:
Disable controls on Foo Controls are disabled now Enable controls on Foo
It is equivalent to the try / finally etc. owing to the mechanism behind reference counting.
-- Barry
-- http://barrkel.blogspot.com/