"Warning: GetWindowMenuPopup failed! "

2023-05-16

对mdi程序中一个弹出菜单警告原因的分析
作者: laomai
网址: http://blog.csdn.net/laomai
(转载时请注明出处)
一、引子
   最近在编译一个别人的mdi程序代码,在调试程序时,vc6的output窗口实现一个了提示
  "Warning: GetWindowMenuPopup failed! "
  为了找出产生这个警告的原因,查了不少资料,并仔细跟踪了有关的mfc代码,
终于找到了这个警告产生的原因,现将我的探索过程记录一下,供大家分享。   
二、产生该警告的代码
   由于这个提示是在运行时出现,自然首先要看看什么代码输出了这个警告。在
mfc的源代码目录中(对于vc6 ,这个目录为 Microsoft Visual Studio/VC98/MFC/SRC)
搜索含有"GetWindowMenuPopup failed!"字符串的文件,发现在该目录下  
的WINMDI.CPP文件的第877行有这么一句
TRACE0("Warning: GetWindowMenuPopup failed!/n");
看来,这就是产生该警告的语句了。下面就来看看这条语句为什么被调用
备注:trace0是vc提供的一个宏,作用和printf类似,只是他的输出是在
vc的output窗口中。

三、函数流程分析
//Microsoft Visual Studio/VC98/MFC/SRC/WINMDI.CPP文件的851行
HMENU CMDIFrameWnd::GetWindowMenuPopup(HMENU hMenuBar)
 // find which popup is the "Window" menu
{
     if (hMenuBar == NULL)
     return NULL;

     ASSERT(::IsMenu(hMenuBar));

     int iItem = ::GetMenuItemCount(hMenuBar);
     while (iItem--)
    {
                HMENU hMenuPop = ::GetSubMenu(hMenuBar, iItem);
  if (hMenuPop != NULL)
  {
   int iItemMax = ::GetMenuItemCount(hMenuPop);
   for (int iItemPop = 0; iItemPop < iItemMax; iItemPop++)
   {
    UINT nID = GetMenuItemID(hMenuPop, iItemPop);
    if (nID >= AFX_IDM_WINDOW_FIRST && nID <= AFX_IDM_WINDOW_LAST)
     return hMenuPop;
   }
  }
 }

 // no default menu found
 TRACE0("Warning: GetWindowMenuPopup failed!/n");
 return NULL;
}

我们来看看GetWindowMenuPopup函数的流程,它以一个菜单句柄hMenuBar作为输入参数,
然后依次查看这个菜单的各子菜单,在每个子菜单里依次查看其菜单项的id,如果某个菜单项
的id在AFX_IDM_WINDOW_FIRST和AFX_IDM_WINDOW_LAST之间,就返回该菜单项所在的子菜单句柄。
如果没找到,就执行后面的trace0语句,输出开头提到的
"Warning: GetWindowMenuPopup failed!"
最后返回一个null值。
    现在我们找到了初步的原因-该项目中所有的菜单项的id都不在AFX_IDM_WINDOW_FIRST和
AFX_IDM_WINDOW_LAST之间,因此函数不会在循环体内结束。如果想去掉这个警告,只要手工
修改项目中的resource.h文件,使某个菜单项的id值满足代码中要求的条件即可。再次编译运行,
这个警告果然没有了。
    那么AFX_IDM_WINDOW_FIRST和AFX_IDM_WINDOW_LAST的值究竟是多少呢??
在Microsoft Visual Studio/VC98/MFC/Include/AFXRES.H的219行可以看到

define AFX_IDM_WINDOW_FIRST            0xE130

define AFX_IDM_WINDOW_LAST             0xE13F

那么这两个id到底代表什么呢?

四、对比实验——查看mdi程序的默认设置
   为了更清楚的看明各id的含义,我们在vc6中建立一个默认的mdi程序,名为mditest.
在return hMenuPop;一句前加上断点,看看满足条件的id到底是多少。
经过实际的调试,这个nID为十六进制的0xe130,
而它对应的菜单项id为ID_WINDOW_NEW,即afxres.h文件的第212行

