СашА
На этот вопрос было получено удивительно мало ответов. Неужели этим почти никто не интересовался?
A 1 Среди заголовочных файлов MFC есть заголовочный файл afxpriv.h, в котором объявлено несколько недокументированных классов, в том числе например класс CDockBar. По-моему именно он обеспечивает создание окон в стиле Visual Studio.
Anton
Я хотел бы предостеречь читателей: использование недокументированных классов чревато неприятностями. В том же MSDN написано, что члены и методы класса CDockBar, скорее всего, претерпят сильные изменения в будущем.
A 2 Во время оно я боролся с этим вопросом. Вот краткие выводы: DialogBar – ДЕРЬМО. Проще сходить на сайт http://www.datamekanix.comи слить оттуда компонент CSizingControlBar написанный Crisite Posea. Он тоже не предел совершенства, но работает почти так же как и Workspace.
Vassili Bourdo
Хочу добавить (как еще один вариант), что я кажется видел класс с такой же функциональностью в Ultimate Toolbox от Dundas Software.
В ПОИСКАХ ИСТИНЫ
Q. У меня есть приложение MFC на базе диалога. Я решил организовать переключение некоторых режимов через главное меню, т.е. в меню присутствуют названия режимов и активный в данный момент режим помечен точкой. Для этого я создал обработчики ON_UPDATE_COMMAND_UI для соответствующих пунктов меню и в них вызов СCmdUI::SetRadio(). Например:
void CHeatDlg::OnUpdateSolve(CCmdUI* pCmdUI) {
if (mode == 1) pCmdUI->SetRadio(TRUE);
else pCmdUI->SetRadio(FALSE);
}
Это не сработало. Похоже, что сообщения ON_UPDATE_COMMAND_UI просто не посылаются. До этого я использовал такой же подход в приложениях SDI и MDI и все работало. Есть какие-нибудь мысли по этому поводу?
Андрей Моисеев
Успехов!
Алекс Jenter jenter@mail.ru Красноярск, 2000.
Программирование на Visual C++
Выпуск №21 от 29 октября 2000 г.
Все настоящие программисты делятся на три категории: на тех, кто пишет программы, завершающиеся по нажатию F10, Alt-F4 и Alt-X. Все остальные принципы деления надуманны.
авт. неизв.
Рад снова приветствовать вас!
Сегодняшний выпуск посвящен вашим письмам с вопросами, ответами, комментариями, замечаниями и дополнениями, которых у меня накопилось изрядное количество.
ВОПРОС-ОТВЕТ
Q. У меня есть приложение MFC на базе диалога. Я решил организовать переключение некоторых режимов через главное меню, т.е. в меню присутствуют названия режимов и активный в данный момент режим помечен точкой. Для этого я создал обработчики ON_UPDATE_COMMAND_UI для соответствующих пунктов меню и в них вызов СCmdUI::SetRadio(). Например:
void CHeatDlg::OnUpdateSolve(CCmdUI* pCmdUI) {
if (mode == 1) pCmdUI->SetRadio(TRUE);
else pCmdUI->SetRadio(FALSE);
}
Это не сработало. Похоже, что сообщения ON_UPDATE_COMMAND_UI просто не посылаются. До этого я использовал такой же подход в приложениях SDI и MDI и все работало. Есть какие-нибудь мысли по этому поводу?
Андрей Моисеев
A 1Решение проблемы обработчика ON_UPDATE_COMMAND_UI частично кроется в одном из предыдущих выпусков — №18. Ведь этот обработчик вызывается Framework'ом MFC из OnIdle объекта приложения, а в dialog-based программах OnIdle не работает. Тут можно посоветовать использовать в качестве главного окна аппликации скрытое "фиктивное" окно и подсунуть его в качестве родителя диалога.
Sergey Emantayev
A 2 Дело в том, что вся логика генерации user-interface update command message для меню (создание объекта CCmdUI и т.д.) реализована в CFrameWnd::OnInitMenuPopup. Соответственно в dialog-based приложениях вызов этой функции отсутствует. Очевидно, предполагалось что в диалогах меню не обязательно. Поэтому можно предложить два варианта. Общим в них является необходимость создания обработчика OnInitMenuPopup для вашего диалога. Первый вариант подойдёт, если вы уже повсеместно расставили обработчики ON_UPDATE_COMMAND_UI, и не хотите ничего переделывать: Вы просто копируте тело функции CFrameWnd::OnInitMenuPopup в созданную вами функцию (благо, что исходники доступны), чистите всё лишнее (разобраться достаточно легко) и созданные вами обработчики OnUpdateXXX начинают вызываться Второй вариант предполагает, что вы, что называется "ручками", изменяете состояния пунктов меню прямо в созданной вами выше функции OnInitMenuPopup, используя передаваемый ей как параметр CMenu*. Этот вариант вполне приемлем, если меню не очень большое и структура его не очень разветвлённая. Для некоторых этот вариант также покажется более привлекательным по той причине, что вы всё делаете сами, а не копируете фрагменты чужого кода.
Роман Клепов
A 3Когда Windows собирается отобразить всплывающее меню, она посылает сообщение WM_INITMENUPOPUP, чтобы программа могла на лету кое-что поменять: отключить некоторые пункты, расставить галочки и т. п. Поэтому базовый способ модификации всплывающих меню состоит в перехвате этого сообщения с последующим использованием функций EnableMenuItem, CheckMenuItem и т.п.
Читать дальше