По просьбам трудящихся (viewtopic.php?p=16854#p16854).

Принцип использования тот же, что у Tools->Add Scroller.
Выделяем монолитно (singleton) вьюшку, для которой нужна поддержка невидимости. Даём команду AbfTools.AddInvisibiler.

Включение невидимости ведётся через обычный контроловский Guard, свойством disabled.

Выбираем Properties - открывается стандартное окно настройки контрола.
Далее два случая:
1) если обёрнутая вьюшка - не контрол: имеет значение только поле Guard.
2) если обёрнутая вьюшка - контрол: настраиваем все свойства сразу для неё (получается полный синхрон с обёрткой). Т.е. disabled для контрола начинает работать как invisible.

## Код:
```
MODULE AbfTools;

   IMPORT Views, Controls, Stores, Meta, Controllers, Properties, Dialog, Models, Services;

   CONST
      invVersion = 0;

   TYPE
      Invisibiler = POINTER TO RECORD (Controls.Control)
         inner: Views.View
      END;

   PROCEDURE Init (v: Invisibiler);
      VAR prop: Controls.Prop;
   BEGIN
      Stores.Join(v, v.inner);
      IF v.inner IS Controls.Control THEN
         Controls.OpenLink(v, v.inner(Controls.Control).prop)
      ELSE
         NEW(prop);
         Controls.OpenLink(v, prop)
      END
   END Init;

   PROCEDURE (v: Invisibiler) Externalize2 (VAR wr: Stores.Writer);
   BEGIN
      wr.WriteVersion(invVersion);
      Views.WriteView(wr, v.inner)
   END Externalize2;

   PROCEDURE (v: Invisibiler) Internalize2 (VAR rd: Stores.Reader);
      VAR ver: INTEGER;
   BEGIN
      rd.ReadVersion(invVersion, invVersion, ver);
      IF ~rd.cancelled THEN
         ASSERT(ver = invVersion, 100);
         Views.ReadView(rd, v.inner);
      END
   END Internalize2;

   PROCEDURE (v: Invisibiler) CopyFromSimpleView2 (source: Controls.Control);
   BEGIN
      WITH source: Invisibiler DO
         v.inner := Views.CopyOf(source.inner, Views.deep);
         Init(v)
      END
   END CopyFromSimpleView2;

   PROCEDURE GetVis (v: Invisibiler; OUT x: BOOLEAN);
   BEGIN
      x := ~v.disabled
   END GetVis;

   PROCEDURE (v: Invisibiler) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR vis: BOOLEAN;
            w, h: INTEGER;
   BEGIN
      GetVis(v, vis);
      IF vis THEN
         Views.InstallFrame(f, v.inner, 0, 0, 0, TRUE)
      ELSE
         v.context.GetSize(w, h);
         Views.RemoveFrames(f, 0, 0, w, h)
      END
   END Restore;

   PROCEDURE (v: Invisibiler) HandleCtrlMsg2 (f: Views.Frame; VAR msg: Controllers.Message; VAR focus: Views.View);
      VAR vis: BOOLEAN;
   BEGIN
      GetVis(v, vis);
      IF vis THEN focus := v.inner END
   END HandleCtrlMsg2;

   PROCEDURE (v: Invisibiler) HandlePropMsg2 (VAR msg: Properties.Message);
      VAR prop: Properties.Property;
   BEGIN
      WITH msg: Controls.DefaultsPref DO
         msg.disabled := FALSE   
      ELSE
         Views.HandlePropMsg(v.inner, msg)
      END
   END HandlePropMsg2;

   PROCEDURE (v: Invisibiler) Neutralize;
   BEGIN
      v.inner.Neutralize
   END Neutralize;

   PROCEDURE (v: Invisibiler) InitContext (context: Models.Context);
   BEGIN
      v.InitContext^(context);
      v.inner.InitContext(context)
   END InitContext;

   PROCEDURE AddInvisibiler*;
      VAR poll: Controllers.PollOpsMsg; v: Invisibiler; replace: Controllers.ReplaceViewMsg;
   BEGIN
      Controllers.PollOps(poll);
      IF (poll.singleton # NIL) & ~(poll.singleton IS Invisibiler) THEN
         NEW(v); v.inner := poll.singleton; Init(v);
         replace.old := poll.singleton; replace.new := v;
         Controllers.Forward(replace)
      ELSE Dialog.Beep
      END
   END AddInvisibiler;

   PROCEDURE RemoveInvisibiler*;
      VAR poll: Controllers.PollOpsMsg; replace: Controllers.ReplaceViewMsg;
   BEGIN
      Controllers.PollOps(poll);
      IF (poll.singleton # NIL) & (poll.singleton IS Invisibiler) THEN
         replace.old := poll.singleton;
         replace.new := Views.CopyOf(poll.singleton(Invisibiler).inner, Views.shallow);
         Controllers.Forward(replace)
      ELSE Dialog.Beep
      END
   END RemoveInvisibiler;

   PROCEDURE IsInvisibiler* (v: Views.View): BOOLEAN;
   BEGIN
      RETURN v IS Invisibiler
   END IsInvisibiler;

   PROCEDURE InnerView* (v: Views.View): Views.View;
   BEGIN
      ASSERT(v IS Invisibiler, 20);
      RETURN v(Invisibiler).inner
   END InnerView;

END AbfTools.
```
