在Visual Studio 2005下创建WM for Smartphone/Standard 软键菜单的问题
SHMENUBARINFO shmbi;
ZeroMemory(&shmbi, sizeof(shmbi));
shmbi.cbSize = sizeof(shmbi);
shmbi.hwndParent = hDlg;
shmbi.nToolBarId = IDR_MENU;
shmbi.hInstRes = g_hInstance;
BOOL bCreateMenu = SHCreateMenuBar(&shmbi);
bCreateMenu 始终为零,但是如果IDR_MENU 改为之前工程中原有的菜单ID就行了,让我感到很郁闷。
通过比较自己刚创建的IDR_MENU只有在.rc文件中的RCDATA下没有相应的内容,但对这个RCDATA不太了解,所以对这个差别也没在意。后来在网上搜索到如下的内容:
请教一个关于smartphone中菜单的问题,请高手指教
其中,hdw191的回答给出了方法:
“……阁下用的应该也是 VS2005了. 因为你创建的菜单缺少 RCDATA资源,所以失败!
我是直接用evc写菜单的~”
因此,我们可以用EVC在其资源编辑器中创建菜单,然后把相应的部分拷到VS2005工程里的.rc文件中。
而cuterain的回答,详细解释了RCDATA部分的内容各个宏的定义:
“开发时发现,不会创建菜单,Smartphone上的菜单资源定义和Windows的菜单资源定义稍微有些不同。由于Smartphone采用的是两个soft key来调用菜单,所以他的菜单在资源文件中的定义叫SHMENUBAR或者叫RCDATA,这两个名字是一样的,最开始我还纳闷了半天。下面给出一个我写的简单的菜单资源。
IDR_MENU MENU DISCARDABLE
BEGIN
POPUP ""
BEGIN
MENUITEM "Pop" ,IDM_PAUSE
END
END
IDR_MENUBAR SHMENUBAR
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
朋友们的Win32 SDK开发都比我强,废话就不用说了,就说一下这个资源的每个地方代表什么意思。
IDR_MENU 是我定义的弹出菜单,注意这里的名字要和下面IDR_MENUBAR SHMENUBAR中紧接在BEGIN后面的第一个参数一致。这样才能实现按right soft key时可以弹出菜单来。
IDR_MENUBAR SHMENUBAR中的参数下面逐一说明:
IDR_MENU 我们要用软键显示的菜单的子菜单名字
2 说明这个MenuBar上有几个菜单项,Smartphone只能有两个(为什么?如果你的Smartphone有三个软键你可以定义三个,哈哈)
I_IMAGENONE Smartphone菜单不支持带有bitmap的,所以这里采用这个定义
IDM_START 这个是我们用来在WM_COMMAND中处理控件的标识
TBSTATE_ENABLED 这个代表菜单的启用状态
TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE 菜单的样式,具体可以查MSDN中WinCE ToolBar Sytle。
TBSTYLE_DROPDOWN 这个也是样式,如果你的菜单有子菜单,那么这里必须要用这个样式
IDS_START 菜单上显示的字,实现在字符串资源中定义
最后的0 子菜单的索引,大家注意,我的IDR_MENU的定义第一项就是一个POPUP式的菜单,所以我这里设置的是0
NOMENU 代表该菜单项没有子菜单
”
这个内容对于研究如何去除SDI程序中Commandbar上的"新建"按钮也非常有帮助。
可能你也注意到了,有些RCDATA下的都是Unicode码与EVC资源编辑器自动生成(以上的格式)的还是有区别。但是在其拷贝到.rc文件中,然后保存退出,再次打开的时候,以上的格式就会自动被转换成16进制的格式
比如:以下在EVC的资源编辑器中,定义两个软键菜单,均是非弹出式菜单
IDR_MENU MENU DISCARDABLE
BEGIN
MENUITEM "确定", ID_UNINSTALL
MENUITEM "取消", ID_CANCEL
END
IDR_MENU SHMENUBAR DISCARDABLE
BEGIN
IDR_MENU,
2,
I_IMAGENONE, ID_DONE, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE,
IDS_MENUITEM40007, 0, NOMENU,
I_IMAGENONE, ID_CANCEL, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE,
IDS_MENUITEM40010, 0, NOMENU,
END
那么相应的在VS2005工程下的.rc文件为:
IDR_MENU MENU
BEGIN
MENUITEM "确定", IDM_DONE
MENUITEM "取消", ID_CANCEL
END
IDR_MENU RCDATA
BEGIN
0x009b, 0x0002, 0xfffe, 0x9c78, 0x0004, 0x0010, 0x9c47, 0x0000, 0xffff,
0xfffe, 0x9c7a, 0x0004, 0x0010, 0x9c4a, 0x0000, 0xffff
END
通过对照以下:红色部分具有通用性
IDR_MENU SHMENUBAR DISCARDABLE // SHMENUBAR DISCARDABLE -> RCDATA
BEGIN
IDR_MENU, //IDR_MENU 在Resource.h的值得16进制值0x009b 下同
2, //0x0002 ,1 就是0x0001
I_IMAGENONE, // 0xfffe
ID_DONE, //0x9c78
TBSTATE_ENABLED, //0x0004
TBSTYLE_AUTOSIZE, //0x0010
IDS_MENUITEM40007, //0x9c47
0, //0x0000
NOMENU,//0xffff
I_IMAGENONE, //0xfffe
ID_CANCEL, //0x9c7a
TBSTATE_ENABLED, //0x0004
TBSTYLE_AUTOSIZE, //0x0010 ,而TBSTYLE_DROPDOWN 对应 0x0018
IDS_MENUITEM40010, //0x9c4a
0, //0x0000
NOMENU,//0xffff
END
可见,VS2005自动对EVC中的格式进行转换,而且几乎是逐个将每个属性(姑且认为每个分号或 | 分割的均为属性)转换为32位的16进制数保存。
另外,今天发现一个很诡异的问题,如下图所示:
正常的情况下,右边的菜单项应该是: 删除(A) 删除全部(B);
而后来我在右软键菜单下添加其他的菜单项,添加的菜单项以及“删除全部”菜单项没有问题,唯一的问题的是“删除”后面的字符D。
后来我在编辑“删除”的菜单项时候,在Caption里的“删除”前面加个空格,就解决了。当然,为了对齐,在选项菜单下的其他菜单项前面都要加个空格。唯一的解释可能是“删除”与系统默认的菜单项冲突了。最后修正后的图如下图所示: