目录

第1章 Windows菜单    1

1.1 窗口菜单和弹出菜单    1

1.2 使用SetMenu    2

1.3 使用TrackPopupMenu    4

第1章 Windows菜单

1.1 窗口菜单和弹出菜单

Windows菜单分为两类:窗口菜单和弹出菜单。窗口菜单主要用来放在某个窗口上。弹出菜单有两个作用,一是鼠标右键单击时显示的菜单;二是作为子菜单添加到窗口菜单。

打开"记事本"程序,右键菜单就是一个弹出菜单:

图1.1 弹出菜单

"记事本"程序的菜单栏部分就是一个窗口菜单,它又包含了"文件""编辑"……这些弹出菜单。

图1.2 窗口菜单

窗口菜单由CreateMenu创建,使用SetMenu将其设置到某个窗口,使用DestroyMenu销毁。

弹出菜单由CreatePopupMenu创建,使用AppendMenu或InsertMenuItem将其添加到窗口菜单或上一级弹出菜单,也可以使用TrackPopupMenu显示弹出菜单。弹出菜单的销毁同样是调用DestroyMenu函数。

1.2 使用SetMenu

下面以代码的方式创建图1.2所示的窗口菜单:

//创建窗口菜单

HMENU hMenuWnd = ::CreateMenu();

{//创建"文件"弹出菜单,并将其添加到窗口菜单

//创建"文件"菜单,这是一个弹出菜单

HMENU hMenuFile = ::CreatePopupMenu();

//给"文件"菜单添加"新建"菜单项,0x8000是菜单项ID号

::AppendMenu(hMenuFile,MF_STRING,0x8000,_T("新建"));

//给"文件"菜单添加"打开"菜单项

::AppendMenu(hMenuFile,MF_STRING,0x8001,_T("打开"));

//给"文件"菜单添加一条分隔线

::AppendMenu(hMenuFile,MF_SEPARATOR,0,NULL);

//继续给"文件"菜单添加菜单项

... ... ... ...

//将整个"文件"菜单添加到窗口菜单

::AppendMenu(hMenuWnd,MF_POPUP,(UINT)hMenuFile,_T("文件"));

}

{//创建"编辑"弹出菜单,并将其添加到窗口菜单

//创建"编辑"菜单,这是一个弹出菜单

HMENU hMenuEdit = ::CreatePopupMenu();

//给"编辑"菜单添加菜单项

... ... ... ...

//将整个"编辑"菜单添加到窗口菜单

::AppendMenu(hMenuWnd,MF_POPUP,(UINT)hMenuEdit,_T("编辑"));

}

{//创建"格式"弹出菜单,并将其添加到窗口菜单

... ... ... ...

}

{//创建"查看"弹出菜单,并将其添加到窗口菜单

... ... ... ...

}

{//创建"帮助"弹出菜单,并将其添加到窗口菜单

... ... ... ...

}

//将窗口菜单设置到窗口上

::SetMenu(hWnd,hMenuWnd);

代码说明:

1、SetMenu的第二个参数必须是窗口菜单句柄,即这个句柄必须由CreateMenu函数创建,而不能是CreatePopupMenu创建的弹出菜单句柄。

2、::AppendMenu(hMenuWnd,MF_POPUP,(UINT)hMenuFile,_T("文件"));将弹出菜单hMenuFile添加到窗口菜单hMenuWnd。它只是把hMenuFile这个句柄添加到hMenuWnd所维护的数据结构里,即它添加的只是弹出菜单的一个引用,并不是把弹出菜单的所有菜单项添加到窗口菜单。因此,可以先将hMenuFile添加到hMenuWnd,再给hMenuFile添加菜单项,如下面的代码所示:

{//创建"文件"弹出菜单,并将其添加到窗口菜单

//创建"文件"菜单,这是一个弹出菜单

HMENU hMenuFile = ::CreatePopupMenu();

//将整个"文件"菜单添加到窗口菜单

::AppendMenu(hMenuWnd,MF_POPUP,(UINT)hMenuFile,_T("文件"));

//给"文件"菜单添加"新建"菜单项,0x8000是菜单项ID号

::AppendMenu(hMenuFile,MF_STRING,0x8000,_T("新建"));

... ... ... ...

}

3、DestroyMenu(hMenuWnd)将销毁它的子菜单、孙菜单。也就是说执行DestroyMenu(hMenuWnd)之后,hMenuFile、hMenuEdit……也被销毁了。上面的代码里,在::SetMenu(hWnd,hMenuWnd);之前增加如下测试代码:

DestroyMenu(hMenuWnd);

hMenuWnd = ::CreateMenu();

::AppendMenu(hMenuWnd,MF_POPUP,(UINT)hMenuFile,_T("文件"));

DestroyMenu(hMenuWnd);将销毁hMenuWnd和hMenuFile,所以AppendMenu将会增加无效的hMenuFile给hMenuWnd。可以想象,"文件"菜单里是不会有菜单项的。

4、何时调用DestroyMenu(hMenuWnd)销毁窗口菜单呢?应该是不再使用时销毁,具体的就是在处理窗口的WM_DESTROY消息时销毁,或者在SetMenu更换菜单后销毁。

