Информация об изменениях

Сообщение Re: CMFCMenuBar - проблемы применения от 31.10.2014 11:56

Изменено 31.10.2014 11:58 AlexGin

Здравствуйте, 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::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);

    // 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>В разрабатываемом приложении на 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::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 я откатил,
сделав так, как первоначально сгенерировал визард студии.