На этом шаге мы рассмотрим создание всплывающего меню.
Во многих современных приложениях используется правая кнопка мыши, чтобы показывать локальное всплывающее меню для каждого окна. Воспользуемся и мы этой возможностью в окне Sweep.
Всплывающие меню проектируются в редакторе меню так же, как и любые нормальные выпадающие меню. Сейчас вам следует создать новое (всплывающее) меню с именем Sweep Popup. Удостоверьтесь, что константа меню - это idr_sweep_popup, и определите четыре команды, изображенные на рис. 1, - Clear, Close, Maximize и Restore.
Рис.1. Проектирование всплывающего меню
Убедитесь, что константа, используемая для пункта Clear, такая же, как и для пункта Clear, который вы определили в меню Sweep и панели инструментов Sweep (id_clear). Для остальных созданных пунктов меню должны быть константы id_close, id_maximize и id_restore (проверьте это и исправьте, если ваша версия среды визуальной разработки генерирует иные значения по умолчанию).
Предложение, которое вызывает всплывающее меню при нажатии правой кнопки мыши, очень простое. Используя редактор, добавьте дополнительное предложение для события e_MouseDown, как показано ниже. Это предложение выясняет, нажата ли правая кнопка мыши, если не выполняется другое предложение для события e_MouseDown.
Не забудьте поместить новое предложение перед старым или альтернативно изменить первую строку старого предложения так, чтобы оно реагировало только на левую кнопку мыши.
win_sweep_eh(_Win,e_MouseDown(_PNT,_,mouse_button_right,0):-!, menu_PopUp(_Win,res_menu(idr_sweep_popup),_PNT, align_Right).
Теперь запустите программу и попытайтесь вызвать окно и использовать правую кнопку мыши. Вы увидите, что пункт Clear уже работает (если вы не забыли использовать id_clear как имя константы для пунктов очистки) - рис. 2.
Рис.2. Показ всплывающего меню
Пункт меню Clear работает потому, что всплывающее меню генерирует те же события e_Menu, что и регулярные меню и панели инструментов.
Когда вы попытаетесь добавить код для трех новых пунктов меню, вы обнаружите, что их нет среди пунктов меню для окна Sweep, т. к. они не зарегистрированы (и не могут быть зарегистрированы) в эксперте окон и диалоговых окон.
Необходимые функции могут быть реализованы, если напечатать три предложения для этих событий вручную. Добавим следующие три предложения в нужном месте в вашем предикате обработчика событий:
win sweep_eh(_Win,e_Menu(id_close,_ShiftCtlAlt),0):-!, win_Destroy(_Win). win sweep_eh(_Win,e_Menu(id_maximize,_ShiftCtlAlt),0):-!, win_SetState(_Win,[wsf_Maximized]). win_sweep_eh(_Win, e_Menu(id_restore,_ShiftCtlAlt),0):-!, win_SetState(_Win,[wsf_Restored]).
Также вы можете обнаружить, что реакция на щелчок правой кнопкой мыши не соответствует поведению уже заданной обработки события e_MouseUp. Если это так, вам нужно изменить предложение, чтобы заданная обработка осуществлялась лишь при нажатии левой кнопки мыши,
win_sweep_eh(_Win,e_MouseUp(_PNT,_,mouse_button_left),0):-!
или изменить порядок предложений.
Любое изображение строк и пикселов происходит посредством выбранного текущего пера, которое имеет ширину, стиль (сплошной или полый) и цвет. Текущее состояние пера может быть получено при помощи вызова предиката win_GetPen и изменено вызовом предиката win_SetPen. Чтобы выбрать новый цвет, мы можем использовать один из общих диалогов dlg_ChooseColor, который изменяет текущий цвет и возвращает новый цвет, выбранный пользователем.
Нам необходимо активизировать изменяющую последовательность, сделаем это, добавляя один дополнительный пункт Color к всплывающему меню. Он будет иметь имя константы id_color:
win_sweep_eh(_Win,e_Menu(id_color,_ShiftCtlAlt),0):-!, Pen=win_GetPen(_Win), Pen=pen(Penwidth,PenStyle, Color), NewColor=dlg_ChooseColor(Color), win_SetPen(_Win,pen(Penwidth,PenStyle,NewColor)), win_Invalidate(_Win).
Созданное приложение можно взять здесь (400,6 Кб)
На следующем шаге мы рассмотрим окно часов.