OberonCore
https://forum.oberoncore.ru/

Нестандартный Caption
https://forum.oberoncore.ru/viewtopic.php?f=24&t=501
Страница 1 из 1

Автор:  Иван Кузьмицкий [ Вторник, 05 Июнь, 2007 16:40 ]
Заголовок сообщения:  Нестандартный Caption

Всем привет!

Занялся генерацией отчётов с использованием составных документов. Очень, очень обрадовал тот факт, что прямо в отчёт можно "втыкать" контролы, которые затем заполняются из интеракторов (эдакий сам себе report builder)!
Но вот незадача — контрол Caption отчего-то отказался читать прикреплённого к нему интерактора.
Я так и не понял, в чём дело и сделал свой Caption, на основе ObxButtons.
Но, может быть, это "велосипед", и с Caption можно управиться проще? "Охранник" тут не подойдёт, ибо в отчёте может быть куча контролов — гораздо проще кинуть контрол в документ, связать его с интерактором и забыть.

Автор:  Илья Ермаков [ Вторник, 05 Июнь, 2007 22:39 ]
Заголовок сообщения: 

Иван, прикол в том, что Caption не связывается с интерактором вообще. Т.е. поле Link иногда и правда заполняется, но привязывается к тому же интерактору, что и тот Edit, к которому относится Caption (чтобы если интерактор вдруг не доступен, надпись стала серой).

Автор:  Иван Кузьмицкий [ Среда, 06 Июнь, 2007 17:53 ]
Заголовок сообщения: 

Илья Ермаков писал(а):
Иван, прикол в том, что Caption не связывается с интерактором вообще. Т.е. поле Link иногда и правда заполняется, но привязывается к тому же интерактору, что и тот Edit, к которому относится Caption (чтобы если интерактор вдруг не доступен, надпись стала серой).


А-а, точно, Caption изначально предназначен для совместного использования с Edit, понятно!
Значит, я иду правильным путём :) Потихоньку в контрол добавляю новые возможности, типа автоматического масштабирования под содержимое, так что это уже совсем не Caption, а что-то вроде ReportString :))

Автор:  worrier [ Воскресенье, 18 Ноябрь, 2007 19:25 ]
Заголовок сообщения:  Re: Нестандартный Caption

Столкнулся с этой же проблемой.
Иван Кузьмицкий, надо полагать у вас есть уже некоторые решения?
Так как следует поступить: собрать несколько нароботок по этому вопросу у занимающихся людей (им объединиться), или каждый пишет сам (т.е. мне, например, придется также писать "свой caption", что для меня проблемно)?

Автор:  Иван Кузьмицкий [ Воскресенье, 18 Ноябрь, 2007 21:51 ]
Заголовок сообщения:  Re: Нестандартный Caption

worrier писал(а):
Столкнулся с этой же проблемой.
Иван Кузьмицкий, надо полагать у вас есть уже некоторые решения?
Так как следует поступить: собрать несколько нароботок по этому вопросу у занимающихся людей (им объединиться), или каждый пишет сам (т.е. мне, например, придется также писать "свой caption", что для меня проблемно)?


Давайте обсудим проблему. Я всё-таки заменил Caption на метку (в качестве метки используется контрол CheckBox с надписью), вместо которой подставляется нужный текст. Это даёт возможность нормально форматировать текст.

Автор:  worrier [ Воскресенье, 18 Ноябрь, 2007 23:21 ]
Заголовок сообщения:  Re: Нестандартный Caption

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

Автор:  Иван Кузьмицкий [ Понедельник, 19 Ноябрь, 2007 07:37 ]
Заголовок сообщения:  Re: Нестандартный Caption

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


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

Автор:  worrier [ Понедельник, 19 Ноябрь, 2007 12:21 ]
Заголовок сообщения:  Re: Нестандартный Caption

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


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


Т.е. единственный способ получить значение интерактора - использовать что-то вроде v.GetLinkValue(); (*Ivan: get value of text link*)?
Как вы используете check box теперь понял. Спасибо. Хорошая идея заменить метки на текст.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/