梦书之家(移动开发)

你有一个苹果,我有一个苹果,我们交换一下,一人还是一个苹果;你有一个思想,我有一个思想,我们交换一下,一人就有两个思想。 ——肖伯纳

导航

在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里的“删除”前面加个空格,就解决了。当然,为了对齐,在选项菜单下的其他菜单项前面都要加个空格。唯一的解释可能是“删除”与系统默认的菜单项冲突了。最后修正后的图如下图所示:

posted on 2007-08-20 18:03  梦书  阅读(3121)  评论(2编辑  收藏  举报