在VS2010中MFC的GetMenu访问冲突原因剖析以及解决办法

VC初学者经常出现的一个问题是:

根据孙鑫老师的《VC++深入详解》书中对菜单操作时,GetMenu->GetSubMenu(0)->CheckMenuItem(0,MF_BYPOSITION | MF_CHECKED); 出现错误如下,0x539001bc (mfc100d.dll) 处最可能的异常: 0xC0000005: 读取位置 0x00000004 时发生访问冲突。

返回从新跟踪一下,

CMenu* pMenu = GetMenu();
ASSERT(pMenu);
CMenu* pSubMenu = pMenu->GetSubMenu(0);
ASSERT(pSubMenu);
pSubMenu()->CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED);

发现GetMenu没有返回值,出现读取错误,但是在VC6.0就可以正常实现。

究其原因,visual studio 2010里默认采用的是Menu格式在OnCreate()末端并未生成。vs2010默认采用的是增加了扩展功能的Menu,所以调用GetMenu()会得到空指针。

水平有限,修改方法如下

1、新建工程,vs2010默认的为实用菜单栏和工具栏,修改命令栏生成方式,改为经典


2、不新建工程,修改工程属性,比较方便,不知道能不能修改,求大神指教!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是在VS2017的MFC将菜单数据存入EXCEL表格的完整代码: 首先,在你的MFC应用程序添加以下头文件: ```cpp #include <afxdisp.h> ``` 然后,在你的CMainFrame类添加以下代码: ```cpp void CMainFrame::OnExportToExcel() { // 获取应用程序的主窗口句柄 HWND hWnd = AfxGetMainWnd()->GetSafeHwnd(); // 创建Excel应用程序对象 _Application app; if (!app.CreateDispatch(_T("Excel.Application"))) { AfxMessageBox(_T("无法创建Excel应用程序对象!")); return; } // 创建Excel工作簿对象 _Workbook workbook; workbook.AttachDispatch(app.get_Workbooks()->Add()); // 创建Excel工作表对象 _Worksheet worksheet; worksheet.AttachDispatch(workbook.get_ActiveSheet()); // 设置Excel单元格的标题 worksheet.put_Range(_variant_t(_T("A1")), _variant_t(_T("菜单名称"))); worksheet.put_Range(_variant_t(_T("B1")), _variant_t(_T("快捷键"))); worksheet.put_Range(_variant_t(_T("C1")), _variant_t(_T("命令ID"))); // 获取菜单栏的菜单句柄 CMenu* pMenu = AfxGetMainWnd()->GetMenu(); if (pMenu == NULL) { AfxMessageBox(_T("无法获取菜单栏的菜单句柄!")); return; } // 获取菜单栏的菜单项数量 int nCount = pMenu->GetMenuItemCount(); // 遍历菜单栏的所有菜单项 int nRow = 2; for (int i = 0; i < nCount; i++) { // 获取菜单项的文本、快捷键和命令ID CString strText, strShortcut, strCommandID; pMenu->GetMenuString(i, strText, MF_BYPOSITION); pMenu->GetMenuString(i, strShortcut, MF_BYPOSITION | MF_BYCOMMAND); UINT nID = pMenu->GetMenuItemID(i); strCommandID.Format(_T("%d"), nID); // 将菜单项的文本、快捷键和命令ID写入Excel单元格 worksheet.put_Range(_variant_t(CString(_T("A")) + CString(nRow)), _variant_t(strText)); worksheet.put_Range(_variant_t(CString(_T("B")) + CString(nRow)), _variant_t(strShortcut)); worksheet.put_Range(_variant_t(CString(_T("C")) + CString(nRow)), _variant_t(strCommandID)); nRow++; } // 保存Excel工作簿 CString strPath = GetAppPath() + _T("MenuData.xlsx"); workbook.SaveAs(_variant_t(strPath)); // 关闭Excel工作簿和Excel应用程序 workbook.Close(); app.Quit(); AfxMessageBox(_T("菜单数据已成功导出到Excel表格!")); } CString CMainFrame::GetAppPath() { // 获取应用程序的模块句柄 HMODULE hModule = AfxGetInstanceHandle(); // 获取应用程序的完整路径 TCHAR szPath[MAX_PATH]; ::GetModuleFileName(hModule, szPath, MAX_PATH); // 去掉应用程序名称,只保留路径 CString strPath = szPath; int nPos = strPath.ReverseFind('\\'); if (nPos != -1) { strPath = strPath.Left(nPos + 1); } return strPath; } ``` 其,OnExportToExcel()函数是导出菜单数据到Excel表格的函数,GetAppPath()函数是获取应用程序路径的函数。你可以在菜单栏添加一个“导出菜单数据”菜单项,并在其响应函数调用OnExportToExcel()函数来导出菜单数据到Excel表格。 需要注意的是,导出菜单数据到Excel表格需要安装Microsoft Office软件,且Excel应用程序对象的创建可能比较耗时,所以在实际使用需要进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值