分清几个概念

<1>“主菜单” 和 “顶层菜单” 是一个意思。

<2>主菜单中的项目叫做 “弹出菜单” 或者 “子菜单”。

<3>弹出菜单的项目能够是另外一个弹出菜单。

<4>菜单的状态:启用,禁用。无效化,无效化跟前两者的差别是灰色显示文字。

(1)菜单消息

<1>WM_INITMENU

        wParam,   // handle to menu (HMENU)
lParam // not used

<2>WM_MENUSELECT

菜单项被选中的时候

       wParam,   // menu item (UINT) and flags (UINT)
lParam //handle to menu (HMENU)

当中

LOWORD(wParam)		//被选中项目:菜单ID或者弹出式菜单句柄
HIWORD(wParam) //选择旗标
旗标是MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU和MF_MOUSESELECT的集合。

<3>WM_INITMENUPOPUP

当下拉菜单被激活的时候就会发出这种消息

WPARAM wParam,   // handle to menu (HMENU)
LPARAM lParam // item position and indicator

LOWORD(lParam)代表的是菜单项索引,HIWORD(lParam)表示的是TRUE,或者FALSE,菜单是系统菜单的时候表示的TRUE,非系统菜单的时候表示的是FALSE。

<4>WM_COMMAND

表示使用者已经从菜单中选择了一个被启用的菜单项,

LOWORD (wParam):菜单命令ID

HIWORD(wParam):0

lParam:0

<5>WM_MENUCHAR

(2)菜单项中的字母的下划线

把字母前面加&字符,就能够出现字母下划线的效果,当用Alt键+ 字符,能够快捷的弹出子菜单,或者运行菜单项命令。

相应属性

(3)菜单项的选中和去选中状态

CheckMenuItem(hMenu, iSelection, MF_UNCHECKED) ;
CheckMenuItem(hMenu, iSelection, MF_CHECKED) ;

(4)关于Menu的函数

关于菜单的操作从大体方向上看无外乎增删改查四种操作。

4.1    HMENUCreateMenu(VOID);

