Шаг 10.
Visual Prolog.
Проверка того, что окно реагирует на события

    На этом шаге мы рассмотрим проверку того, что окно реагирует на события.

    Поместите курсор на начало предиката обработчика события в модуле Cross и наберите новое предложение (которое должно быть первым предложением обработчика событий), которое распечатает полученное событие и вызовет предикат fail (будьте внимательны не добавляйте никаких отсечений !). Это не будет влиять на логику окна Cross, но в окне Messages (нашего приложения Myproj) вы можете теперь просматривать все события, которые посылаются обработчику событий окна Cross (рис. 1).


Рис.1. Изучение событий

   win_cross_eh(Win,Event,0):-   %    <-- Введите эти три строки
     write(Win,"  ",Event),nl,
     fail. 
   %BEGIN Cross, e_Create
      win_cross_eh(_Win,e_Create(_),0):-!.

    Попытайтесь запустить приложение. Выполните различные действия, например создание, движение и изменение размеров окна, набор на клавиатуре, работу мыши и закрытие окна.

    Теперь вы можете наблюдать, какие события посылаются окну в различных обстоятельствах. Можно добавить код (предложения обработчика событий win_cross_eh), который реагирует выборочно на каждое из этих событий.

    Сейчас мы изучим основы рисования в окне. Приложение всегда должно быть подготовлено к тому, чтобы перерисовать окно. Если окно было закрыто и затем выдвинуто на передний план, содержимое должно быть повторно перерисовано.

    Всякий раз, когда окно должно быть перерисовано, обработчик событий для окна получит событие e_Update. Поэтому нам нужно добавить код, чтобы выполнить это изменение.

    В качестве примера мы будем рисовать диагонали окна. Чтобы сделать это, обратимся к эксперту окон и диалоговых окон и добавим предложение для события e_Update (рис. 2).


Рис.2. Добавление предложения для управления событием e_Update

    Чтобы добавить вызов предиката VPI, вам следует воспользоваться средствами вставки в редакторе. Можно использовать меню вставки (и всплывающее меню мыши), но существует также комбинация клавиш <Shift>+<Ctrl>+<V>, которая немедленно вызывает список VPI-предикатов.

    Чтобы нарисовать диагонали, сначала мы должны найти координаты нижнего угла. Для этого находим клиентский прямоугольник запросом к win_GetClientRect, этот прямоугольник содержит в двух последних параметрах ширину и высоту окна, так что код для выполнения этих действий выглядит следующим образом.

   win_cross_eh(_Win,e_Update (_),0):-!,
      RCT=win_GetClientRect(_Win),             %1 Напечатать эти 4 линии здесь
      RCT=rct(_,_,R,B) ,                       %2 Координаты прямоугольника
      draw_Line(_Win,pnt(0,0),pnt(R,B)),       %3 относительно окна
      draw_Line(_Win,pnt(0,B),pnt(R,0)),       %4 !.

    Когда вы запустите свое приложение и выберете команду пункта меню Test | CrossWin, на экране можно будет увидеть окно, изображенное на рис. 3.


Рис.3. Внешний вид окна Cross

    Созданное приложение можно взять здесь (373,6 Кб)

    Вы увидите, что окно ведет себя почти правильно, что вы можете создавать несколько экземпляров окна, перемещать его, перекрывать другим окном и делать снова видимым. Однако, если вы будете изменять размеры окна, обнаружится проблема. Окно перекрашивается неправильно. Вы увидите, что только заново открываемая часть окна перекрашена.

    Это происходит из-за того, что базовая система GUI пытается перекрашивать по минимуму и для этого устанавливает область отсечения так, чтобы модификации затрагивали только новую часть окна. Это правильное поведение для многих окон, таких как редакторы, изображения и т. д. Однако в нашем случае этого недостаточно: когда изменяется размер окна, нам нужно перерисовать все окно. Один из способов - вызвать предикат win_Invalidate в событии e_Size.

    Используйте редактор окон, нажмите кнопку Edit Clause для события e_Size (там есть уже некоторый код, заданный по умолчанию). После того как вы вставили вызов win_Invalidate, ваш код для события e_Size должен выглядеть так:

   win_cross_eh(_Win,e_Size(_Width,_Height),0):-!,
      win_Invalidate(_Win), 
   ifdef use_tbar
      toolbar_Resize(_Win),
   enddef 
      !.

    Если вы снова запустите приложение, вы заметите, что теперь окно работает как нужно.

    Созданное приложение можно взять здесь (373,8 Кб)

Несколько операций рисования

    Теперь, раз уж мы занимаемся рисованием, рассмотрим еще пару дополнительных графических предикатов. Добавим такой код к предложению обработчика для события e_Update:

   draw_Text(_Win,55,20,"This is a text in the Cross Window"),
   draw_Ellipse(_Win,rct (30, 50, 60,100) ),
   draw_PolyGon(_Win,[pnt(130,130),pnt(180,130),pnt(145,100),
                  pnt(150,150),pnt(170,110)]),
   draw_Rect(_Win,rct(250,50,300,100)),

    Созданное приложение можно взять здесь (375,4 Кб)

    Имеются и другие графические примитивы. Можно установить шрифт, цвет, размер цвет, тип линии, образец заполнения и т. д. (рис. 4).


Рис.4. Новые рисунки в окне Cross

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




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