В разрабатываемом приложении на MFC9 (MSVS 2008) применяю MFC Feature Pack.
Певоначально, когда визард генерирует каркас приложения для MDI-application, меню и тулбар плавающие.
При этом, меню главного окна — это объект класса
CMFCMenuBar.
Пользователи нередко "утаскивали" это меню за пределы экрана, а потом жаловались, что пропало меню.
Лечить приходилось чисткой той ветки реестра Windows, что отвечает за мое приложение. Обычно это: HKCU\Software...
Я задумался — как исправить проблему. Нашел вот этот материал:
http://social.msdn.microsoft.com/Forums/en-US/ca76b6c4-bcda-4855-8391-a3dc8310b74a/how-to-disable-the-cmfcmenubar-from-floating?forum=vcgeneral
Это вроде помогло — прибил меню "гвоздиками"
Однако, на днях выяснилась проблема — панели тулбаров иногда оказываются прикрыты этим самым меню, которое "прибито гвоздиками"
В общем — думаю, как с этим бороться?
Здравствуйте, AlexGin, Вы писали:
AG>В разрабатываемом приложении на MFC9 (MSVS 2008) применяю MFC Feature Pack.
AG>Певоначально, когда визард генерирует каркас приложения для MDI-application, меню и тулбар плавающие.
AG>При этом, меню главного окна — это объект класса CMFCMenuBar.
AG>Пользователи нередко "утаскивали" это меню за пределы экрана, а потом жаловались, что пропало меню.
AG>Лечить приходилось чисткой той ветки реестра Windows, что отвечает за мое приложение. Обычно это: HKCU\Software...
Пока я остановился на таком вот решении:
1) В классе, наследнике CMFCMenuBar, переопределяем виртуальный метод OnBeforeFloat:
class CMyMenuBar : public CMFCMenuBar
{
public:
virtual BOOL OnBeforeFloat(CRect& rectFloat, AFX_DOCK_METHOD dockMethod)
{
if (dockMethod != DM_DBL_CLICK)
return CMFCMenuBar::OnBeforeFloat(rectFloat, dockMethod);
else
return FALSE;
};
};
В этом методе просто заблокирован переход меню в плавающее состояние, когда пользователь (возможно, по ошибке) дал по нему двойной-клик.
2) В классе главного окна CMainFrame — тип объекта меню теперь новый:
CMyMenuBar, с переопределенным виртуальным методом
OnBeforeFloat.
3) В обработчике CMainFrame::OnCreate — все так, как первоначально сгенерировано визардом, одноко я здесь убираю "гриппер" главного меню:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;
BOOL bNameValid;
if (!m_wndMenuBar.Create(this))
{
TRACE0("Failed to create menubar\n");
return -1; // fail to create
}
m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() & ~CBRS_GRIPPER); // Я добавил эту строку, для удаления "гриппера" (AlexGin)!!!
// prevent the menu bar from taking the focus on activation
CMFCPopupMenu::SetForceMenuFocus(FALSE);
...............................................................
...............................................................
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005));
return 0;
}
После этих доработок, головное меню уже не "прибито гвоздиками" и в то же время уже не слетает при двойном клике пользователя.
Теперь, главное меню функционорует аналогично главному меню в Visual Studio 2008.
З.Ы. Подчеркиваю, что все доработки, рекомендованные для CMainFrame::OnCreate в приведенной ранее статье с форума social.msdn я откатил,
сделав так, как первоначально сгенерировал визард студии.
Здравствуйте, AlexGin, Вы писали:
AG>1) В классе, наследнике CMFCMenuBar, переопределяем виртуальный метод OnBeforeFloat:
AG>AG>class CMyMenuBar : public CMFCMenuBar
AG>{
AG>public:
AG> virtual BOOL OnBeforeFloat(CRect& rectFloat, AFX_DOCK_METHOD dockMethod)
AG> {
AG> if (dockMethod != DM_DBL_CLICK)
AG> return CMFCMenuBar::OnBeforeFloat(rectFloat, dockMethod);
AG> else
AG> return FALSE;
AG> };
AG>};
AG>
AG>В этом методе просто заблокирован переход меню в плавающее состояние, когда пользователь (возможно, по ошибке) дал по нему двойной-клик.
Более правильным решением (после feedback со стороны юзверов) мне видится такое:
class CMyMenuBar : public CMFCMenuBar
{
public:
virtual BOOL OnBeforeFloat(CRect& rectFloat, AFX_DOCK_METHOD dockMethod)
{
if ((dockMethod != DM_DBL_CLICK) && (dockMethod != DM_MOUSE)) // Добавлено DM_MOUSE
return CMFCMenuBar::OnBeforeFloat(rectFloat, dockMethod);
else
return FALSE;
};
};
Теперь уже у пользователя нет шансов "утащить" головное меню приложения, даже если пользователь "после хорошей бутылкы"