Шаг 85.
Visual Prolog.
Обработка событий

    На этом шаге мы рассмотрим обработку событий.

    Рассмотрим, как VPI-программы обрабатывают события.

События, находящиеся в очереди на обработку

   vpi_ProcessEvents(SendEventsToThisAppBoolean)

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

    MS Windows 3.x не имеет приоритетного планирования. Это означает, что если вызван предикат обработчика событий, то никакие другие приложения или окна не получат событий до окончания работы предиката. А значит, нежелательно иметь очень длинные непрерывные операции, такие как компиляция, генерация отчетов баз данных, вывод больших изображений, сложные вычисления и т. д. Очевидна необходимость какого-либо механизма для хранения событий, передаваемых другим обработчикам событий. Таким механизмом может быть регулярно вызываемый предикат vpi_ProcessEvents внутри длинных операций.

    Например, компилятор Пролога в VDE регулярно вызывает предикат vpi_ProcessEvents для обеспечения компиляции в фоновом режиме, чтобы выполнять другие приложения во время работы компилятора.

    Параметр логического типа SendEventsToThisAppBoolean определяет, должен ли предикат vpi_ProcessEvents вызывать обработку событий из очереди событий приложения (b_True) или только передавать управление другим приложениям (b_False). Во втором случае он вызывает обработку только событий е_Timer и e_Update, находящихся в настоящее время в очереди событий приложения; все остальные события кроме e_Timer и e_Update, будут удалены из очереди событий.

    Вариант предиката vpi_ProcessEvents/0 работает так же, как vpi_ProcessEvents(b_True).

   vpi_ProcessEvents(SendEventsToThisAppBoolean,WaitNewEventsBoolean)

    Причем vpi_ProcessEvents/2 отличается от vpi_ProcessEvents/l только тогда, когда WaitNewEvents=b_true. В этом случае vpi_ProcessEvents/2 приостанавливает приложение, если нет событий в очереди, и ждет до тех пор, пока не придет новое событие, а затем вызывает обработку этого события.

    Предикат vpi_ProcessEvents/2 обычно используется в циклах, где приложение ожидает событий от других приложений.

    Вы должны удостовериться, что сможете завершить длинный процесс, если пользователь выберет команду File | Exit, чтобы закрыть приложение. Перед тем как вызывать предикат vpi_ProcessEvents, необходимо вызвать предикат, который проверяет флаг, определяющий, можно завершить приложение или нет.

Отправка событий

    Пока события происходят в системе управления окнами, код приложения может послать событие одному из его собственных обработчиков событий, используя предикат win_SendEvent, эффект будет таким же, как при вызове обработчика для этого окна. Конечно, можно вызвать обработчик событий непосредственно, если он доступен в данной точке, но во многих ситуациях известен только дескриптор окна, поэтому лучше использовать вызов, основанный на дескрипторе окна. Значение long, которое возвращается предикатом win_SendEvent, является возвращаемым значением (заключительным параметром) предложения обработчика событий для этого события.

   Long=win_SendEvent(Window,Event)

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

   win_SendEvent(ParentWindow,e_Menu(ID,CtrlAltShift))

    Предикат win_SendEvent не завершится до завершения соответствующего предложения обработчика событий. Если это предложение обработчика завершается неуспешно, то win_SendEvent возвратит нуль.

    Иногда нужно поставить событие в очередь, чтобы оно было обработано после завершения текущего события и остальных ждущих обработки событий. Постановку события в очередь выполняет предикат win_PostEvent:

   win_PostEvent(Window,Event)

    Этот предикат завершается сразу после постановки события в очередь.

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




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