sdk之菜单使用一

定义菜单

要使用Developer Studio来给程序资源描述文件添加菜单,可以从Insert菜单中选择 Resource并选择Menu(或者您可能已经知道了)。然后,您可以用交谈式的方式定义菜单。菜单中每一项都有一个相关的 Menu Item Properties对话框,指出该项目的字符串。如果选中了Pop-up复选框,该项目就会呼叫一个弹出式菜单,并且没有ID与此项目相联系。如果没有选中 Pop-up复选框,该项目被选中时就会产生带有特定ID的WM_COMMAND消息。这两类菜单项分别出现在资源描述档的POPUP和MENUITEM叙述中。

当您为菜单中的项目键入文字时,可以键入一个「&」符号,指出后面一个字符在Windows显示菜单时要加底线。这种底线字符是在您使用Alt键选择菜单项时Windows要寻找的比对字符。如果在文字中不包括「&」符号,就不显示任何底线,Windows会将菜单项文字的第一个字母用于Alt键查找。

如果在Menu Items Properties对话框中选中Grayed选项,则菜单项是不能启动的,它的文字是灰色的,该项不产生WM_COMMAND消息。如果选中 Inactive选项,则菜单项也是不能启动的,也不产生WM_COMMAND消息,但是它的文字显示正常。 Checked选项在菜单项边上放置一个选中标记。Separator选项在弹出式菜单上产生一个分栏的横线。

在弹出式菜单的项目上,可以在字符串中使用制表符/t。紧接着/t的文字被放置在距离弹出式菜单的第一列右边新的一列上。在本章后面,会看到在使用键盘快捷键时它起的作用。字符串中的/a使跟着它的文字向右对齐。

您指定的ID值是Windows发送给窗口消息处理程序中菜单消息中的数值。在菜单中ID值应该是唯一的。按照惯例,我使用以IDM(「ID for a Menu」)开头的标识符。

在程序中引用菜单

大多数Windows应用程序在资源描述文件中只有一个菜单。您可以给菜单起一个与程序名称相同的文字的名称。程序写作者经常将程序名用于菜单名称,以便相同的字符串可以用于窗口类别、程序的图标名称和菜单名称。然后,程序在窗口的定义中为菜单引用该名称:

wndclass.lpszMenuName = szAppName ;
        

虽然存取菜单资源的最常用方法是在窗口类别中指定菜单,您也可以使用其它方法。Windows应用程序可以使用LoadMenu函数将菜单资源加载内存中,如同LoadIcon和LoadCursor函数一样。LoadMenu传回一个菜单句柄。如果您在资源描述档中为菜单使用了名称,叙述如下:

hMenu = LoadMenu (hInstance, TEXT ("MyMenu")) ;
        

如果使用了数值,那么LoadMenu呼叫采用如下的形式:

hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (ID_MENU)) ;
        

然后,您可以将这个菜单句柄作为CreateWindow的第九个参数:

hwnd = CreateWindow (      TEXT ("MyClass"), TEXT ("Window Caption"),
        
   WS_OVERLAPPEDWINDOW,
        
   CW_USEDEFAULT, CW_USEDEFAULT,
        
   CW_USEDEFAULT, CW_USEDEFAULT,
        
   NULL, hMenu, hInstance, NULL) ;
        

在这种情况下,CreateWindow呼叫中指定的菜单可以覆盖窗口类别中指定的任何菜单。如果CreateWindow的第九个参数是NULL,那么您可以把窗口类别中的菜单看作是这种窗口类别的窗口内定使用的菜单。这样,您可以为依据同一窗口类别建立的几个窗口使用不同的菜单。

您也可以在窗口类别中指定NULL菜单,并且在CreateWindow呼叫中也指定NULL菜单,然后在窗口被建立后再给窗口指定一个菜单:

SetMenu (hwnd, hMenu) ;
        

这种形式使您可以动态地修改窗口的菜单。在本章后面的NOPOPUPS程序中我们将会看到这方面的例子。

当窗口被清除时,与窗口相关的所有菜单都将被清除。与窗口不相关的菜单在程序结束前通过呼叫DestroyMenu主动清除。

菜单和消息

当使用者选择一个菜单项时,Windows通常向窗口消息处理程序发送几个不同的消息。在大多数情况下, 您的程序可以忽略大部分消息,只需把它们传递给DefWindowProc即可。WM_INITMENU就是这一类的消息,它具有下列参数:

wParam: 主菜单句柄

lParam: 0

wParam值是您的主菜单句柄,即使使用者选择的是系统菜单中的项目。Windows程序通常忽略WM_INITMENU消息。尽管在选中该项之前的消息已经给程序提供了修改菜单的机会,但是我们觉得此刻改变顶层菜单是会扰乱使用者的。

