Шаг 87.
Visual Prolog.
Меню

    На этом шаге мы рассмотрим меню.

Редактор меню VDE

    Самый простой способ выполнения различных команд состоит в том, чтобы организовать такие команды в виде пунктов меню. Эту задачу выполняет редактор меню VDЕ. Каждому пункту меню присваивается идентификатор ресурса. Ваше приложение может быть сделано более понятным, если присваивать каждому идентификатору ресурса имя, связанное с выполняемым действием.

    Меню связываются с окнами во время создания окна. Параметр меню в предикате win_create определяет, что меню расположено в файле ресурсов или что оно динамически формируется из структуры языка Пролог.

    При использовании режима MDI все меню будут появляться в окне Task. Меню автоматически изменяется при модификации активного окна.

    Для того чтобы каждое окно имело свое собственное меню, нужно сбросить флаг MDI в эксперте приложений. Родительским окном должно быть окно Screen.

    VPI имеет возможность создавать собственные меню. Это средство не является переносимым на все платформы. Обратите внимание, что редактор меню в VDE поддерживает только текстовые меню.

Домен MENU

    Рассмотрим домены, использующиеся при создании меню:

   menu=res_menu(resId);dyn_menu(menu_item_list);no_menu 
   menu_item_list=menu_item*
   menu_item=
      txt(menu_tag,  % Целое значение для этого пункта меню
      string,	 % Текст меню
      integer Mnemonic,  % Буква для акселератора
      boolean Enabled,
      boolean Checked,
      integer ItemState,    % Константы: mis_None, mis_Checked, mis_Help.
                            % Последний размещает пункт меню 'Window' 
                            % сразу перед этим пунктом. Обычно это 
                            % используется для размещения пункта 
                            % меню Help в крайнюю правую позицию
      menu_item_list);
   ownerdraw(
      menu_tag,
      long Val,  % 32-разрядное число, передаваемое в e_ownerDraw
      boolean Enabled,
      boolean Checked,
      menu_item_list) ;
   separator;  % Рисует горизонтальную линию в меню
      menu_break  % Разрыв колонки в меню
   menu_tag = unsigned
 

    Параметр ItemState определяет состояние пункта меню. Его значения приведены таблице 1.

Таблица 1. Значения параметра ItemState
Параметр Описание
mis_None Определяет обычное состояние
mis_Checked Устанавливает галочку в пункте меню
mis_Help Определяет, что этот пункт меню должен быть размещен сразу после меню Window; обычно это используется для того, чтобы поместить пункт Help в крайнее правое положение в меню (только в режиме MDI)

    Сочетание

   ItemState=mis_Checked+mis_Help,
определяет, что пункт меню должен быть размещен сразу после пункта Window и должен иметь галочку.

Определение действий для пункта меню

    Для того чтобы пункт меню выполнял какое-то действие, в обработчике событий окна при помощи эксперта кода нужно сгенерировать предложение, которое обрабатывает событие от этого пункта меню. Любой код, помещенный в это предложение, будет выполняться при выборе данного пункта меню (если пункт меню заблокирован, то этот код никогда не будет выполнен, кроме случаев, когда существует кнопка на панели инструментов, которая не заблокирована и имеет тот же идентификатор ресурса).

    Событие, которое было порождено выбором команды File | Open в окне Task, обрабатывается таким кодом:

   task_win_event_handler(Window,e_Menu(id_file_open,ShiftCtlAlt),0):-
      dlg_note("Menu","You chose Open"),
      !.

Загрузка меню из файла ресурсов

    Предикат menu_GetRes используется для получения меню из файла ресурсов. Меню загружается в структуру данных VPI из домена menu.

   NewMenu=menu_GetRes(irm_my_menu), 
   menu_Set(Window,NewMenu)

Изменение текста пункта меню

    Текст отдельного пункта меню может быть изменен при помощи предиката menu_SetText/3. Следующая строка, вставленная в событие создания окна Task - e_Create - изменит стандартный текст File Open на другой, например, Open DataBase:

   menu_SetText(Window,id_file_open,"Open DataBase")

Метки

    С пунктами меню могут быть связаны метки, которые определяют, доступно некоторое свойство или нет. Начальное состояние задается в определении меню. Это состояние можно изменить, вызвав предикат menu_Check/3.

   menu_Check(Window,menu_item_resource_identifier,Boolean)

Включение/блокировка пунктов меню

    По умолчанию новые пункты меню в редакторе меню являются включенными (кроме тех пунктов, которые автоматически генерируются экспертом приложений без кода). Их можно выключить или блокировать двойным щелчком мыши по имени пункта меню на этапе проектирования или изменением состояния заблокированного пункта, а во время работы приложения - вызовом предиката menu_Enable с последним параметром b_False.

   % Блокировка пункта File|New
   menu_Enable(Window,id_file_new,b_False),
   % Включение пункта File|New
   menu_Enable(Window,id_file_new,b_True).

Принудительная перерисовка меню

    Если вы динамически изменяете текст пунктов меню в событиях, отличных от e_Create, то ваше изменение может быть не видно пользователю на некоторых платформах. Предикат menu_update/l объявляет область экрана, занимаемую меню, недостоверной, инициируя ее перерисовку:

   menu_SetText(Window,id_file_open,"OpenDB"),
   % Вызывает перерисовку области меню 
   menu_Update(Window)

Работа с подменю в MS Windows

    Если пункт подменю нужно включить, блокировать, отметить галочкой или изменить текст, то в MS Windows необходимо использовать специальные варианты предикатов menu_Enable, menu_Check и menu_SetText, которые используют текст пункта меню вместо идентификатора.

   menu_Enable(Window,String,Boolean)
   menu_Check(Window,String,Boolean) 
   menu_SetText(Window,String,NewString)

Всплывающие меню

    Предикат menu_PopUp/4 используется для создания всплывающих меню и обычно вызывается в ответ на нажатие кнопки мыши. Следующее предложение:

   my_event_handler(Window,e_MouseDbl(Pnt,_,_),0):-!,
      menu_PopUp(Window,res_menu(idr_my_pop_up),Pnt,align_Left).

отобразит меню с идентификатором ресурса idr_my_popup в точке Pnt в окне Window когда пользователь дважды щелкнет мышью в этом окне.

    Последний параметр, который может быть равен align_Left, align_Right или align_Center, определяет положение всплывающего меню относительно точки Pnt.

    Когда пользователь щелкает мышью во всплывающем меню для данного окна, VPI посылает обычное событие e_Menu обработчику событий этого окна.

    Со следующего шага мы начнем рассматривать внешние базы данных в Visual Prolog.




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