二、Windows菜单—较难的一种菜单定义方法
在程序的资源描述文件中定义菜单,通常是在您的窗口中添加菜单的最简单方法,但不是唯一的方法。如果您没有使用资源描述档,那么可以使用CreateMenu和AppendMenu两个函数在程序中建立菜单。在您定义完菜单后,您可以将菜单句柄发送给CreateWindow,或者使用SetMenu来设定窗口的菜单。
以下是具体的做法。CreateMenu简单地把一个句柄传回给新菜单:
hMenu = CreateMenu () ;
        
菜单一开始为空。AppendMenu将菜单项插入菜单中。您必须为顶层菜单项和每一个弹出式菜单提供不同的菜单句柄。弹出式菜单是单独构成的,然后将弹出式菜单句柄插入顶层菜单。程序10-5中所示的程序代码就是用这种方法建立菜单的,实际上,这个菜单与MENUDEMO程序中的菜单相同。为了简化说明,代码使用ASCII字符串。
程序10-5  不使用资源描述文件建立与MENUDEMO程序相同菜单的C程序代码
        
hMenu = CreateMenu () ;
        
hMenuPopup = CreateMenu () ;
        
AppendMenu         (hMenuPopup, MF_STRING, IDM_FILE_NEW, "&New");
        
AppendMenu         (hMenuPopup, MF_STRING, IDM_FILE_OPEN, "&Open...");
        
AppendMenu         (hMenuPopup, MF_STRING, IDM_FILE_SAVE, "&Save");
        
AppendMenu         (hMenuPopup,  MF_STRING, IDM_FILE_SAVE_AS, "Save &As...");
        
AppendMenu         (hMenuPopup, MF_SEPARATOR, 0, NULL) ;
        
AppendMenu         (hMenuPopup, MF_STRING, IDM_APP_EXIT, "E&xit") ;
        
AppendMenu         (hMenu, MF_POPUP, hMenuPopup, "&File") ;
        
hMenuPopup = CreateMenu () ;
        
AppendMenu         (hMenuPopup, MF_STRING, IDM_EDIT_UNDO,"&Undo") ;
        
AppendMenu         (hMenuPopup, MF_SEPARATOR, 0, NULL) ;
        
AppendMenu         (hMenuPopup, MF_STRING,IDM_EDIT_CUT, "Cu&t") ;
        
AppendMenu         (hMenuPopup, MF_STRING,IDM_EDIT_COPY,"&Copy") ;
        
AppendMenu         (hMenuPopup,  MF_STRING,IDM_EDIT_PASTE,"&Paste") ;
        
AppendMenu         (hMenuPopup, MF_STRING,IDM_EDIT_CLEAR,"De&lete") ;
        
AppendMenu         (hMenu,       MF_POPUP,     hMenuPopup, "&Edit") ;
        
hMenuPopup = CreateMenu () ;
        
AppendMenu (hMenuPopup, MF_STRING| MF_CHECKED,        IDM_BKGND_WHITE, "&White");
        
AppendMenu (hMenuPopup, MF_STRING,          IDM_BKGND_LTGRAY, "&Light Gray");
        
AppendMenu (hMenuPopup, MF_STRING,                    IDM_BKGND_GRAY,   "&Gray") ;
        
AppendMenu (hMenuPopup, MF_STRING,          IDM_BKGND_DKGRAY, "&Dark Gray");
        
AppendMenu (hMenuPopup,    MF_STRING,          IDM_BKGND_BLACK,  "&Black") ;
        
AppendMenu (hMenu, MF_POPUP, hMenuPopup, "&Background") ;
        
hMenuPopup = CreateMenu () ;
        
AppendMenu (hMenuPopup, MF_STRING,          IDM_TIMER_START, "&Start") ;
        
AppendMenu (hMenuPopup, MF_STRING | MF_GRAYED, IDM_TIMER_STOP, "S&top") ;
        
AppendMenu (hMenu,       MF_POPUP, hMenuPopup, "&Timer") ;
        
hMenuPopup =      CreateMenu () ;
        
AppendMenu (hMenuPopup, MF_STRING,    IDM_HELP_HELP,        "&Help") ;
        
AppendMenu (hMenuPopup, MF_STRING,    IDM_APP_ABOUT,        "&About MenuDemo...") ;
        
AppendMenu (hMenu, MF_POPUP, hMenuPopup, "&Help") ;
        
我认为您会同意底下这个观点:使用资源描述档菜单模板来制作菜单,会更容易而且更清楚。我并不鼓励您使用这里的方法定义菜单,而只是提供了一种实作菜单的方法。当然,您可以使用包含所有菜单项字符串、ID和旗标等的结构数组来压缩程序代码大小。不过,如果您这么做了,那么您还可以利用Windows定义菜单的第三种方法。LoadMenuIndirect函数接受一个指向MENUITEMTEMPLATE型态的结构指针,并传回菜单的句柄,该函数在载入资源描述档中的常规菜单模板后,在Windows中构造菜单,读者不妨自己尝试一下。
