На этом шаге мы рассмотрим создание окна редактора.
Так же просто, как и окно, показывающее дерево, можно создать окно редактора.
Для настройки и использования редактора существует гибкий API (Application Programming Interface). Помимо специальных функций, редактор поддерживает закрашивание лексемы и гипертекстовые поля. Теперь поработаем с окном редактора. Выполните следующие шаги:
Результат работы приложения изображен на рисунке 1:

Рис.1. Результат работы приложения
Если посмотрим на сгенерированный код в модуле Edwin.pro, то увидим, что вызов создания окна редактора имеет задаваемый по умолчанию набор значений для различных аргументов.
win_editor_Create(_Parent):-
ifdef use_editor
Text="",
Font=font_Create(ff_Fixed,[],10),
Readonly=b_false,
Indent=b_true,
InitPos=1,
edit_Create(win_editor_WinType,win_editor_RCT,win_editor_Title,
win_editor_Menu,_Parent,win_editor_Flags,Font, Readonly,
Indent,Text,InitPos,win_editor_eh),
enddef
true.
Вы можете легко изменить этот код, например, чтобы загрузить определенный текст в редактор:
file_str("C:\\TEMP\\TST\\Myproj.con",Text)
Далее попытаемся добавить несколько возможностей окну редактора.
Чтобы проиллюстрировать, как делать выборку и находить часть текста в редакторе, организуем такую возможность: при двойном щелчке на слове (лексеме) пусть выдается поле примечания с этим словом.
Для этого необходимо использовать три предиката из редактора. Предикат edit_SelectWord высвечивает выбранную лексему, edit_GetSelection находит начальную и конечную позиции текущей выборки и edit_GetText возвращает выбранный в редакторе текст.
in editor_eh(_Win,e_MouseDbl(_PNT,_ShiftCtlAlt,_Button),0):-!,
WordSelected=edit_SelectWord(_Win),
WordSelected=b_true,
edit_GetSelection(_Win,Pos1,Pos2),
Text=edit_GetText(_Win),
NoOfBytes=Pos2-Pos1,
substring(Text,Pos1,NoOfBytes,Substring),
format(Msg,"Got the token: >%<",Substring),
dlg_Note(Msg)
Результат работы приложения изображен на рисунке 2:

Рис.2. Результат работы приложения
Вставить текст в редактор, вызывая предикаты, очень просто. Предикат edit_PasteStr может вставлять строку в любую позицию в тексте (эта позиция начинается с 1).
В качестве примера мы можем добавить новую функцию, которая состоит в том, что, как только вы напечатаете начало комментария /*, автоматически будет вставлен конец комментария */. Чтобы сделать это, мы будем следить за печатаемыми символами. Когда пользователь нажимает клавишу, активному окну посылается событие e_char. Очень просто добавить пару предложений, которые отслеживают символы / и *. Как только замечен символ /, устанавливается флажок для регистрации этого факта, и если следом идет символ *, тогда будет вставлена строка */, в противном случае флажок будет сброшен. Используем предикат edit_GetPos, чтобы определить позицию курсора в редакторе. Наконец, для удобства пользователя мы выделяем строку, которая вставлена таким образом, что если пользователь не хочет ее вставлять, ему всего лишь нужно напечатать любой символ, и строка исчезнет.
win_editor_eh(_Win,e_Char ('/',_),0):-!,
not(commentflag(_Win)),
assert(commentflag(_Win)),
fail.
win_editor_eh(_Win,e_Char ('*',_),0):-!,
retract(commentflag(_Win)),
Pos=edit_GetPos(_Win),
edit_PasteStr(_Win,Pos, "* */"),
Pos1=Pos+1,
Pos2=Pos1+4,
edit_SetSelection(_Win,Pos1,Pos2),
!.
win_editor_eh(_Win,e_Char(_,_),0):-!,
retract(commentflag(_Win)),
fail.
Два предыдущих предложения, которые просто управляют состоянием флажка, тоже завершаются неуспехом; таким образом, редактор сам может выполнять стандартную обработку таких сообщений (вставить символы, обновить экран и т. д.) так, как если бы этих предложений не было.
Чтобы определить базу данных, используемую выше, вставьте следующий код в начале файла:
facts-editor
commentflag(window)
Результат работы приложения изображен на рисунке 3:

Рис.3. Результат работы приложения
Текст в редакторе может быть сохранен на диске при помощи последовательных вызовов предикатов edit_GetText и file_str.
Если в окне редактора мы хотим использовать команду File | Save, чтобы вызвать сохранение текста, то для этого нужно обратиться к диалоговому окну настройки атрибутов для окна редактора и отметить, что окно редактора должно иметь меню Task окна.

Рис.4. Задание меню Task окна
Этот пункт меню не должен быть разрешенным, когда другие окна имеют фокус, поэтому сделаем его разрешенным в предложении, обрабатывающем e_GetFocus-событие, и, соответственно, неразрешенным в предложении, обрабатывающем e_LoseFocus-coбытиe:
win_editor_eh(_Win,e_LoseFocus,0):-!,
menu_Enable(_Win,id_file_save,b_false),
!.
win_editor_eh(_Win,e_GetFocus,0):-!,
menu_Enable(_Win,id_file_save,b_true),
!.

Рис.5. Активация/деактивация пункта меню
Должно быть добавлено следующее предложение, обрабатывающее событие e_Menu:
win_editor_eh(_Win, e_Menu (id_file_save,_ShiftCtlAlt),0):-!,
Msg="Save As File",
Flags=[dlgfn_Save],
SaveFileName=dlg_GetFileName("*.txt",
["*.txt","*.txt","*.*","*.*"],
Msg, Flags,"", _OutListFiles),
Text=edit_GetText(_Win),
file_str(SaveFileName,Text),
win_SetText(_Win,SaveFileName),
!.
В исходном коде файла Edwin.pro вы можете проверить, как используется событие e_Initmenu для активизации функциональности пунктов меню из подменю Edit.
Созданное приложение можно взять здесь (442,4 Кб).
На следующем шаге мы рассмотрим обработку буфера обмена.