VC++菜单的句柄是不是就是菜单的ID

VC++菜单的句柄是不是就是菜单的ID,第1张

VC++菜单的句柄也可以理解成菜单的识别符(ID) 但如果指菜单项的ID, 那可能又是一回事了。按我的理解:

1 句柄是程序运行中系统为其分配的,菜单项ID是编程者自己定义指定的。一般可在资源文件中定义也可在动态创建菜单时指定,程序中引用。

2 菜单的句柄是属于菜单的,菜单项ID是属于菜单中某一个菜单项的。编程者通过菜单的句柄访问菜单,通过ID进行菜单项识别并进行消息处理。

3 菜单的句柄类型是HMENU, 菜单项ID的类型是UINT(无符号整型)。当然这两种类型本质上并无差别,但编程者一般不混用。当然不排除强制类型转换,如有(HMENU)id

4 如果某菜单项是子菜单或下拉菜单,则动态创建插入该菜单项时, 子菜单或下拉菜单的句柄用作该菜单项的ID 这时则有(UINT)hSubMenu的用法。

曾经在一些书上看到用C语言实现动态菜单的方法 需要调用大量的API函数 但是这里我想换一种方法 借助PowerBuilder提供的属性和递归算法实现动态菜单的创建过程 需要指出的是 这里讨论的动态菜单是已经在外部数据源中定义好菜单结构 而菜单对象没有有任何菜单项 需要由程序生成各个定义好的菜单项

一 定义菜单数据结构

实现动态菜单 首先设计合理的菜单数据结构 其数据源可以是任何DBMS 甚至可以是TXT文本文件(只要能建立好合理的分层结构)

菜单如同一个树形控件 有着分层的顺序结构 所以在定义数据结构时 应当选择一种能够形象地表示父子 兄弟关系的模型 而能够最好反映菜单结构的控件就是树形控件 treeview 并且定义按照二位递进的数据结构形式 即 以级别确定层数 以序号确定兄弟关系 以二位递进确定父子关系 例如 如图所示的菜单的对应数据结构如下

这样的菜单结构 在建立菜单结构时 非常适合用递归的算法 那么我们可以按照树的遍历算法建立一个树形结构的菜单对象

接下来 定义菜单数据结构 菜单数据结构应当包含以下基本元素 菜单名 菜单类型 菜单序号 菜单项文本 菜单项id 菜单项的执行代码 菜单显示风格 如下表说明

二 动态创建菜单

流程图

流程说明

如上图 整个建立菜单的过程分成两部分 初始化菜单和设置菜单属性 初始化菜单即是以递归的算法从数据源中读取菜单数据 每读一个菜单项建立一个菜单项对象 利用powerbuilder中create方法一级一级建立菜单 首先定义一个菜单实例对象 这里的菜单是指主菜单 而不是d出菜单 由于而者的区别 对于d出菜单的处理在后面介绍 菜单建立的核心原理很简单 只有四句 创建菜单对象 挂接菜单项目 先隐藏后显示菜单对象 如下

integer      ai_item_serial_no     //序号 作为递归的函数传入参数 menu    am_obj        //菜单对象 作为递归的函数传入参数  m_menu_item   lam_root       //菜单对象 m_menu_item是预先定义的一//个菜单对象 该对象没有一个菜单项 //创建菜单对象 lam_root item[ai_item_serial_no] = create m_menu_item  //将新建的菜单对象 挂接到已有菜单对象上am_obj = lam_root item[ai_item_serial_no] //下面两句用于显示建立好的菜单 lam_root Hide()      //隐藏菜单对象  lam_root Show()      //显示菜单对象

将上面的语句放在一个递归过程中 就可以建立起整个的菜单结构        

在建立菜单的过程中需要得到菜单的itemid 该属性是用来捕获菜单响应动作的唯一标示 只有知道的菜单的itemid 才知道是触发了哪个菜单项的事件

得到菜单项itemid的方法 在不同系统经过反复测试之后 发现一个规律 父项菜单的itemid是从 开始依次递增 子项菜单的itemid是从 开始依次递增 由此按照递归算法 生成每层每个菜单项的itemid 并存入数据库中

设置菜单显示风格 是在菜单建立后设置三种显示风格 文字风格 风格 文字混合的显示方式 为了提高效率 在设置每个菜单风格时 不对所有父项菜单 不可视菜单项和没有定义显示的菜单项进行设置 因为文字风格是默认风格不必更改 这部分程序员主要用到三个API函数

Getsubmenu 用于得到指定菜单项的句柄 SetMenuItemBitmaps 用于设置文字显示风格或设置风格 两种情况的区别在于该函数的最后两位若为 则是去掉菜单项上的位图 最后两位若是句柄 则是在菜单项上添加位图 ModifyMenu 用于设置显示风格

经过反复测试 发现如果指定的显示名为 bmp 等不合法名称 则显示出的效果是一个分割符

