CMFCMenuBar不可自定义但仍受自定义对话框的影响。 [英] CMFCMenuBar not customizable but still affected by the customize dialog.

查看:117
本文介绍了CMFCMenuBar不可自定义但仍受自定义对话框的影响。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用VS 2013编写的应用程序,带有一些工具栏和一个主菜单。菜单源自CMFCMenuBar,工具栏源自CMFCToolBar。菜单部分是从资源文件定义的,部分是由于加载的驱动程序等动态添加的条目。



我想要工具栏但不能自定义菜单,所以我通过在菜单构造函数中设置m_bDisableCustomize = TRUE来禁用菜单的自定义。



问题是我仍然可以选择从自定义对话框重置菜单(从工具栏打开时),然后菜单将丢失所有动态添加的条目。 (一个MFC错误?)



我试过覆盖菜单类中的RestoreOriginalState() - 函数,但由于某种原因它永远不会被调用 - 为什么?



有什么想法可以完全禁用CMFCMenuBar的重置,还是在它破坏动态添加的菜单项之前在菜单类中捕获它?



问候,

RobertM

I have an application written in VS 2013, with some toolbars and a main menu. The menu is derived from a CMFCMenuBar and the toolbars are derived from CMFCToolBar. The menu is partly defined from the resource file and partly by dynamically added entries due to loaded drivers etc.

I want the toolbars but not the menu to be customizable, so I have disabled customization of the menu by setting m_bDisableCustomize = TRUE in the menu constructor.

The problem is that I can still choose to reset the menu from the Customize-dialog (when opened from a toolbar), and then the menu will lose all dynamically added entries. (an MFC bug?)

I have tried overriding the RestoreOriginalState()-function in the menu class, but for some reason it is never called - why?

Any ideas out there how to either disable the reset of the CMFCMenuBar altogether or catch it in the menu class before it destroys the dynamically added menu entries?

Regards,
RobertM

推荐答案

我无法将整个代码库显示为它有点大(人们可能会因为我发布它而感到恼火),但这里是菜单类和主框架中菜单对象的引用。在主框架中隐式创建菜单。



如果在Customize对话框中的reset命令上调用RestoreOriginalState或OnReset,我可以解决问题,但对于某些人来说原因他们不是。



IaMenuBar.h

I can't show my entire code base as it is sort of big (and people might get kind of annoyed if I published it), but here is the menu class and the references to the menu object in the main frame. The menu is implicitly created in the main frame.

I could solve the problem if the RestoreOriginalState or OnReset was called on the reset command in the Customize dialog, but for some reason they are not.

IaMenuBar.h
// This is the main menu class. We have derived our own class to be able to
// for example block customization.
class IaMenuBar : public CMFCMenuBar
{
  DECLARE_SERIAL(IaMenuBar)
public:
  IaMenuBar();
  virtual ~IaMenuBar();

  virtual BOOL CreateEx( CWnd* pParentWnd,
                         DWORD dwCtrlStyle,
                         DWORD dwStyle,
                         CRect rcBorders,
                         UINT  nID );
  virtual BOOL RestoreOriginalState();   // TBD: Is not called???
  virtual BOOL CanBeRestored() const;
  virtual BOOL LoadState(LPCTSTR lpszProfileName = NULL, int nIndex = -1, UINT uiID = (UINT)-1);
  virtual BOOL SaveState(LPCTSTR lpszProfileName = NULL, int nIndex = -1, UINT uiID = (UINT)-1);

  afx_msg void OnContextMenu(CWnd* pWnd, CPoint pos);
  virtual void OnReset();   // TBD: Is not called???

private:
  DECLARE_MESSAGE_MAP()
};





IaMenuBar.cpp



IaMenuBar.cpp

#include "IaPch.h"
#include "IaMenuBar.h"

IMPLEMENT_SERIAL(IaMenuBar, CMFCMenuBar, VERSIONABLE_SCHEMA | 1)

//{{AFX_MSG_MAP(IaMenuBar)
BEGIN_MESSAGE_MAP(IaMenuBar, CMFCMenuBar)
  ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()
//}}AFX_MSG_MAP

IaMenuBar::
IaMenuBar()
: CMFCMenuBar()
{
  m_bDisableCustomize = TRUE;
}

IaMenuBar::
~IaMenuBar()
{
}

BOOL 
IaMenuBar::
CreateEx( CWnd* pParentWnd,
          DWORD dwCtrlStyle,
          DWORD dwStyle,
          CRect rcBorders,
          UINT  nID )
{
  if (!__super::CreateEx(pParentWnd, dwCtrlStyle, dwStyle, rcBorders, nID))
  {
    return FALSE;
  }
  return TRUE;
}

BOOL 
IaMenuBar::
RestoreOriginalState()
{
  // Skip restoring of the state, since we don't allow customization and
  // we don't want our inserted menus to be replaced by the insertion
  // points.
  return TRUE;
  // TBD: This function is not called!
}

BOOL
IaMenuBar::
CanBeRestored() const
{
  return FALSE;
}

BOOL 
IaMenuBar::
LoadState(LPCTSTR lpszProfileName /*= NULL*/, int nIndex /*= -1*/, UINT uiID /*= (UINT)-1*/)
{
  // Skip loading of the state, since we don't allow customization and
  // we want to control what the menu looks like ourselves.
  return TRUE;
}

BOOL 
IaMenuBar::
SaveState(LPCTSTR lpszProfileName /*= NULL*/, int nIndex /*= -1*/, UINT uiID /*= (UINT)-1*/)
{
  // Skip saving of the state, since we don't allow customization and
  // we want to control what the menu looks like ourselves.
  return TRUE;
}

void
IaMenuBar::
OnContextMenu(CWnd* pWnd, CPoint pos)
{
  // Prevent the context menu from appearing if the customize dialog is
  // open. That context menu is for customizing the menu, which we have
  // disabled.
  if (IsCustomizeMode())
    return;

  CMFCMenuBar::OnContextMenu(pWnd, pos);
}

void
IaMenuBar::
OnReset()
{
  // Prevent the context menu from appearing if the customize dialog is
  // open. That context menu is for customizing the menu, which we have
  // disabled.
  if (IsCustomizeMode())
    return;

  CMFCMenuBar::OnReset();
}





IaMainFrame.h



IaMainFrame.h

class IaMainFrame : 
  public IfMDIFrameWnd,...

private:
...
  // control bar embedded members
  IaMenuBar           m_wndMenuBar;





IaMainFrame.cpp



IaMainFrame.cpp

int
IaMainFrame::
OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (IfMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;

  if (!m_wndMenuBar.Create(this))
  {
    TRACE0("Failed to create menubar\n");
    return -1;
  }
  m_wndMenuBar.SetPaneStyle(CBRS_BORDER_TOP | CBRS_TOP | CBRS_SIZE_FIXED |
    CBRS_TOOLTIPS | CBRS_FLYBY);

...

  // If I use CBRS_ALIGN_TOP instead of CBRS_ALIGN_ANY here the menu appears 
  // under the toolbar, for some reason.
  m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
  EnableDocking(CBRS_ALIGN_TOP);
  DockPane(&m_wndMenuBar);

...
}

void
IaMainFrame::
UpdateMenuBar()
{
  // Found no other way (than being brutal) to make the CMFCMenuBar rebuild what it displays.
  HMENU hMenu = m_wndMenuBar.GetHMenu();
  m_wndMenuBar.CreateFromMenu(hMenu, TRUE, TRUE);
}


这篇关于CMFCMenuBar不可自定义但仍受自定义对话框的影响。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