Шаг 21.
Visual Prolog.
Создание окна редактора

    На этом шаге мы рассмотрим создание окна редактора.

    Так же просто, как и окно, показывающее дерево, можно создать окно редактора.

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

  1. Создайте новый исходный модуль Edwin.pro.
  2. Создайте новое окно Editor.
  3. Войдите в эксперт окон и диалоговых окон и определите, что код должен быть в модуле Edwin.pro. Выберите стиль кода edit_Create для генерации экспертом кода.
  4. Добавьте пункт Editor Window в меню Task подменю Test. Вставьте код для соз дания окна редактора для этого события.
  5. Попытайтесь запустить приложение: откройте окно редактора и попробуйте редактировать какой-либо текст в этом редакторе.

    Результат работы приложения изображен на рисунке 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 Кб).

    На следующем шаге мы рассмотрим обработку буфера обмена.




Предыдущий шаг Содержание Следующий шаг