define ID_WINDOW_NEW                   0xE130

而这个菜单项正是mditest程序中的IDR_MDITESTYPE菜单中的第四个子菜单
的第一个菜单项,即"窗口->新建窗口"菜单。也就是说mfc默认把"窗口"子菜单做为
GetWindowMenuPopup返回的弹出菜单。

五、小结
本文中的警告产生流程可以总结如下
1、在mfc程序的CMDITestApp::InitInstance函数中,有一句
pDocTemplate = new CMultiDocTemplate(
  IDR_MDITESTYPE,....);
  第一个参数的id值有很多含义,其中一个就是程序主菜单的id,程序通过这个id
  得到主菜单的句柄,把它作为参数传给CMDIFrameWnd::GetWindowMenuPopup
  函数。
2、CMDIFrameWnd::GetWindowMenuPopup的第一次调用发生在
   if (!ProcessShellCommand(cmdInfo))一句中,
   GetWindowMenuPopup的实际作用就是从输入的父菜单中抽出一个可以作为弹出菜单的子菜单。
不过这个弹出菜单如何在程序运行时被显示出来,我还没找到办法,希望有知道的读者告诉我。

六、扩充实验
在MDITest程序的资源视图中,删掉IDR_MDITESTYPE菜单,弹出菜单的警告没有了
又会出现另外一个警告
Warning: no shared menu for document template #129.
Warning: no shared menu for document template #129.
有的兴趣读者可以自行分析以上现象产生产生的原因,并把您的心得和我交流
---------------------
作者:laomai
来源:CSDN
原文:https://blog.csdn.net/laomai/article/details/1847177?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!

转载于:https://www.cnblogs.com/Dennis-mi/articles/9802735.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

"Warning: GetWindowMenuPopup failed! " 的相关文章

