Обновление состояния пунктов меню 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Обновление состояния пунктов меню



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

В MFC есть специальный механизм для обновления пунктов меню – макрос карты сообщений ON_UPDATE_COMMAND_UI. Он предназначен для регистрации обработчиков обновления для отдельных пунктов меню. Эти обработчики вызываются перед каждым выводом пункта на экран. Обработчику обновления передается указатель на объект CCmdUI, функции-члены которого можно использовать для модификации пункта меню. Класс CCmdUI не специфичен именно для пунктов меню, поэтому данный способ обновления можно использовать для обновления кнопок панели инструментов и других элементов пользовательского интерфейса.

Допустим, в приложении есть меню Цвет и глобальная переменная для хранения текущего цвета m_nCurrentColor (0/1/2 – красный, зеленый, синий). Обработчики команд и обновления пунктов меню Цвет можно записать следующим образом:

// Фрагмент карты сообщений CMainWindow ON_COMMAND(ID_COLOR_RED, OnColorRed) ON_COMMAND(ID_COLOR_GREEN, OnColorGreen) ON_COMMAND(ID_COLOR_BLUE, OnColorBlue) ON_UPDATE_COMMAND_UI(ID_COLOR_RED, OnUpdateColorRed) ON_UPDATE_COMMAND_UI(ID_COLOR_GREEN, OnUpdateColorGreen) ON_UPDATE_COMMAND_UI(ID_COLOR_BLUE, OnUpdateColorBlue)     void CMainWindow::OnColorRed() { m_nCurrentColor = 0; }   ...   void CMainWindow::OnUpdateColorRed(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_nCurrentColor == 0); }   ...   void CMainWindow::OnUpdateColorBlue(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_nCurrentColor == 2); }

Макрос ON_UPDATE_COMMAND_UI связывает пункты меню с обработчиками обновления, аналогично тому, как ON_COMMAND связывает их с обработчиками команд. Вызов CCmdUI::SetCheck позволяет включить/выключить пометку соответствующего пункта меню. Кроме SetCheck, в классе CCmdUI есть еще несколько функций-членов, полезных для изменения пунктов меню. Они перечислены в таблице::

Функция-член Описание
CCmdUI::Enable Разрешает/запрещает пункт меню
CCmdUI::SetCheck Включает/выключает пометку пункта меню
CCmdUI::SetRadio Включает/выключает маркер возле пункта меню
CCmdUI::SetText Изменяет текст пункта меню

Функция SetRadio похожа на SetCheck, но добавляет или удаляет маркер-окружность, а не метку в виде галочки. Обычно маркер применяется для отметки текущего выбора из группы взаимно исключающих команд, а метка – для выбора независимой команды.

 

Ускоряющие клавиши

При разработке меню приложения можно завести ускоряющие клавиши, позволяющие с помощью комбинации клавиш быстро выбирать команды меню, даже не входя в него. Для этого надо создать специальный ресурс – таблицу ускоряющих клавиш, в которой сопоставлены идентификаторы пунктов меню и комбинации клавиш. В программе этот ресурс надо загрузить. Если у приложения главным окном служит окно-рамка, то Windows и это окно выполнят всю обработку ускоряющих клавиш автоматически. Приложение будет получать сообщения WM_COMMAND так же, как и в случае выбора команд меню.

В RC-файле таблица ускоряющих клавиш выглядит примерно так (как и шаблон меню, она не записывается вручную, а создается в редакторе ресурсов):

IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE BEGIN "N", ID_FILE_NEW, VIRTKEY,CONTROL "Z", ID_EDIT_UNDO, VIRTKEY,CONTROL "X", ID_EDIT_CUT, VIRTKEY,CONTROL ... VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT ... END

В данном примере IDR_MAINFRAME является идентификатором ресурса. Обычно идентификаторы меню и таблицы ускоряющих клавиш одинаковы. В каждой строке таблицы определяется одна ускоряющая клавиша. Сначала указывается клавиша, затем идентификатор соответствующего пункта меню, а затем, после слова VIRTKEY, коды виртуальных клавиш-модификаторов для указания комбинации клавиш (CONTROL, ALT или SHIFT). В приведенном примере для команды ID_FILE_NEW определена ускоряющая клавиша Ctrl+N и т.д.

Подобно меню, ускоряющие клавиши должны быть загружены и присоединены к окну перед тем, как оно будет выведено на экран. У окна-рамки это делает функция-член LoadAccelTable:

LoadAccelTable(MAKEINTRESOURCE(IDR_MAINFRAME));

Эту функцию можно не вызывать явно, она вызывается изнутри LoadFrame, которая загружает меню и таблицу ускоряющих клавиш, если у них одинаковый идентификатор ресурса.:

LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW, NULL, NULL);

 

Контекстные меню

Во многих приложениях Windows правая кнопка мыши используется для вызова контекстных меню с командами, применимыми к объекту, на котором произведен щелчок мышью. При щелчке правой кнопкой Windows посылает окну сообщение WM_CONTEXTMENU (если только щелчок правой кнопкой не был обработан по сообщению WM_MOUSEDOWN).

Для вывода контекстного меню на экран можно использовать функцию CMenu::TrackPopupMenu:

BOOL TrackPopupMenu(UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT lpRect = NULL)

Параметры x и y содержат экранные координаты для вывода меню, nFlags – битовые флаги, задающие горизонтальное выравнивание меню относительно координаты x, а также то, какие кнопки мыши (или клавиши) могут быть использованы для выбора пунктов меню. Допустимые флаги выравнивания: TPM_LEFTALIGN, TPM_CENTERALIGN и TPM_RIGHTALIGN; флаги кнопок мыши: TPM_LEFTBUTTON и TPM_RIGHTBUTTON. Указатель pWnd задает окно, которому будут послано сообщение о выбранной команде. Допустим, pMenu является указателем на объект CMenu, представляющий контекстное меню. Тогда вызов:

pMenu->TrackPopupMenu(TPM_LEFTALIGN ¦ TPM_LEFTBUTTON ¦ TPM_RIGHTBUTTON, 32, 64, AfxGetMainWnd());

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

Функция-член TrackPopupMenu обычно вызывается из обработчиков сообщений WM_CONTEXTMENU (ему соответствует макрос карты сообщений ON_WM_CONTEXTMENU). Обработчик сообщения должен иметь имя OnContextMenu и соответствовать прототипу:

afx_msg void OnContextMenu(CWnd* pWnd, CPoint point)

Параметр pWnd указывает на окно, в котором произошел щелчок правой кнопкой. а point содержит экранные координаты указателя мыши.

При необходимости экранные координаты point можно преобразовать в координаты клиентской области окна вызовом CWnd::ScreenToClient. Если обработчик OnContextMenu не обработал сообщение, он должен вызвать обработчик базового класса. Ниже приведен обработчик, в котором контекстное меню pContextMenu вызывается только при щелчке в верхней половине окна:

void CChildView::OnContextMenu(CWnd* pWnd, CPoint point) { CPoint pos = point; ScreenToClient(&pos); CRect rect; GetClientRect(&rect); rect.bottom /= 2; if (rect.PtInRect(pos)) { pContextMenu->TrackPopupMenu(TPM_LEFTALIGN ¦ TPM_LEFTBUTTON ¦ TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()); return; } CWnd::OnContextMenu(pWnd, point); }

Загрузить контекстное меню, разработанное в редакторе ресурсов, удобнее всего с помощью функции CMenu::LoadMenu, например:

CMenu menu; menu.LoadMenu(IDR_CONTEXTMENU); menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN ¦ TPM_LEFTBUTTON ¦ TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd());

 

Упражнения

1) Напишите приложение, в центре клиентской области которого выводится красная окружность с черным контуром (диаметр окружности – 50 пикселов, толщина контура –5 пикселов). Окружность можно перетаскивать мышью "за внутреннюю область" в пределах клиентской области окна. При перетаскивании окружности приложение должно выполнять захват мыши. Стрелками курсора окружность можно перемещать на 1 пиксел в заданном направлении, а в комбинации с Ctrl – на 10 пикселов в заданном направлении. По нажатию пробела или правой кнопки мыши над окружностью она должна возвращаться в центр окна.

2) Добавьте в приложение из п.1) изменение формы указателя мыши на направленные в 4 стороны стрелки, когда указатель находится над окружностью. Это стандартный указатель с идентификатором IDC_SIZEALL.

3) Сделайте так, чтобы окружность в процессе перетаскивания отображалась без контура (но диаметр оставался 50 пикселов). Для этого можно проверять в обработчике OnPaint, не захвачена ли мышь главным окном приложения.

4) Добавьте в приложение вывод в центре окружности последнего символа, полученного вместе с сообщением WM_CHAR. Для отображения символа используйте полужирный шрифт Arial.

5) Сделайте так, чтобы при нажатой клавише Ctrl окружность выводилась без контура (как при перетаскивании), чтобы показывать пользователю, что программа готова к перемещению окружности (по нажатию клавиш курсора).

6) Изучите англо-русский словарь терминов по теме 6-й лекции (см. CD-ROM).

7) Выполните лабораторную работу №3, "Работа с меню в MFC-приложениях" (см. CD-ROM).



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 232; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.87.209.162 (0.009 с.)