目录

第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. C#中的异步和同步

    同步 同步(英语:Synchronization [ˌsɪŋkrənaɪ'zeɪʃn]),指对在一个系统中所发生的事件(event)之间进行协调,在时间上出现一致性与统一化的现象.说白了就是多个任务一 ...

  2. c++中两种常量方法的比较

    [c++]在C++中定义常量的两种方法的比较   常量是定以后,在程序运行中不能被改变的标识符.C++中定义常量可以用#define .const 这两种方法.例如: #define PRICE 10 ...

  3. android 入门 004 (同一个方法,点击实现不同的效果)

    同一个方法,点击实现不同的效果 <Button android:id="@+id/btn3" android:layout_width="wrap_content& ...

  4. 扩展duilib edit控件的提示功能和多种文字颜色(解决edit为password显示不正常的bug)

    参考博客:Redrain 转载:http://blog.csdn.net/zhuhongshu/article/details/41786407 在Redrain博客的基础上做了修改 1.CEditU ...

  5. iOS静态库和动态库的区别

    一.什么是库? 库是共享程序代码的方式,一般分为静态库和动态库. 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用 ...

  6. CentOS7安装Docker,运行Nginx镜像、Centos镜像

    摘要 总体思路:yum命令直接安装Docker,下载想要的镜像并启动 1.环境,CentOS7 Minimal 64位,Docker必须要64位的系统 2.通过yum命令直接安装,yum instal ...

  7. js模拟表单提交

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. Android Studio 初级安装

    最近学习安卓,很多教程都说Android Studio 好用,于是下一个来看看. 1.在安装这个工具之前需要先安装 JDK 我的环境是win7-64位. 提供一个下载地址:http://pan.bai ...

  9. Javascript this指针

    Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.   前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对 ...

  10. JavaScript经典代码【一】【javascript HTML控件获取值】

    javascript HTML控件获取值 1.下拉列表框选定值 ddlPageSize.options[ddlPageSize.selectedIndex].value ddlPageSize.opt ...