4.2   BOOL AppendMenu( HMENU hMenu, // handle to menu

                         UINT uFlags,                            //menu-item options

                         UINT_PTR uIDNewItem,       // identifier, menu, or submenu

                         LPCTSTR lpNewItem         //menu-item content);

当中uFlags 能够是:

MF_BITMAP。MF_OWNERDRAW,MF_STRING

演示样例:

AppendMenu         (hMenuPopup, MF_STRING, IDM_APP_EXIT,"E&xit") ;

AppendMenu         (hMenu, MF_POPUP, hMenuPopup,"&File") ;

4.3    BOOLInsertMenu(  HMENU hMenu,          // handle to menu

                         UINT uPosition,       // item that new item precedes

                         UINT uFlags,          // options

                         UINT_PTR uIDNewItem,  // identifier, menu, or submenu

                         LPCTSTR lpNewItem     // menu item content);

这个函数和AppendMenu相比除了uPosition这个參数外,其余全然同样

uPosition:表示被插的位置索引或者菜单ID,详细是哪一个取决于uFlags中是MF_BYCOMMAND还是MF_BYPOSITION。

uIDNewItem:插入项是命令项的时候表示的是ID,插入项是菜单的时候表示的菜单句柄。

lpNewItem:    插入项的内容,详细取决于uFlags中包括的MF_BITMAP。MF_STRING。MF_OWNERDRAW

注意:不能放在一起的命令组合

  • MF_BYCOMMAND and MF_BYPOSITION
  • MF_DISABLED, MF_ENABLED, and MF_GRAYED
  • MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR
  • MF_MENUBARBREAK and MF_MENUBREAK
  • MF_CHECKED and MF_UNCHECKED

4.4    BOOLInsertMenuItem(  HMENU hMenu,           // handle to menu

                UINT uItem,            // identifier or position

                BOOL fByPosition,      // meaning of uItem

                LPCMENUITEMINFO lpmii  // menu item information);

typedef struct tagMENUITEMINFO {
UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
ULONG_PTR dwItemData;
LPTSTR dwTypeData;
UINT cch;
HBITMAP hbmpItem;
} MENUITEMINFO, *LPMENUITEMINFO;

4.5   BOOL RemoveMenu(  HMENU hMenu,     // handle to menu

                UINT uPosition, // menu item identifier or position

                UINT uFlags     // options);

4.6    BOOLModifyMenu(  HMENU hMnu,           // handle to menu

                UINT uPosition,       // menu item to modify 

                   UINTuFlags,          // options

                UINT_PTR uIDNewItem,  // identifier, menu, or submenu

                 LPCTSTR lpNewItem     // menu item content);

4.7    BOOLDeleteMenu(  HMENU hMenu,     // handle to menu

                UINT uPosition,  // menu item identifier or position

                UINT uFlags      // option);

删除菜单项,假设菜单项时弹出菜单。那么就会释放菜单句柄所指向的内存。

4.7    BOOLDrawMenuBar(  HWND hWnd  // handle to window);

4.8    HMENUGetSubMenu(  HMENU hMenu,  // handle to menu

                         int nPos      // menu item position);

当菜单条发生变化时候。必须调用这个函数又一次绘制菜单//常常验证。未必

(6)右键菜单

右键菜单跟一般的菜单没什么差别。仅仅是弹出的时候。须要用到这个函数

BOOLTrackPopupMenu(  HMENU hMenu,         // handle to shortcut menu
UINT uFlags, // options
int x, // horizontal position
int y, // vertical position
int nReserved, // reserved, must be zero
HWND hWnd, // handle to owner window
CONST RECT *prcRect // ignored);

当中的uFlags參数指定了菜单中菜单中的对齐方式,左键右键选定菜单项

TPM_CENTERALIGN。TMP_LEFTALIGN。TMP_RIGHTALIGN

TPM_BOTTOMALIGN, TPM_TOPALIGN, TPM_VCENTERALIGN

TPM_LEFTBUTTPON,TPM_RIGHTBUTTON

TPM_NONOTIFY, TPM_RETURNCMD

(7)系统菜单

获取系统菜单句柄

HMENU GetSystemMenu(

HWNDhWnd,    // handle to window

BOOL bRevert  // reset option);

当中bRevert = FALSE时候。表示。复制系统的菜单,而且返回复制菜单的句柄,这个菜单能够进行改动。当bRevert = TRUE 时,设置系统菜单为默认的原始状态。而且函数返回值是NULL.

(8) 加速键

加速键也是一种资源,它能够使用快捷键迅速的打开命令项。加速键 能够在在资源中自己加入,也能够直接使用程序编写。

加速键中基本的改变的code有

while(GetMessage(&msg,NULL,0,0))

{

if (!TranslateAccelerator(hWnd,hAccel,&msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

在这里 TranslateAccelerator函数把 一些按键消息翻译成WM_COMMAND,或者WM_SYSCOMMAND消息。

(9)代码演示样例

一下演示样例是一个全然依靠code不依赖创建资源的菜单demo,当中包括菜单条。右键菜单,系统菜单,加速键能够对菜单进行动态的改动,删除。加入操作。

#define OEMRESOURCE
# include<Windows.h> #define IDM_FILE_OPEN 100
#define IDM_FILE_NEW 101
#define IDM_FILE_PIC 102
#define IDM_FILE_EXIT 103
#define IDM_MENU_ADD 104
#define IDM_MENU_REM 105
#define IDM_MENU_DEL 106
#define IDM_MENU_MOD 107
#define IDM_ABOUT 108
#define IDM_VERSION 109
#define IDM_MENU_NEW 110 #define IDM_POP_ONE 200
#define IDM_POP_TWO 201 #define IDM_SYS_ONE 300
#define IDM_SYS_TWO 301 LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
HMENU createOwnMenu(HWND hwnd);
HMENU createPopMenu(HWND hwnd);
HACCEL createAccelerator(HWND hwnd);
TCHAR* szAppName = TEXT("MenuClass");
TCHAR* szWndName = TEXT("ChangeMenu");
HACCEL hAccel = NULL; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int iCmdShow)
{
WNDCLASS wndCls;
HWND hWnd;
MSG msg; wndCls.cbClsExtra = 0;
wndCls.cbWndExtra = 0;
wndCls.lpfnWndProc = WndProc;
wndCls.style = CS_HREDRAW | CS_VREDRAW;
wndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndCls.hCursor = LoadCursor(NULL,IDC_ARROW);
wndCls.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndCls.hInstance = hInstance;
wndCls.lpszClassName = szAppName;
wndCls.lpszMenuName = NULL; if(!RegisterClass(&wndCls))
{
MessageBox(NULL,TEXT("Register window failed"),TEXT("Error"),MB_OK);
} hWnd = CreateWindow(szAppName,szWndName,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL); UpdateWindow(hWnd);
ShowWindow(hWnd,SW_NORMAL); while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(hWnd,hAccel,&msg))
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
static int nAdd = 1;
HMENU hMenu,hSonMenu,hTmpMenu;
HMENU hTrack,hSon;
HMENU hSysMenu;
POINT pt; switch(msg)
{
case WM_CREATE:
hMenu = createOwnMenu(hwnd);
SetMenu(hwnd,hMenu);
hSysMenu = GetSystemMenu(hwnd,FALSE);
AppendMenu(hSysMenu,MF_SEPARATOR,0,NULL);
AppendMenu(hSysMenu,MF_STRING,IDM_SYS_ONE,TEXT("SysOne"));
AppendMenu(hSysMenu,MF_STRING,IDM_SYS_TWO,TEXT("SysTwo"));
hAccel = createAccelerator(hwnd);
break;
case WM_SYSCOMMAND:
switch(LOWORD(wParam))
{
case IDM_SYS_ONE:
MessageBox(NULL,TEXT("This is added system menu item1"),NULL,MB_OK);
break;
case IDM_SYS_TWO:
MessageBox(NULL,TEXT("This is added system menu item2"),NULL,MB_OK);
break;
}
break;
case WM_COMMAND:
hMenu = GetMenu(hwnd);
switch(LOWORD(wParam))
{
case IDM_FILE_OPEN:
MessageBox(NULL,TEXT("File Open selected"),TEXT("Test check"),MB_OK);
break;
case IDM_MENU_ADD:
hTmpMenu = GetSubMenu(hMenu,2);
AppendMenu(hTmpMenu,MF_STRING,IDM_MENU_NEW+nAdd,TEXT("New Item"));
nAdd++;
DrawMenuBar(hwnd);
break;
case IDM_MENU_REM:
hTmpMenu = GetSubMenu(hMenu,2);
if( nAdd >1 )
{
nAdd--;
RemoveMenu(hTmpMenu,IDM_MENU_NEW+nAdd,MF_BYCOMMAND);
}
// 当菜单项时弹出菜单的时候,只切断弹出菜单跟所属菜单的联系,但不销毁对象
/*GetSubMenu(hTmpMenu,2);
RemoveMenu(hTmpMenu,2,MF_BYPOSITION);*/
DrawMenuBar(hwnd);
break;
case IDM_MENU_MOD:
hTmpMenu = GetSubMenu(hMenu,2);
ModifyMenu(hTmpMenu,0,MF_BYPOSITION,IDM_ABOUT,TEXT("Modified Item"));
DrawMenuBar(hwnd);
break;
case IDM_MENU_DEL:
hTmpMenu = GetSubMenu(hMenu,2);
DeleteMenu(hTmpMenu,2,MF_BYPOSITION);
DrawMenuBar(hwnd);
break;
}
break;
case WM_RBUTTONDOWN:
hTrack = createPopMenu(hwnd);
hSon = GetSubMenu(hTrack,0);
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ClientToScreen(hwnd,&pt);
TrackPopupMenu(hSon,TPM_LEFTBUTTON| TPM_RIGHTALIGN,pt.x,pt.y,0,hwnd,NULL);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
} return DefWindowProc(hwnd,msg,wParam,lParam);
} HMENU createOwnMenu(HWND hwnd)
{
HMENU hMenu = CreateMenu();
HMENU hPopMenu = CreateMenu();
//MF_BYPOSIOTION,MF_BYCOMMAND is not useful here in AppendMenu
AppendMenu(hPopMenu,MF_STRING|MF_CHECKED|MF_GRAYED,IDM_FILE_OPEN,TEXT("&Open"));
InsertMenu(hPopMenu,0,MF_BYPOSITION|MF_STRING|MF_DISABLED,IDM_FILE_NEW,TEXT("&New")); HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
HBITMAP hBmp = (HBITMAP)LoadImage(hInstance,TEXT("bitmap1.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
AppendMenu(hPopMenu,MF_BITMAP,IDM_FILE_PIC,(LPCWSTR)hBmp);
AppendMenu(hPopMenu,MF_SEPARATOR,NULL,NULL);
AppendMenu(hPopMenu,MF_STRING,IDM_FILE_EXIT,TEXT("&Exit"));
SetMenuItemBitmaps(hPopMenu,IDM_FILE_PIC,MF_BYCOMMAND,hBmp,hBmp);
AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("File")); hPopMenu = CreateMenu();
AppendMenu(hPopMenu,MF_STRING,IDM_MENU_ADD,TEXT("&Add"));
AppendMenu(hPopMenu,MF_STRING,IDM_MENU_REM,TEXT("&Remove"));
AppendMenu(hPopMenu,MF_STRING,IDM_MENU_MOD,TEXT("&Modify"));
AppendMenu(hPopMenu,MF_STRING,IDM_MENU_DEL,TEXT("&Delete"));
AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("Menu")); hPopMenu = CreateMenu();
AppendMenu(hPopMenu,MF_STRING,IDM_ABOUT,TEXT("About"));
AppendMenu(hPopMenu,MF_STRING,IDM_VERSION,TEXT("Version"));
HMENU hSonMenu = CreateMenu();
AppendMenu(hSonMenu,MF_STRING,IDM_MENU_NEW,TEXT("Son"));
AppendMenu(hPopMenu,MF_POPUP,(UINT_PTR)hSonMenu,TEXT("Son Menu"));
AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("Change")); return hMenu;
} HMENU createPopMenu(HWND hwnd)
{
HMENU hMenu = CreateMenu();
HMENU hPop = CreateMenu();
AppendMenu(hPop,MF_STRING,IDM_POP_ONE,TEXT("One"));
AppendMenu(hPop,MF_STRING,IDM_POP_TWO,TEXT("Twod")); AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPop,TEXT("Pop"));
return hMenu; } HACCEL createAccelerator(HWND hwnd)
{
ACCEL acce[2];
acce[0].fVirt = FCONTROL | FNOINVERT | FVIRTKEY;
acce[0].key = 'A';
acce[0].cmd = IDM_MENU_ADD;
acce[1].fVirt = FCONTROL | FNOINVERT | FVIRTKEY;
acce[1].key = 'R';
acce[1].cmd = IDM_MENU_REM; HACCEL hAccel = CreateAcceleratorTable(acce,2);
return hAccel;
}

windows编程之菜单操作的更多相关文章

  1. Windows编程中各种操作文件的方法

    windows编程中文件操作有以下几种常见方法:1.C语言中文件操作.2.C++语言中的文件操作.3.Win32 API函数文件操作.4.MFC CFile类文件操作.5.MFC CFileDialo ...

  2. 资源在windows编程中的应用----菜单

    资源在Windows编程中的应用 资源 加速键.位图.光标.对话框.菜单.字符串.工具条 1.菜单的创建 菜单由以下组成部分: (1)窗口主菜单条 (2)下拉式菜单框 (3)菜单项热键标识 (4)菜单 ...

  3. 【C语言/C++编程学习笔记】你的第一个Windows程序!高级操作~

    什么是windows编程?了解到Windows API 编程.Windows编程.Windows SDK 编程是一个概念.今天我们运用C语言来实现你的第一个真正的Windows程序. windows. ...

  4. 【Windows编程】系列第六篇:创建Toolbar与Statusbar

    上一篇我们学习了解了如何使用Windows GDI画图,该应用程序都是光光的静态窗口,我们使用Windows应用程序,但凡稍微复杂一点的程序都会有工具栏和状态栏,工具栏主要用于一些快捷功能按钮.比如典 ...

  5. 【Windows编程】系列第十一篇:多文档界面框架

    前面我们所举的例子中都是单文档界面框架,也就是说这个窗口里面的客户区就是一个文档界面,可以编写程序在里面输入或者绘制文本和图形输出,但是不能有出现多个文档的情况.比如下面的UltraEdit就是一个典 ...

  6. 【Windows编程】系列第八篇:通用对话框

    上一篇我们学习了菜单的基本编程,本篇来了解一下通用对话框的使用.Windows系统之所以是目前最流行的桌面系统,也是因为Windows有一套标准化,统一友好的交互界面,比如菜单.工具栏.状态栏以及各个 ...

  7. MFC-01-Chapter01:Hello,MFC---1.1 Windows 编程模型

    1.1 Windows编程模型 为传统的操作系统编写的程序使用的是过程化模型,即程序从头到尾按顺序执行.例如C程序,从main函数入口开始执行,中间调用不同的函数一直到程序结束返回,这种过程是程序本身 ...

  8. Direct3D 10学习笔记(四)——Windows编程

    本篇将简单整理基本的Windows应用程序的实现,并作为创建Direct3D 10应用程序的铺垫.具体内容参照< Introduction to 3D Game Programming with ...

  9. Windows编程基础

    主要内容:介绍Windows编程的一些基础概念 1.窗口的概念 <1>一个应用程序的窗口通常包括控制菜单框.下拉菜单. 工作区以及最大化按钮.最小化按钮, 还有垂直滚动条.水平滚动条 &l ...

随机推荐

  1. JIRA官方:JIRA亮点介绍

    操作超级简单 简单不意味着要以牺牲功能作为代价.JIRA提供了友好.直观的可配置的Web界面,并支持大量的快捷键操作. 跟踪任何事务 跟踪问题.任务.需求,当然还有软件缺陷.定义你自己的事务类型来使之 ...

  2. linux之SQL语句简明教程---UNION

    UNION 指令的目的是将两个 SQL 语句的结果合并起来.从这个角度来看, UNION 跟 JOIN有些许类似,因为这两个指令都可以由多个表格中撷取资料. UNION 的一个限制是两个 SQL 语句 ...

  3. 2.x ESL第二章习题2.5

    题目 描述 $y_i=x_i^T\beta+\epsilon_i$$\epsilon_i\sim N(0,\sigma^2)$ 已有训练集$\tau$,其中$X:n\times p,y:n\times ...

  4. 【概率论】【POJ 3682】【King Arthur's Birthday Celebration】

    题意:进行翻硬币实验,若k次向上则结束,进行第n次实验需花费2*n-1的费用,询问期望结束次数及期望结束费用 设F[i]为第i次结束时的概率 F[i]=  c(i-1,k-1)*p^k*(1-p)^( ...

  5. 线上应用故障排查之一:高CPU占用

    一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hank ...

  6. Asp.Net Web API 2

    Asp.Net Web API 2第十八课——Working with Entity Relations in OData   前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导 ...

  7. ipa 重签

    IPA 重签名 时间 2014-03-03 10:28:36  txx's blog原文  http://blog.rpplusplus.me/blog/2014/03/03/ipa-re-codes ...

  8. c#创建带参数的线程

    1.无参数线程的创建 Thread thread = new Thread(new ThreadStart(getpic)); thread.Start(); private void showmes ...

  9. Android Studio 项目目录结构 英文版

    I don't know if this is because of the Gradle Build System (I'd wager it is), but I'll tell you what ...

  10. 【学习笔记01】:hover为DIV添加鼠标悬停时改变颜色的效果

    :hover所有主流浏览器都支持(IE6.0以下支持不好,以后再学习用Javascript来实现悬停效果) 这是一个绿色底白色Icon的搜索按钮