Bootstrap

VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法

解决方法1: //来源:http://www.cnblogs.com/yuzhoufeng/archive/2011/12/11/2284200.html

今天学习VC++ 2010 MFC单文档应用程序中动态添加菜单,下面是代码部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
int  CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
......
CMenu m_Menu;
m_Menu.CreatePopupMenu();
ASSERT(m_Menu.GetSafeHmenu());
GetMenu()->AppendMenuW(MF_POPUP,( UINT )m_Menu.m_hMenu,_T( "文件" ));
m_Menu.AppendMenuW(MF_STRING,111,_T( "新建" ));
m_Menu.AppendMenuW(MF_STRING,112,_T( "打开" ));
m_Menu.Detach();
return  0;
}

  但是GetMenu()返回始终未NULL,无法获取菜单指针,网上查了下,说VS2010建的SDI/MDI与之前的不一样,是类似BCG的一些东西,所以用之前的方法GetMenu()得到CMenu是NULL或者无效。

【解决方案】:

  在CMainFrame类中找到CMFCMenuBar m_wndMenuBar;这个成员变量,将跟它相关的代码注释掉的话,然后运行,OK。

 

解决方法2: //来源:http://blog.csdn.net/grasshopperwarbler/article/details/6337754

这里说的是SDI的情况,如果在vs2010里面按着默认选项创建一个单文档工程(Single Document).

问题分析:

出错的代码如下 :
GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);
加在CMainFrame::Oncreate()里面,整个程序就会崩溃,出现的异常类似如此:Unhandled exception at 0x58aba12c (mfc100ud.dll) in menu1.exe: 0xC0000005: Access violation reading location 0x00000004.

出错的原因是,在执行这段代码的时候,Menu并没有生成。因为采用断点来检测的话,此时的GetMenu返回值不是一个正常的地址。为什么会这样呢?

后来才发现visual studio2010里默认采用的是Menu格式在OnCreate()末端并未生成。vs2010默认采用的是增加了扩展功能的Menu,所以调用GetMenu()会得到空指针。

解决方法:

最原始的解决方法是采用回原来的Menu格式。就在新建工程的一个对话框中选择回原始的菜单模式即可如下图:

[整理]VS2010中GetMenu()和GetSubMenu(0)为NULL引发异常的解决方法 - 钰央 - 计算机视觉·图像处理

不过经过更改后编译会出现两个错误,是关于:

ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)

两句代码是关于打印功能的。如果不涉及这方面的功能,可以直接把这两句话注释掉。(也可以在创建项目时把“打印预览”去掉)

然后在CMainFrame::OnCreate()末尾加上GetMenu()->GetSubMenu(0)->CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);
程序就可以顺利通过了。

;