原文来自:http://hi.baidu.com/donghaozheng/blog/item/2165c3112f5c8d17b8127bc7.html
stuido 2008
New Project -- Other languages-- virual c++ -- Smart Device-- Win32 Smart Device Project
生成的工程模型比较简洁,下方menu bar 左边是一个用来退出程序的soft key,右边是一个菜单。
牵扯到的知识点:
1. 下方那个叫做MenuBar,但不要理解成字面上的,实质上它上面既可以放软键,也可以放菜单。
用SHCreateMenuBar 来创建MenuBar,摘录小段代码:
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.nToolBarId = IDR_MENU;
mbi.hInstRes = g_hInst;
if (!SHCreateMenuBar(&mbi))
{
g_hWndMenuBar = NULL;
}
else
{
g_hWndMenuBar = mbi.hwndMB;
}
2. 工程里有个以rc2后缀的文件,也是工程的资源文件, 用于VC++不能直接进行编辑的资源,以及被多个工程使用的资源。这个文件中的资源不能在VC的集成环境下直接进行编辑和修改, 而是由我们自己根据需要手工地编辑这个文件。
这里生成的rc2文件就是定义了SHMenuBar的资源。
//
// SHMENUBAR
//
IDR_MENU SHMENUBAR DISCARDABLE //资源类型(实际就是RCDATA)
BEGIN
IDR_MENU, //菜单资源的ID,因为不同的资源类型ID可以相同,系统这里用了与SHMENUBAR 相同的ID。
2,//MenuBar上按钮或菜单数目
I_IMAGENONE, IDM_OK, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,
IDS_OK, 0, NOMENU,
I_IMAGENONE, IDM_HELP, TBSTATE_ENABLED, TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE,
IDS_HELP, 0, 0,//最后这个数字是对应的菜单资源的菜单项的序号(0代表一个菜单项)
END
一般来说,WM建议左边键是一个常用的操作,右边键是菜单。所以默认生成的也正是这种模式。
两边都是菜单一般不会用,太不友好,如果两边都想是按钮,可以如下改:
IDR_MENU SHMENUBAR DISCARDABLE
BEGIN
0,
2,
I_IMAGENONE, IDM_OK, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,
IDS_OK, 0, NOMENU,
I_IMAGENONE, IDM_HELP, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,
IDS_HELP, 0, NOMENU,
END
在消息处理函数里,处理WM_COMMAND消息,来处理不同的按键。
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
break;
case IDM_OK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
3.可以通过参数设置,来通过不同方式或者完成不同效果的MenuBar
//set up menu bar structure
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hDlg;
mbi.hInstRes = g_hInst;
switch(g_dwCreateMenuType)
{
case ID_SHCREATEMENUBAR_RCDATA:
mbi.nToolBarId = IDR_CMB_CMDBAR;//RCDATA资源类型,二进制
break;
case ID_SHCREATEMENUBAR_HMENU:
mbi.dwFlags = SHCMBF_HMENU;
mbi.nToolBarId = IDM_CMB_MENU;//菜单资源
break;
case ID_SHCREATEMENUBAR_EMPTYBAR:
mbi.dwFlags = SHCMBF_EMPTYBAR;
break;
case ID_SHCREATEMENUBAR_NOSIPBUTTON:
mbi.dwFlags = SHCMBF_EMPTYBAR|SHCMBF_HIDESIPBUTTON;
break;
case ID_SHCREATEMENUBAR_HIDDENMENUBAR:
mbi.dwFlags = SHCMBF_HMENU;//设置此单数但不设置nToolBarId,会隐藏MenuBar
break;
default:
break;
}
if (FALSE == SHCreateMenuBar(&mbi))
{
MessageBox(hDlg, _T("SHCreateMenuBar Failed"), _T("Error"), MB_OK);
}
//retain the hwnd to the toolbar to destroy it if necessary
hwndMB = mbi.hwndMB;
4. RCDATA 格式说明
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
IDR_MENUOK RCDATA
BEGIN
0, // menu
1, // Count of buttons
I_IMAGENONE,
IDC_OK,
TBSTATE_ENABLED,
TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE,
IDS_OK,
0,
NOMENU,
END
IDM_MAIN_MENU RCDATA
BEGIN
IDR_MENU,
2,
I_IMAGENONE, IDM_START, TBSTATE_ENABLED, TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE, IDS_START, 0, NOMENU,
I_IMAGENONE, IDM_STOP,TBSTATE_ENABLED, TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_STOP, 0, 0,
END
说明:
IDR_MENU 我们要用软键显示的菜单的子菜单名字
2 说明这个MenuBar上有几个菜单项
I_IMAGENONE 菜单不支持带有bitmap(0xfffe)
IDM_START 用来在WM_COMMAND中处理控件的标识
TBSTATE_ENABLED 代表菜单的启用状态(0x0004)
TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE
菜单的样式,具体可以查MSDN中WinCE ToolBar Sytle。
TBSTYLE_DROPDOWN 这个也是样式,如果你的菜单有子菜单,那么这里必须要用这个样式
IDS_START 菜单上显示的字,实现在字符串资源中定义
最后的0 子菜单的索引
NOMENU 代表该菜单项没有子菜单(0xffff)