В настоящей записке описывается архитектура маршрутизации и диспетчеризации команд, так и дополнительные темы в общем окне Маршрутизация сообщений.
Обратитесь к Visual C++ программист руководстве общие сведения о архитектуры, описанных здесь, особенно различия между Windows сообщения, уведомления элементов управления и команды. В настоящей записке предполагается, что, хорошо знакомы с вопросы, поднятые в печатной документации и рассматриваются лишь весьма сложные темы.
Маршрутизация команд и диспетчеризации MFC 1.0 функциональность развивается с MFC 2.0 архитектура
Windows имеет сообщения WM_COMMAND , перегружена для предоставления уведомлений о команды меню, сочетания клавиш и уведомления управления диалогового окна.
MFC 1.0, построен на том, что немного, позволяя обработчика команды (например, "OnFileNew") в CWnd производного класса вызываются в ответ на конкретные WM_COMMAND. Это склеены вместе с структура данных называется схема сообщений и приводит механизм очень пространства эффективные команды.
MFC 1.0 обеспечивает дополнительную функциональность для разделения уведомления элементов управления от командования сообщений. Команды представлены 16-битный Идентификатор, иногда известная как идентификатор команды. Команды обычно начинаются с CFrameWnd (например: меню select или переведенные ускорителя), а получить целый ряд других окон.
MFC 1.0 используется, Маршрутизация команд в ограниченном смысле для осуществления из многодокументного интерфейса (MDI). (Фрейма окна интерфейса MDI делегировать команды для его активного MDI дочернее окно MDI).
Эта возможность обобщить и расширена в MFC 2.0, чтобы позволить команды для обработки широкого круга объектов (не только объекты window). Он обеспечивает более формальный и расширяемую архитектуру для маршрутизации сообщений и повторно использует цели команды, маршрутизация не только обработку команд, но и для обновления объектов пользовательского Интерфейса (например, пункты меню и кнопки панели инструментов) для отражения текущих доступности команды.
Идентификаторы команд
Смотрите руководство Visual C++ программиста объяснение команда привязки процесса и маршрутизации. Техническое примечание 20 содержится информация об ID именования.
Мы используем Общий префикс «ID_» для идентификаторов команд. Команда идентификаторы являются gt; = 0x8000. Панель сообщений линии или состояния покажет строку описания команды если есть STRIN>ABLE ресурс с же идентификаторы как Идентификатор команды.
В ресурсах приложения появляется в нескольких местах команда, ID может:
В исходном коде приложения появляется в нескольких местах команда, ID может:
В настоящее время, единственный в MFC, которая требует идентификаторы команд осуществляться gt; = 0x8000 является осуществление &GOSUB диалоги/команды.
GOSUB команды, с помощью команды архитектуры в диалоговых окнах
Команда архитектура маршрутизации и позволяя команды хорошо работает с окно фрейма, пункты меню, кнопки панели инструментов, кнопки панели диалогового окна, другие панели элементов управления и другие элементы интерфейса пользователя, предназначенные для обновления по, спроса и маршрут команд или управлять идентификаторы для главной команды целевого элемента (обычно фрейм главного окна). Этой цели основные команды могут направлять уведомления команды или элемента управления на целевые объекты другие команды в случае необходимости.
Диалоговое окно (модальные и немодальные) могут воспользоваться некоторые из особенностей архитектуры команда если присвоить Идентификатор элемента управления диалогового окна элемента управления идентификатор соответствующей команды. Поддержка диалоговых окон не автоматически, так что вам возможно придется написать дополнительный код.
Следует отметить, что для всех этих возможностей для правильной работы, идентификаторы команд должны быть gt; = 0x8000. Поскольку многие диалоги могут получить передана тот же кадр, общие команды должно быть > = 0x8000, в то время как не используется совместно IDC в конкретного диалога должно быть < = 0x7FFF.
Вы можете разместить обычная кнопка в нормальных модальных диалоговых с IDC кнопки значение идентификатора соответствующую команду. Когда пользователь выбирает кнопку, владелец диалоговое окно (обычно фрейм главного окна) получает команду так же, как любой другой команды. Это называется GOSUB команды, так как он обычно используется для воспитывать другое диалоговое окно (GOSUB первого диалога).
Также можно вызвать функцию CWnd::UpdateDialogControls на вашем диалоговом окне и передать ему адрес фрейма главного окна. Эта функция будет включена или отключить элементы управления диалогового окна на основе того, имеют ли они обработчиков команд в кадре. Эта функция вызывается автоматически для вас для панелей элементов управления в цикле простоя вашего приложения, но необходимо вызвать непосредственно для нормального диалоговых окон, которые вы хотите иметь эту возможность.
Когда вызывается ON_UPDATE_COMMAND_UI
Поддержание включена/проверка состояния пунктов меню все программы все время может быть вычислительно дорогостоящей проблемой. Распространенный метод должен включить/проверка пункты меню только тогда, когда пользователь выбирает POPUP. MFC 2.0 осуществление CFrameWnd обрабатывает сообщение WM_INITMENUPOPUP и использует архитектуру маршрутизации команд для определения государства меню через обработчики ON_UPDATE_COMMAND_UI.
CFrameWnd также обрабатывает сообщение WM_ENTERIDLE для описания текущего меню пункт выбранной на статус бар (также известный как линия сообщения).
Структура меню приложения, под редакцией Visual C++, используется для представления потенциальным команды, доступные в WM_INITMENUPOPUP время. Обработчики ON_UPDATE_COMMAND_UI может изменить состояние или текст меню, или для передовых видов использования (например, список файлов MRU или OLE всплывающее меню команд), на самом деле изменить структуры меню перед выводом меню.
Тот же самый вид обработки ON_UPDATE_COMMAND_UI делается для панели инструментов (и других панелей элементов управления) когда приложение входит простой цикл. Справочник по библиотекам классов и техническое примечание 31 более подробная информация о панелей элементов управления.
Вложенные меню Popup
Если вы используете структуры вложенных меню, можно заметить, что в ON_UPDATE_COMMAND_UI для первого пункта меню в контекстное меню вызывается обработчик в двух различных случаях.
Сначала она вызывается для самого popup. Это необходимо, так как всплывающие меню не имеют идентификаторов и мы используем ID элемента первого меню popup для обозначения всей popup. В этом случае переменная-член m_pSubMenu объекта CCmdUI будет не NULL и будет указывать на всплывающее меню.
Во-вторых она вызывается непосредственно перед пункты меню в контекстное меню, чтобы сделать. В этом случае Идентификатор ссылается только на первый пункт меню и переменную-член m_pSubMenu объекта CCmdUI будет иметь значение NULL.
Это позволяет включить отличается от его пункты меню popup, но написать код знает меню. К примеру в вложенного меню со следующей структурой:
Filegt;
Новый >
Лист (ID_NEW_SHEET)
Диаграмма (ID_NEW_CHART)
Команды ID_NEW_SHEET и ID_NEW_CHART может быть независимо включен или отключен. Всплывающее меню «New» должна быть включена, если любой из этих двух включена.
Обработчик команд для ID_NEW_SHEET (первая команда в popup) будет выглядеть примерно так:
void CMyApp::OnUpdateNewSheet (CCmdUI * pCmdUI)
{
nbsp; Если (pCmdUI - > m_pSubMenu! = NULL)
{
/ / включить весь popup для «Новый» таблицы и диаграммы
BOOL bEnable = m_bCanCreateSheet || m_bCanCreateChart;
/ / CCmdUI::Enable это холостой для этого случая, так что мы
/ / должны сделать то, что это будет сделано.
pCmdUI - > m_pMenu - > EnableMenuItem (pCmdUI - > m_nIndex,
MF_BYPOSITION |
(bEnable? MF_ENABLED: (MF_DISABLED | MF_GRAYED)));
возвращение;
}
/ / иначе только команда новый лист
pCmdUI - > Enable(m_bCanCreateSheet);
}
Обработчик команд для ID_NEW_CHART бы нормального обновления обработчик команд и посмотреть, что-то вроде:
void CMyApp::OnUpdateNewChart (CCmdUI * pCmdUI)
{
nbsp; pCmdUI - > Enable(m_bCanCreateChart);
}
ON_COMMAND и ON_BN_CLICKED
Сообщение карты макросы для ON_COMMAND и ON_BN_CLICKED являются одинаковыми. MFC командования и управления маршрутизации механизм уведомления только использует Идентификатор команды для решить, где для маршрутизации. Уведомления элементов управления с кодом уведомления управления нулевой (BN_CLICKED), интерпретируются как команды.
Расширенные Примечание: В самом деле, все сообщения уведомления управления пройти через цепь обработчика команды. Поэтому это технически возможно для вас, чтобы написать обработчик уведомления управления для скажем EN_CHANGE в вашем классе документа. Это не правило, целесообразно, так как практического применения этой функции очень мало, эта функция не поддерживается в ClassWizard, и использование функции может привести к нестабильной кода.
Отключение автоматического отключения элементов управления Button
Если поместить элемент управления button на панели диалогового окна, или в диалоговое окно, используя, где вы звоните CWnd::UpdateDialogControls на свой собственный, вы заметите, что кнопки, которые не имеют обработчики ON_UPDATE_COMMAND_UI или ON_COMMAND автоматически отключается для вас в Framework. В некоторых случаях вам не будет нужно иметь обработчик, но будет использовать эту кнопку для остаются включенными. Самый простой способ для достижения этой цели является добавление обработчика манекен команды (это легко сделать с ClassWizard) и делать ничего в нем.
Маршрутизация окна сообщений
Ниже описываются некоторые более сложные темы на классы MFC и маршрутизация сообщений Windows и другие темы влияния их. Кратко описан только информация здесь. Обратитесь к Справочник по библиотекам классов для подробной информации об общедоступных интерфейсов API. Обратитесь к исходный код библиотеки MFC для получения дополнительной информации о детали реализации.
Обратитесь к технической записке 17 за подробную информацию о очистки окна, очень важной темой для всех CWnd-производные классы.
CWnd вопросы
Для реализации функции-члена CWnd::OnChildNotify обеспечивает мощный и расширяемый архитектуру для дочерних окон (также известный как элементы управления) для подключения или иным образом информироваться о сообщений, команд и уведомления элементов управления, которые идут к их родителей (или "владелец"). Если дочернее окно (/ управления) представляет собой объект C++ CWnd , сам, виртуальная функция OnChildNotify вызывается сначала с параметрами из исходного сообщения (то есть, структурой MSG ). Дочернее окно может оставить сообщение в одиночку, есть его или изменить сообщение для родителя (редко).
Реализация по умолчанию CWnd обрабатывает следующие сообщения и использует OnChildNotify крюк позволить дочерних окон (элементы управления) для того чтобы получить первые трещины на сообщение:
Вы заметите, что ловушка OnChildNotify используется для изменения сообщений рисования владельцем в self-draw сообщения.
В дополнение к OnChildNotify Хук сообщения прокрутки имеют дальнейшей маршрутизации поведение. Смотрите ниже для получения более подробной информации о полосы прокрутки и источниках WM_HSCROLL и WM_VSCROLL сообщений.
CFrameWnd вопросы
Класс CFrameWnd обеспечивает большую часть Маршрутизация команд и интерфейса пользователя обновление осуществления. Это используется главным образом для фрейма главного окна приложения (CWinApp::m_pMainWnd), но применяется ко всем окнам кадра.
Фрейм главного окна — это окно в строке меню и является родительской строки состояния или сообщение строку. Обратитесь к выше обсуждение Маршрутизация команд и WM_INITMENUPOPUP.
Класс CFrameWnd обеспечивает управление активного представления. Следующие сообщения маршрутизируются через активное представление:
CMDIFrameWnd/CMDIChildWnd вопросы
Как MDI фрейма окна классы являются производными от CFrameWnd и поэтому оба для включены же рода обновления пользовательского интерфейса в CFrameWndи маршрутизации команд. В типичном приложении MDI только фрейм главного окна (то есть, объект CMDIFrameWnd ) держит панель меню и строки состояния и поэтому является главным источником реализации маршрутизации команд.
Общая схема маршрутизации является активное дочернее окно MDI получает первые трещины на команды. Функции PreTranslateMessage по умолчанию обрабатывать таблицы сочетаний клавиш для обоих дочерних окон MDI (первый) и рама MDI (второй), а также стандартных ускорителей команды системы MDI, обычно занимаются TranslateMDISysAccel (последний).
Полоса прокрутки вопросов
При обработке сообщения прокрутки (WM_HSCROLL/OnHScroll и/или WM_VSCROLL/OnVScroll ), вам нужно попробовать писать код обработчика, поэтому она не полагается на откуда сообщение панель прокрутки. Это проблема не только общего Windows, так как сообщения прокрутки может исходить от полосы управления истинной прокрутки или WS_HSCROLL/WS_VSCROLL полосы прокрутки, которые являются не прокручивать бар элементов управления.
MFC распространяется, чтобы элементы управления полосы прокрутки для детей или братьев и сестер окна, прокрутка (на самом деле родитель-потомок между полосой прокрутки и будучи прокрутке окна может быть что угодно). Это особенно важно для общих полосу прокрутки с окнами разделителя. Обратитесь к технической записке 29 подробную информацию о выполнении CSplitterWnd включая больше информации по вопросам общих прокрутки бар.
На стороне записки существует два CWnd производные классы, где время создать Стили отрезков прокрутки, указанные в ловушке и не передаются в Windows. При передаче в создание обычной, можно независимо задать WS_HSCROLL и WS_VSCROLL , но после того, как создание не может быть изменен. Конечно следует напрямую не проверить или установить WS_?ПРОКРУТКА битов стиля окна, которое они создали.
Для CMDIFrameWnd Стили отрезков прокрутки, которое передается в Create или LoadFrame , используются для создания MDICLIENT. Если вы желаете иметь прокручиваемой области MDICLIENT (как Windows руководитель программы) не забудьте задать оба полоса стилей прокрутки (WS_HSCROLL | WS_VSCROLL) стиль, используемый для создания CMDIFrameWnd.
Для CSplitterWnd Стили отрезков прокрутки относятся к специальным общих полосу прокрутки для разделителя регионов. Для windows статический разделитель будет обычно не задано либо стиль панели прокрутки. Для динамических разделителя windows, как правило, полоса набора стилей в каком направлении будет разделить, то есть, WS_HSCROLL если вы можете разделить строки, WS_VSCROLL если вы можете разделить столбцы прокрутки.
Технические примечания по номеру |nbsp; Технические примечания по категориям