1.3 使用TrackPopupMenu

上一节的代码里包含了弹出菜单的创建,并增加到窗口菜单。弹出菜单还有一个作用就是用来显示图1.1所示的右键弹出菜单,方法就是调用TrackPopupMenu函数。需要注意的是:TrackPopupMenu的第一个参数必须是一个弹出菜单的句柄,就是说它必须由CreatePopupMenu创建。

以上一节的代码为例:

//可以显示出弹出菜单

TrackPopupMenu(hMenuFile,...);

//无法显示弹出菜单,因为hMenuWnd是一个窗口菜单,不是弹出菜单

TrackPopupMenu(hMenuWnd,...);

//GetSubMenu(hMenuWnd,0) 返回的其实就是hMenuFile

//因此下面的代码可以正常显示弹出菜单

TrackPopupMenu(GetSubMenu(hMenuWnd,0),...);

当使用LoadMenu从资源里载入菜单时,其返回的是一个窗口菜单句柄,直接传递给TrackPopupMenu是无法正常显示的。必须使用GetSubMenu获得窗口菜单里的弹出菜单句柄,才能正常调用TrackPopupMenu。

执行TrackPopupMenu之后,可以立即调用DestroyMenu销毁菜单。

Windows菜单的更多相关文章

  1. eclipse安装ADT后在windows菜单下找不到android SDK and AVD Manager

    eclipse安装ADT后在windows菜单下找不到android SDK and AVD Manager选项的解决办法 - zhjr1220的专栏 - 博客频道 - CSDN.NET  http: ...

  2. ADT后windows菜单未找到Android SDK Manager和Android Virtual Device Manager该解决方案的选择

    打开今天凌晨ADT准备编译androidproject的时候,突然发现windows菜单下的Android SDK Manager和Android Virtual Device Manager选项不见 ...

  3. eclipse安装ADT后在windows菜单下找不到android SDK and AVD Manager选项的解决办法

    在eclipse中点击window→Customize Perspective→Command Groups availability→Available command groups下勾选Andro ...

  4. WIN 下的超动态菜单(三)代码

    WIN 下的超动态菜单(一)简介 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/ 超动态 ...

  5. WIN 下的超动态菜单(二)用法

    WIN 下的超动态菜单(一)简介 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/     ...

  6. 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!

    今年微软Build 2016大会最让开发人员兴奋的消息之一,就是在Windows上可以原生运行Linux bash,对开发人员来说,这是一个喜闻乐见的消息. 1 安装 你必须安装开发者预览版本,才能使 ...

  7. 重新安装配置ubuntu的引导菜单

     查看分区挂在情况,找到ubuntu所在分区(boot)$sudo fdisk   -l   卸载isodevice镜像设备所在盘分区(boot) $sudo  umount  -l  /isodev ...

  8. Playmaker Input篇教程之PlayMaker菜单概述

    Playmaker Input篇教程之PlayMaker菜单概述 Playmaker InputPlayMaker菜单概述 Playmaker插件被导入游戏项目以后,会自动为Unity编辑器添加一个名 ...

  9. Windows API 的数据类型与 Delphi 数据类型对照表

    Windows 数据类型 Delphi 数据类型 描述 LPSTR PAnsiChar 字符串指针 LPCSTR PAnsiChar 字符串指针 DWORD LongWord 整数 BOOL Long ...

随机推荐

  1. Android启动Activity的两种方式与四种启动模式

    1.在一个Activity中调用startActivity()方法 2.在一个Activity中调用startActivityRequest()方法. 重写onActivityResult方法,用来接 ...

  2. 列出本机JCE提供者,支持消息摘要算法,支持公钥私钥算法

    import java.security.Provider; import java.security.Security; public class TestBouncyCastle { public ...

  3. anroid

    http://mirrors.neusoft.edu.cn/more.we#android http://www.cnblogs.com/youxilua/archive/2013/05/20/308 ...

  4. DEBUG模式开关

    在.NET中,有一个特殊的特性可以用:[Conditional("DEBUG")]MyConstructor(IExtensionManager mgr){...}

  5. Zabbix监控交换机设置

    说明: Zabbix监控服务端已经配置完成,现在要使用Zabbix对交换机进行监控. 具体操作: 以下操作在被监控的交换机上进行,这里以Cisco交换机为例. 一.登录到Cisco交换机,开启snmp ...

  6. 关于float的感悟

    给元素设置了float样式后,最终的结果是: 1:这个元素漂浮起来, 2:其他的元素位置可以视为 这个元素不存在 的时候的位置:但是float样式还是对整个页面有所影响 3:float的影响就是他附近 ...

  7. [UVa1213]Sum of Different Primes(递推,01背包)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  8. [HDOJ3718]Similarity(KM算法,二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3718 题意:有一堆答题情况和正确答案,问每一个答题情况的正确率最大是多少. 给每一对答案和答题情况的字 ...

  9. linux留下后门的技巧

    在团队内部的wiki上已经写出 http://drops.wooyun.org/tips/1951 http://www.freebuf.com/sectool/10474.html 还有一种方法是写 ...

  10. poj 3304线段与直线相交

    http://poj.org/problem?id=3304 Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: ...