在整个菜单建立过程 需要重点设计的是程序算法 数据存取的方式和出错控制

) 程序算法主要指递归算法 一般递归有两种算法 即FOR循环的方法和DO…while循环方法 两者都是循环算法 但是效率不同 建议用户根据自己的能力选择方法 切忌不能写成死循环 For循环的方式比较简单直观 循环控制遍历的次数 循环内再调用本身 实现递归调用 DO…while循环方法主要在循环内判断叶子或枝子(即父亲节点) 对叶子和枝子进行分别处理 内部也要调用本身 实现递归调用

) 选择合理安全的数据存取方式 对于稳定建立菜单也很重要 定义一个datastore(数据存储)对象 在初始化菜单时候 将从数据库中提取的所有数据存入该datastore对象 然后不再对数据库进行任何 *** 作 直到需要结束时将变更的菜单数据(如 itemid)以datastore的update形式提交数据库 在此之前所有需要从datastore得到的数据 用过滤的方式得到 即用setfilter()和filter()函数 一定要注意的是 按照结对编程的规则 在过滤并使用完datastore中数据后 一定再写一对过滤条件为空字符串的过滤 如下 setfilter( 条件 )filter()……处理过程……setfilter( )filter()

这样也可以将数据及时还原到初始状态 以便下一个模块调用

利用datastore 既可以保持在菜单建立期间的数据安全 不受数据库影响 又可以提高效率 省去对数据库的反复读写 *** 作

) 因为菜单的重要性 使得出错控制在菜单建立尤为重要 我们在递归建立菜单时 要考虑尽可能多的潜在错误 谁也不能保证数据库中的菜单结构数据不出错 虽然正确定义不是建立模块的事 尤其菜单的二位递进的分层数据结构 若有一处错误 可能导致整个建立过程失败 更糟糕的会发生程序异常退出 所以程序在设计出错处理时 应当考虑是终止进程 还是跳过错误的环节继续进行 我建议 在设计程序时应但兼具一定的冗余度和纠错能力 即遇到错误的数据能够根据环境修正为正确的值 对于可以忽略的一些小问题 为提高效率不作处理

需要指出的是 经过反复测试 发现对于菜单的属性 如果是字符类型则不能赋空值 如果没有应当是空字符串 如果是整数类型也不能赋空值 如果没有应当是某个缺省整数 否则程序会报异常错误 然后退出

由此可见 反复测试是非常重要的 不仅能发现语法错误和确保算法的正确 更能找出许多我们难以推断的错误

三 对d出菜单的特殊处理

由于d出菜单的对象定义和调用方式与主菜单的不同 需要进行一些特殊处理 首先定义一个菜单实例对象 该对象需有且只有一个根菜单 所有d出的菜单项都挂接在根菜单项后 要在窗口的鼠标右键事件中 调用d出菜单 而主菜单则在窗口初始化事件调用 调用d出菜单之前需要知道d出点的X Y坐标 然后用popmenu()函数显示出来

四 菜单响应事件的处理

由于菜单的响应事件在数据结构中定义好了 在建立菜单之后 用户点击某菜单时候 只需要获得菜单的句柄 就知道是触发了哪个菜单 而后在数据库中找到对应的事件定义 就可以开始执行动作了 重要的是句柄如何得到 菜单的句柄就是itemid 在菜单所在窗口定义一个自定义事件 ue_mouse_clicked EVENT_ID pbm_menuselect 此事件中有两个参数可用 itemid和flag itemid即被触发菜单对象的句柄 flag是对应于windows消息号的标志 当此标志不等于 时就是触发了菜单事件 所以我们可以定义一个实例变量 保存itemid 就可以调用菜单事件了 还有一个关键问题 何时触发事件ue_mouse_clicked呢 在用户定义的菜单实例对象的clicked事件中写以下代码 if  Isvalid(iw_win)  thenmessage StringParm = this is_ItemID   //将itemid作为消息传递 iw_win postEvent( ue_menuitemclicked ) //触发窗口事件 处理消息end ifiw_win 定义的窗口实例变量is_ItemID 用以保存菜单itemid的字符串类型的实例变量postEvent 是把响应处理放在菜单事件的最后 以免妨碍之前定义的动作

lishixinzhi/Article/program/SQL/201311/16396

对一个窗口hwnd的一个菜单menu的每一个 菜单项 都有一个编号就是索引号。它是按照在菜单中的位置从0开始编号的。。。

你有自己创建好了的菜单(资源文件里),你就可以自己数一下它的位置即索引号就是那个nPos参数

vs把菜单项名设置成id_start步骤如下:

1、在vs顶部菜单中依次选择:工具-自定义。

2、这里要添加文件的右键菜单,因此在打开的窗口中依次选择:命令-上下文菜单。

3、点击添加命令,在打开的窗口中,选择工具-外部命令4。

4、最后自己设置名称。

以上就是关于VC++菜单的句柄是不是就是菜单的ID全部的内容,包括:VC++菜单的句柄是不是就是菜单的ID、在PowerBuilder中实现动态菜单的方法、WINDOWS SDK中GetMenuItemID函数第二个参数是如何确定的,譬如我想获取菜单栏中第一个菜单项的第一菜单子项等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10145175.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存