随机推荐

  • 常见的ftp工具有哪些,分享8款常见的ftp工具

    市面上有很多ftp服务器软件 xff0c 但是功能参差不齐 xff0c 安全性太多没有保障 xff0c 小编也进了很多坑 xff0c 为了让您少走弯路 xff0c 今天给大家分享8款常见的ftp工具 每款都很有特色 xff0c 感兴趣的小伙
  • tftp命令怎么传输文件,5步掌握tftp命令的使用方法

    FTP让用户得以下载存放于远端主机的文件 xff0c 也能将文件上传到远端主机放置 tftp是简单的文字模式ftp程序 xff0c 它所使用的指令和FTP类似 IIS7服务器管理工具可以批量管理 定时上传下载 同步操作 数据备份 到期提醒
  • filezilla ftp设置,7步完成filezilla ftp设置

    FTP服务器 File Transfer Protocol Server 是在互联网上提供文件存储和访问服务的计算机 xff0c 它们依照FTP协议提供服务 FTP是文件传输协议 xff0c 就是专门用来传输文件的协议 这篇文章主要介绍fi
  • 8uftp无法取得目录列表,解决8uftp无法取得目录列表的问题只需4步

    最近发现自己买的香港空间出现一个很严重的问题 xff0c ftp连接时无法取得目录列表 xff0c 因为之前一直固定在一家买空间 xff0c 所以善良的我很自然的打电话给这位老朋友让他赶紧起床看一看 xff0c 当时是凌晨两点半 几分钟后
  • 大数据ftp软件,2步完成大数据ftp软件的连接与命令操作

    ftp软件是什么软件 xff0c 可能有人会回答说不知道 xff0c 因为一般只有从事网站管理的工作者会使用的多一点 但不是每个人生来就会的 xff0c 所以刚开始肯定都会学习怎么使用ftp软件 这篇文章就来告诉大家大数据ftp软件大数据f
  • PID算法控制平衡小车直立

    1 平衡小车直立控制 xff1a 如果我们要控制一根木棍在手上直立 xff0c 需要两个步骤 gt 托着木棒的手可以移动 gt 眼睛能看到木棒的倾斜角度和倾斜趋势 xff08 角速度 xff09 类比到平衡小车中 xff0c 同理想让小车保
  • 数据结构 - 链式队列

    1 链式队列 链式队列 xff1a 用链表形式实现的队列 链表结点为队列数据存储区 xff0c 链表结点包括两部分数据存储 区和指针存储区 数据存储区 xff1a 存放真实有效数据的区域 指针存储区 xff1a 存放下一个链表结点的地址 2
  • Sugar BI:如何在下钻中改变地图范围

    下钻是指在点击本图表的某一部分时 xff0c 可以打开一个新的图表或超链接 xff0c 进而查看与图表此部分相关的详细信息 Sugar BI支持无限层级的下钻 xff0c 只要下钻的弹出展示的图表也是支持下钻的 xff0c 就可以继续配置进
  • darknet_ros部署及测试

    一 darknet ros部署 1 创建ROS工作空间 span class token function mkdir span p catkin ws src span class token builtin class name cd
  • ensp 查看命令(display)

    ensp 查看命令 xff08 display xff09 span class token number 1 span display this span class token comment 查看当前配置过的命令 span span
  • 关于HTTP 和 HTTPS

    什么是http 超文本传输协议 Http xff0c HyperText Transfer Protocol 是互联网上应用最为广泛的一种网络协议 xff0c 设计Htto最初的目的是提供一种发布和接收HTML页面的方法 xff0c 他可以
  • 关于事件流的简单理解

    JS事件 1 首先 xff0c 什么是事件 xff1f JavaScript和Html发生交互是通过事件来实现的 xff0c 事件 xff0c 就是文档或浏览器窗口发生一些特定的交互的瞬间 2 什么是事件流 xff1f 事件流就是 xff0
  • Vue中引入自定义公共组件方法以及步骤

    什么是公共组件 xff0c 公共组件的使用场景 项目中如果多个页面都显示有相同的区域内容 xff0c 则该公共区域内容可以封装成公共组件进行使用 步骤 xff1a 1 创建自定义公共组件 xff0c 在src下的components目录中自
  • vue中的data为什么是一个函数

    首先 xff1a 组件是一个可复用的Vue实例 xff0c 一个组件被创建好之后 xff0c 就可能被用在各个地方 xff0c 而组件不管被复用多少次 xff0c 组件中data数据都应该是相互隔离 xff0c 互不影响的 xff0c 基于
  • Vue中key值的作用

    Vue中key值的作用 首先v for 在列表渲染时 xff0c 我们可以用v for基于一个数组来渲染一个列表 v for指令需要使用item in arr形式的特殊语法来进行渲染列表 xff0c arr是源数据 xff0c span c
  • 电商后台管理项目d01

    电商后台管理项目d01 1 项目技术栈 2 项目初始化 3 Element UI 的按需引入 4 路由配置 5 Axios 的封装 6 实现登录功能 7 完成首页部分 8 用户管理 用户列表 9 权限管理 1 角色
  • react之jsx语法规则

    希望在之后的日子里 xff0c 能够时常更新 xff01 定义虚拟DOM时 xff0c 不要写引号 标签中混入JSX表达式时 xff0c 要用 样式的类名不要用class属性 xff0c 要是用clsaaName属性 lt h1 class
  • 电子凭证文件上传

    最近 xff0c 一直在做一些关于文件上传 xff0c 以及凭证导出打印的工作 xff0c 做一些记录 xff0c 方便日后的查阅 对了 xff0c 我在这里用的是antDesign这个第三方组件 文件上传 vue模板中 lt p gt l
  • 可视化图表API格式要求有哪些?Sugar BI详细代码示例(2)

    Sugar BI中的每个图表可以对应一个数据 API xff0c 用户浏览报表时 xff0c 选定一定的过滤条件 xff0c 点击 查询 按钮将会通过 API 拉取相应的数据 xff1b 前面说过 xff0c 为了确保用户数据的安全性 xf
  • "Warning: GetWindowMenuPopup failed! "

    对mdi程序中一个弹出菜单警告原因的分析 作者 laomai 网址 http blog csdn net laomai xff08 转载时请注明出处 xff09 一 引子 最近在编译一个别人的mdi程序代码 xff0c 在调试程序时 vc6