Отслеживание состояния команд
Текущее состояние команды меню или кнопки на панели инструментов легко определяется по их облику: недоступная команда или кнопка имеет блеклый (grayed) вид. Кроме того, бывают команды, работающие по принципу переключателя (включен – выключен). Их состояние определяется по наличию – отсутствию флажка слева от команды меню или утопленному – нормальному облику кнопки.
Отслеживание состояния команд производится каркасом приложения в паузах между обработкой сообщений. В эти моменты вызывается виртуальная функция Onldle, и если вы ее переопределите для выполнения какой-либо своей фоновой задачи, то можете нарушить или замедлить процесс отслеживания состояния команд. Логика перехода между состояниями определяется специальными функциями т – обработчиками событий UPDATE_COMMAND_UI. Мы должны создать такой обработчик для отслеживания состояния команды ID_EDIT_NEWPOLY. Схема создания точно такая же, как и для самой команды, за исключением того, что вы вместо строки COMMAND выбираете строку UPDATE_COMMAND_UI:
void CDrawView::OnUpdateEditNewpoly(CCradUI *pCmdUI) { pCmdUI › SetCheck(m_bNewPoints); }
Метод SetCheck вспомогательного класса ccmdui устанавливает флажок рядом с командой меню, если параметр имеет значение TRUE, или снимает его, если параметр имеет значение FALSE. Состояние кнопки на инструментальной панели синхронизировано с состоянием команды меню, имеющей тот же идентификатор.
Следующим шагом в развитии приложения будет введение в действие второй панели инструментов IDR_Draw_TYPE. Загрузка из ресурсов панели инструментов осуществляется методом LoadToolBar класса CToolBar. Так как объект этого класса (m_wndToolBar) хранится в классе главного окна (CMainFrame), то и смену панелей инструментов целесообразно выполнять в этом же классе. Введите в него новый метод:
void CMainFrame::ChangeToolbar(UINT tb) { //=== в параметре tb будет передан идентификатор панели m_wndToolBar.LoadToolBar (tb); //=== Перерисовка toolbar RecalcLayout(); }
Метод CFrameWnd::RecalcLayout занимается перерисовкой панели инструментов и пересчетом размеров клиентской области окна, так как панель инструментов хоть и управляется классом главного окна, но расположена в клиентской области окна, отнимая у нее часть полезной площади.
Имея в классе главного окна такую функцию, как ChangeToolbar, мы просто должны вызывать ее в нужные моменты, подавая на вход идентификатор той или иной панели. Осталось правильно определить те моменты, когда надо производить смену панелей. Очевидно, это моменты перевода фокуса из окна типа CTreeFrame в окно типа CDrawFrame и наоборот.
Примечание
Здесь важно понять, что фокус на самом деле попадает в одно из дочерних окон CLeftView или CRightView или CDrawView. Но это происходит после того, как он попадет в родительское окно-рамку. В принципе, возможны и другие варианты решения проблемы своевременной смены панелей инструментов. Например, переопределить в каждом из трех представлений виртуальную функцию OnActivateView и в ней вызывать ChangeToolbar.
Заметьте, что фокус может быть переведен в окно четырьмя разными способами:
- активизация представления или его рамки при помощи левой кнопки мыши;
- ввод клавишной комбинации (accelerator) CTRL + F6, которая обрабатывается каркасом приложения и по очереди в цикле активизирует окна;
- системная активизация следующего окна при закрытии одного из окон;
- системная активизация окна при создании одного из окон (вспомните вызов CreateNewFrame В теле CTreeDoc::MakeView) или открытии существующего документа.
Во всех четырех случаях окну-рамке будет послано сообщение WM_SETFOCUS, что нам и надо. Создайте известным вам способом обработчики рассматриваемого сообщения в двух классах окон-рамок CTreeFrame и CDrawFrame и наполните заготовки кодами, как показано ниже:
void CTreeFrame::OnSetFocus(CWnd* pOldWnd) //====== Родитель делает свое дело, CMDIChildWnd::OnSetFocus(pOldWnd); //====== а мы делаем свое ((CMainFrame*)GetParentFrame()) › ChangeToolbar(IDRJTreeTYPE); void CDrawFrame::OnSetFocus(CWnd* pOldWnd) CMDIChildWnd::OnSetFocus(pOldWnd); ((CMainFrame*)AfxGetMainWnd()) › ChangeToolbar(IDR_DrawTYPE);