程序也会接收到WM_MENUSELECT消息。随着使用者在菜单项中移动光标或者鼠标,程序会收到许多WM_MENUSELECT消息。这对实作那些包含对菜单项的文字描述的状态列是很有帮助的。WM_MENUSELECT的参数如下所示:

LOWORD (wParam):被选中项目:菜单ID或者弹出式菜单句柄

HIWORD (wParam):选择旗标

lParam: 包含被选中项目的菜单句柄

WM_MENUSELECT是一个菜单追踪消息,wParam的值告诉您目前选择的是菜单中的哪一项(加高亮度显示的那个),wParam的高字组中的「选择旗标」可以是下列这些旗标的组合:MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU和MF_MOUSESELECT。如果您需要根据对菜单项的选择来改变窗口显示区域的内容,那么您可以使用WM_MENUSELECT消息。许多程序把该消息发送给DefWindowProc。

当Windows准备显示一个弹出式菜单时,它给窗口消息处理程序发送一个WM_INITMENUPOPUP消息,参数如下:

wParam: 弹出式菜单句柄

LOWORD (lParam):弹出式菜单索引

HIWORD (lParam): 系统菜单为1,其它为0

如果您需要在显示弹出式菜单之前启用或者禁用菜单项,那么这个消息就很重要。例如,假定程序使用弹出式菜单上的 Paste命令从剪贴簿复制文字,当您收到弹出式菜单中的WM_INITMENUPOPUP消息时,应确定剪贴簿内是否有文字存在。如果没有,那么应该使 Paste菜单项无效化。我们将在本章后面修改的POPPAD程序中看到这样的例子。

最重要的菜单消息是WM_COMMAND,它表示使用者已经从菜单中选中了一个被启用的菜单项。第八章中的WM_COMMAND消息也可以由子窗口控件产生。如果您碰巧为菜单和子窗口控件使用同一ID码,那么您可以通过lParam的值来区别它们,菜单项的lParam其值为0,请参见表10-1。

表10-1

 

菜单

控件

LOWORD (wParam):

菜单ID

控件ID

HIWORD (wParam):

0

通知码

lParam:

0

子窗口句柄

WM_SYSCOMMAND消息类似于WM_COMMAND消息,只是WM_SYSCOMMAND表示使用者从系统菜单中选择一个启用的菜单项:

wParam: 菜单ID

lParam: 0

然而,如果WM_SYSCOMMAND消息是由按鼠标按键产生的,LOWORD(lParam)和HIWORD(lParam)将包含鼠标光标位置的x和y屏幕坐标。

对于WM_SYSCOMMAND,菜单ID指示系统菜单中的哪一项被选中。对于预先定义的系统菜单项,较低的那四个位应该和0xFFF0进行AND运算来屏蔽掉,结果值应该为下列之一:SC_SIZE、SC_MOVE、SC_MINIMIZE、SC_MAXIMIZE、SC_NEXTWINDOW、SC_PREVWINDOW、SC_CLOSE、SC_VSCROLL、SC_HSCROLL、SC_ARRANGE、SC_RESTORE和SC_TASKLIST。此外,wParam可以是SC_MOUSEMENU或SC_KEYMENU。

如果您在系统菜单中添加菜单项,那么wParam的低字组将是您定义的菜单ID。为了避免与预先定义的菜单ID相冲突,应用程序应该使用小于0xF000的值,这对于将一般的WM_SYSCOMMAND消息发送给DefWindowProc是很重要的。如果您不这样做,那么您实际上就是禁用了正常的系统菜单命令。

我们将讨论的最后一个消息是WM_MENUCHAR。实际上,它根本不是菜单消息。在下列两种情况之一发生时,Windows会把这个消息发送到窗口消息处理程序:如果使用者按下Alt和一个与菜单项不匹配的字符时,或者在显示弹出式菜单而使用者按下一个与弹出式菜单里的项目不匹配的字符键时。随WM_MENUCHAR消息一起发送的参数如下所示:

LOWORD (wParam): 字符代码(ASCII或Unicode)

HIWORD (wParam): 选择码

lParam: 菜单句柄

选择码是:

  • 0 不显示弹出式菜单
     
  • MF_POPUP 显示弹出式菜单
     
  • MF_SYSMENU 显示系统弹出式菜单
     

Windows程序通常把该消息传递给DefWindowProc,它一般给Windows传回0,这会使Windows发出哔声。在 第十四章GRAFMENU程序中会看到WM_MENUCHAR消息的使用。

 

你可能感兴趣的:(windows,properties,command,null,insert,menu)