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