sdk之菜单使用二

本文详细介绍了Windows程序中菜单的使用,包括如何通过AppendMenu、DeleteMenu等函数修改系统菜单,菜单项的增删改查,以及如何强制更新菜单显示。此外,还探讨了菜单项的选中状态、禁用、高亮等属性的设置和获取。

在程序窗口建立之后,POORMENU得到一个系统菜单的句柄:

hMenu = GetSystemMenu (hwnd, FALSE) ;
        

第一次呼叫GetSystemMenu时,您应该为修改菜单作准备,将第二个参数设定为FALSE。

使用四个AppendMenu呼叫来实作对菜单的修改:

AppendMenu (hMenu,       MF_SEPARATOR, 0,                                                NULL) ;
        
AppendMenu (hMenu,       MF_STRING, IDM_SYS_ABOUT,     TEXT ("About...")) ;
        
AppendMenu (hMenu,       MF_STRING, IDM_SYS_HELP,             TEXT ("Help...")) ;
        
AppendMenu (hMenu,       MF_STRING, IDM_SYS_REMOVE,    TEXT ("Remove Additions"));
        

第一个AppendMenu呼叫是添加分隔条。选择「Remove Additions」菜单项将使POORMENU删除这些附加的菜单项,这只要把第二个参数设定为TRUE,再次呼叫GetSystemMenu即可:

GetSystemMenu (hwnd, TRUE) ;
        

标准系统菜单有下列选项:Restore、Move、Size、Minimize、Maximize和Close。它们产生wParam分别等于SC_RESTORE、SC_MOVE、SC_SIZE、SC_MINIMUM、SC_MAXIMUM和SC_CLOSE的WM_SYSCOMMAND消息。尽管Windows程序一般不这样做,但是您可以自己处理这些消息,而不把它们留给DefWindowProc。您也可以使用下面所述的方法来禁止或者除掉系统菜单的标准选项。Windows文件中还介绍了一些系统菜单的标准附加项目,这些附加项目使用标识符SC_NEXTWINDOW、SC_PREVWINDOW、SC_VSCROLL、SC_HSCROLL和SC_ARRANGE。您也许会发现,在一些应用程序中将这些命令加入系统菜单是合适的。

改变菜单

我们已经看到了如何使用AppendMenu函数为程序定义菜单以及将菜单项加入到系统菜单中。在Windows 3.0之前,您不得不被迫使用ChangeMenu函数来完成这种工作。ChangeMenu函数有很多功能,至少在当时,整个Windows中它是最复杂的函数之一。现在,许多函数都比ChangeMenu函数还要复杂,并且ChangeMenu的功能被分解为五个新的函数:

  • AppendMenu在菜单尾部添加一个新的菜单项目
     
  • DeleteMenu删除菜单中一个现有的菜单项并清除该项目
     
  • InsertMenu在菜单中插入一个新项目
     
  • ModifyMenu修改一个现有的菜单项目
     
  • RemoveMenu从菜单中移走某一项目
     

如果菜单项是一个弹出式菜单,那么DeleteMenu和RemoveMenu之间的区别就很重要。DeleteMenu清除弹出式菜单,但RemoveMenu不清除它。

其它菜单命令

下面是在使用菜单时一些有用的函数。

当您改变顶层菜单项时,直到Windows重画菜单列时才显示所做的改变。您可以通过下列呼叫来强迫执行菜单更新:

DrawMenuBar (hwnd) ;
        

注意,DrawMenuBar的参数是窗口句柄而不是菜单句柄。

您可以使用下列命令来获得弹出式菜单的句柄:

hMenuPopup = GetSubMenu (hMenu, iPosition) ;
        

其中iPosition是hMenu指示的顶层菜单中弹出式菜单项的索引(开始为0)。然后您可以在其它函数中使用弹出式菜单句柄(例如在AppendMenu函数中)。

您可以使用下列命令获得顶层菜单或者弹出式菜单中目前的项数:

iCount = GetMenuItemCount (hMenu) ;
        

您可以取得弹出式菜单项的菜单ID:

id = GetMenuItemID (hMenuPopup, iPosition) ;
        

其中iPosition是菜单项在弹出式菜单中的位置(以0开始)。

在MENUDEMO中您已经看到如何选中、或者取消选中弹出式菜单中的某一项:

CheckMenuItem (hMenu, id, iCheck) ;
        

在MENUDEMO中,hMenu是顶层菜单的句柄,id是菜单ID,而iCheck的值是MF_CHECKED或MF_UNCHECKED。如果hMenu是弹出式菜单句柄,那么参数id是位置索引而不是菜单ID。如果使用索引会更方便的话,那么您可以在第三个参数中包含MF_BYPOSITION,例如:

CheckMenuItem (hMenu, iPosition, MF_CHECKED | MF_BYPOSITION) ;
        

除了第三个参数是MF_ENABLED、MF_DISABLED或MF_GRAYED外,EnableMenuItem函数与CheckMenuItem函数所完成的工作类似。如果您在具有弹出式菜单的顶层菜单项上使用EnableMenuItem,那么必须在第三个参数中使用MF_BYPOSITION标识符,因为菜单项没有菜单ID。我们将在本章后面所示的POPPAD2程序中看到EnableMenuItem的一个例子。 HiliteMenuItem也类似于CheckMenuItem和EnableMenuItem,但是它使用的是MF_HILITE和MF_UNHILITE。当您在菜单项之间移动时,Windows使用反白显示方式加亮显示菜单项。您通常不需要使用HiliteMenuItem。

您还需要对您的菜单做些什么呢?还记得我们在菜单中使用了哪些字符串吗?您可以透过下面的呼叫来回顾一下:

iCharCount = GetMenuString (hMenu, id, pString, iMaxCount, iFlag) ;
        

iFlag可以是MF_BYCOMMAND(其中id是菜单ID),也可以是MF_BYPOSITION(其中的id是位置索引)。函数将字符串的iMaxCount个字节复制到pString中,并传回复制的字节数。

或许您也想知道菜单项目前的属性是什么:

iFlags = GetMenuState (hMenu, id, iFlag) ;
        

同样地,iFlag可以是MF_BYCOMMAND或MF_BYPOSITION。传回值iFlags是目前所有属性的组合,您可以通过对MF_DISABLED、MF_GRAYED、MF_CHECKED、MF_MENUBREAK、MF_MENUBARBREAK和MF_SEPARATOR标识符的检测来决定目前的属性。

也许现在您对菜单有了一些了解。这时您可能想知道,如果您不再需要菜单时又应该如何处理。您可以使用下面的命令来清除菜单:

DestroyMenu (hMenu) ;
        

从而使菜单句柄无效。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值