На этом шаге мы рассмотрим создание окна редактора.
Так же просто, как и окно, показывающее дерево, можно создать окно редактора.
Для настройки и использования редактора существует гибкий 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 Кб).
На следующем шаге мы рассмотрим обработку буфера обмена.