> -- worrier писал(а):
> Про использование check box я не понял: как вместо него подставляется нужный текст? Если вас не затруднит - можно подробнее.
В документе я просто вставляю контрол и в его атрибут Label вставляю определённое имя. Потом сканирую документ, и как только сканер натыкается на контрол нужного типа, да и ещё с нужным именем, то контрол удаляется и вместо него подставляется текст.
Вот кусок исходника, который за это отвечает.

## Код:
```
PROCEDURE Insert(IN f: TextMappers.Formatter; t: TextModels.Model; IN label : ARRAY OF CHAR; prop : Properties.StdProp);
VAR
      p1, p2 : INTEGER;
BEGIN
      p1 := f.Pos();
      IF label = 'surname' THEN f.WriteString(surname); END;
      IF label = 'name' THEN f.WriteString(name); END;
      IF label = 'boxname' THEN f.WriteString(boxname); END;
      IF label = 'boxtariff' THEN f.WriteString(boxtariff); END;
      IF label = 'date' THEN f.WriteString(sdate); END;
      IF label = 'passport' THEN f.WriteString(passport); END;
      IF label = 'address' THEN f.WriteString(address); END;
      IF label = 'phone' THEN f.WriteString(phone); END;
      p2 := f.Pos();
      t.Modify(p1, p2, NIL, prop);
END Insert;

PROCEDURE Print*;
VAR 
      loc: Files.Locator; name: Files.Name;
      v: Views.View; t: TextModels.Model; f: TextMappers.Formatter; s: TextMappers.Scanner;
      conv: Converters.Converter; prop: Properties.StdProp;
      c : Controls.Control; label : Dialog.String;
BEGIN
      Dates.GetDate(date);
      Dates.DateToString(date, Dates.long, sdate);
      Dialog.UpdateString(sdate);

      (*открываю заранее подготовленный документ с расставленными метками*)

      loc := Files.dir.This("Guard/Rsrc"); name := "PersAgm";
      v := Views.OldView(loc, name); 
      IF (v # NIL) & (v IS TextViews.View) THEN
         t := v(TextViews.View).ThisModel();
         f.ConnectTo(t);

      (*устанавливаю опции сканирования*)

         s.ConnectTo(t); s.SetPos(0); s.SetOpts({TextMappers.returnViews});
         WHILE ~s.rider.eot DO
            s.Scan;

      (*если наткнулся на контрол с заполненным атрибутом Label*)

            IF (s.view # NIL) & (s.view IS Controls.Control) THEN
               label := s.view(Controls.Control).prop.label;
               IF  label # '' THEN
                  prop := t.Prop(s.Pos()-2, s.Pos()-1)(Properties.StdProp);
                  t.Delete(s.Pos()-2, s.Pos()-1);
                  f.SetPos(s.Pos()-2);

      (*на место удалённого контрола вставляю свой текст*)

                  Insert(f, t, label, prop);
                  s.view := NIL;
               END;
            END;
         END;
         Views.OpenAux(v, "Договор");
      END;
END Print;
```


> -- worrier писал(а):
> Посмотрев документацию ObxButtons и ObxFldCtrls сделал вывод, что обрабатывать в контроле нужно сообщение Properties.SetMsg и в его обработчике менять нужные свойства, верно ли это? Если верно, то как мне заполнить запись Property из основного модуля и передать моему контролу? Т.е. хотелось бы простой пример "своего контрола", просто меняющего свой label.

Ну, я поступил так. Скопировал себе стандартный модуль ObxButtons, в котором уже реализованы все процедуры обратной связи, и немного модифицировал процедуру Restore, отвечающую за отрисовку контрола (поставил масштабирование и пр.). Вот как это выглядело:

## Код:
```
(*Ivan: lookup variable by its name*)
   PROCEDURE (v: View) GetLinkValue(), NEW;
   VAR 
         item : Meta.Item; ok : BOOLEAN;
         item0 : RECORD (Meta.Value)
            value :  Dialog.String;   
         END;
   BEGIN
      Meta.LookupPath(v.link, item);
      IF item.obj = Meta.varObj THEN
         item.GetVal(item0, ok);
         IF ok THEN IF item0.value # '' THEN v.label := item0.value; END; END;
      END
   END GetLinkValue;

   PROCEDURE (v: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
      VAR w, h, x, y, asc, dsc, fw: INTEGER;
   BEGIN   (* restore view at least in rectangle (l, t, r, b) *)
      v.GetLinkValue(); (*Ivan: get value of text link*)
      v.context.GetSize(w, h);   (* the container context maintains the view's size *)
      w := v.font.StringWidth(v.label);
      v.context.SetSize(w,h);
      x := 0;
      v.font.GetBounds(asc, dsc, fw);
      y := h DIV 2 + (asc + dsc) DIV 3;
      f.DrawString(x, y, v.color, v.label, v.font) 
   END Restore;
```


Размещение поля делал так (стандартный способ): GuardControls.Deposit; StdCmds.PasteView,
затем в размещённом поле вручную прописывал интерактор и всё работало. Но была проблема - если интерактор не загружен в память, то попытка к нему обратиться вызывала тряп. Пока я думал, как это разрешить, обнаружилось, что поскольку поле рассматривается как один символ, то текст плохо форматируется. Пришлось сделать по-другому.

> -- worrier писал(а):
> И, как я понял, взаимодействовать из основного модуля с формой и контролами возможно только посредством интеракторов?

Да, это простая и стандартная схема.