当前位置:中国易下载软件教材中心文章中心编程语言汇编语言 → 汇编语言教学(8)

汇编语言教学(8)

减小字体 增大字体 作者:佚名  来源:不详  发布时间:2007-8-21 1:04:14
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
喜欢这些内容嘛,请告诉你身边的朋友,易下载中心-QQ资源-itnetcn.com一起享受这份乐趣,本站内容来源互联网
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

第八课 菜单yXh海岸线网络安全资讯站
本课中我们将在我们的应用程序中加入一个菜单。 yXh海岸线网络安全资讯站
理论:yXh海岸线网络安全资讯站
菜单可以说是WINDOWS最重要的元素之一。有了它,用户可以方便地选择操作命令.用户只要细读一下所有的菜单项就可以明了应用程序所提供的大概功能,而且可以立即操作,无须去阅读手册了.正因为菜单给了用户一种方便的方式,所以您在应用程序中加入菜单时就要遵守一般的标准.譬如:一般头两个菜单项是"File"和"Edit",最后是"Help",您可以在这中间插入您要定义的菜单项.如果所运行的菜单命令会弹出一个对话框,那么就要在该菜单项后加入省略符(...).菜单是一种资源,除菜单外还有其它像对话框,字符串,图标,位图资源等.在链接时链接程序将把资源加入到可执行程序中去,最后我们的执行程序中就既包括机器指令又包括了资源. 您可以在任何文本编辑器中编写脚本文件,在文件中您可以指定资源呈现出来的外观和其它的一些属性.当然更直观的方法是用资源编辑器,通常资源编辑器都打包在编译环境中,像Visual C++, Borland C++等都带了资源编辑器. 我们可以按以下方式来定义一个菜单资源: yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
MyMenu MENU yXh海岸线网络安全资讯站
{ yXh海岸线网络安全资讯站
[menu list here] yXh海岸线网络安全资讯站
} yXh海岸线网络安全资讯站
这和C语言中的结构体的定义非常相似。 MyMenu类似于被定义的变量,而MENU则类似于关键字。当然您可以用另外一种办法,那就是用BEGIN和END来代替花括号,这和PASCAL语言中的风格相同。 yXh海岸线网络安全资讯站
在菜单项的列表中是一大串的MENUITEM和POPUP语句。MENUITEM定义了一个菜单项,当选择后不会激活对话框。它的语法如下: yXh海岸线网络安全资讯站
MENUITEM "&text", ID [,options] yXh海岸线网络安全资讯站
它由关键字MENUITEM开头,紧跟在MENUITEM后的是指菜单项的名称字符串,符号“&“后的第一个字符将会带下画线,它也是该菜单项的快捷键。ID的作用当该菜单被选中时,WINDOWS的消息处理过程用来区分菜单项用的。毫无疑问,ID号必须唯一。options有以下可供选择的属性: yXh海岸线网络安全资讯站
GRAYED 代表该菜单项处于非激活状态,即当其被选中时不会产生WM_COMMAND消息。该菜单以灰色显示。 yXh海岸线网络安全资讯站
INACTIVE 代表该菜单项处于非激活状态,即当其被选中时不会产生WM_COMMAND消息。该菜单以正常颜色显示。 yXh海岸线网络安全资讯站
MENUBREAK 该菜单项和随后的菜单项会显示在新列中。(译者注:比较难描述,请做实验。) yXh海岸线网络安全资讯站
HELP 该菜单项和随后的菜单项右对齐。(译者注:我在WINDOWS2000下编译有该标志的菜单项,该标志好像没起作用) yXh海岸线网络安全资讯站
您可以单独使用以上标志位,也可以把它们或在一起。当然INACTIVE和GRAYED不能同时使用。 POPUP的语法如下: yXh海岸线网络安全资讯站
POPUP "&text" [,options] yXh海岸线网络安全资讯站
{ yXh海岸线网络安全资讯站
[menu list] yXh海岸线网络安全资讯站
}yXh海岸线网络安全资讯站
POPUP定义了一个菜单项当该菜单项被选中时又会弹出一个子菜单。另外有一种特别类型的MENUITEM语句MENUITEM SEPARATOR,它表示在菜单项位置画一条分隔线。定义完菜单后,您就可以在程序中使用脚本中定义的菜单资源了。您可以在程序的两个地方(或叫做用两种方式)使用它们: yXh海岸线网络安全资讯站
在WNDCLASSEX结构体的成员lpszMenuName中。譬如,您有一个菜单“FirstMenu“,您可以按如下方法把它联系到您的窗口: yXh海岸线网络安全资讯站
.DATA yXh海岸线网络安全资讯站
MenuName db "FirstMenu",0 yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
.CODE yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
mov wc.lpszMenuName, OFFSET MenuName yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
在CreateWindowEx函数中指明菜单的句柄: yXh海岸线网络安全资讯站
.DATA yXh海岸线网络安全资讯站
MenuName db "FirstMenu",0 yXh海岸线网络安全资讯站
hMenu HMENU ? yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
.CODE yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
invoke LoadMenu, hInst, OFFSET MenuName yXh海岸线网络安全资讯站
mov hMenu, eax yXh海岸线网络安全资讯站
invoke CreateWindowEx,NULL,OFFSET ClsName,\ yXh海岸线网络安全资讯站
OFFSET Caption, WS_OVERLAPPEDWINDOW,\ yXh海岸线网络安全资讯站
CW_USEDEFAULT,CW_USEDEFAULT,\ yXh海岸线网络安全资讯站
CW_USEDEFAULT,CW_USEDEFAULT,\ yXh海岸线网络安全资讯站
NULL,\ yXh海岸线网络安全资讯站
hMenu,\ yXh海岸线网络安全资讯站
hInst,\ yXh海岸线网络安全资讯站
NULL\ yXh海岸线网络安全资讯站
........................... yXh海岸线网络安全资讯站
您也许会问,这两着之间有什么不同呢?当您用第一种方法时,由于是在窗口类中指定,故所有由该窗口类派生的窗口都将有相同的菜单。如果您想要从相同的类中派生的窗口有不同的菜单那就要使用第二中方法,该方法中通过函数CreateWindowEx指定的菜单会“覆盖”WNDCLASSEX结构体中指定的菜单。接下来我们看看当用户选择了一个菜单项时它是如何通知WINDOWS 窗口过程的:当用户选择了一个菜单项时,WINDOWS窗口过程会接收到一个WM_COMMAND消息,传进来的参数wParam的底字节包含了菜单项的ID号。好了,上面就是关于菜单项的一切,下面我们就来实践。 yXh海岸线网络安全资讯站
例子:yXh海岸线网络安全资讯站
第一个例子显示了指定一个菜单项的第一种方法: yXh海岸线网络安全资讯站
.386 yXh海岸线网络安全资讯站
.model flat,stdcall yXh海岸线网络安全资讯站
option casemap:none yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
include \masm32\include\windows.inc yXh海岸线网络安全资讯站
include \masm32\include\user32.inc yXh海岸线网络安全资讯站
include \masm32\include\kernel32.inc yXh海岸线网络安全资讯站
includelib \masm32\lib\user32.lib yXh海岸线网络安全资讯站
includelib \masm32\lib\kernel32.lib yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
.data yXh海岸线网络安全资讯站
ClassName db "SimpleWinClass",0 yXh海岸线网络安全资讯站
AppName db "Our First Window",0 yXh海岸线网络安全资讯站
MenuName db "FirstMenu",0 ; The name of our menu in the resource file. yXh海岸线网络安全资讯站
Test_string db "You selected Test menu item",0 yXh海岸线网络安全资讯站
Hello_string db "Hello, my friend",0 yXh海岸线网络安全资讯站
Goodbye_string db "See you again, bye",0 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
.data? yXh海岸线网络安全资讯站
hInstance HINSTANCE ? yXh海岸线网络安全资讯站
CommandLine LPSTR ? yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
.const yXh海岸线网络安全资讯站
IDM_TEST equ 1 ; Menu IDs yXh海岸线网络安全资讯站
IDM_HELLO equ 2 yXh海岸线网络安全资讯站
IDM_GOODBYE equ 3 yXh海岸线网络安全资讯站
IDM_EXIT equ 4 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
.code yXh海岸线网络安全资讯站
start: yXh海岸线网络安全资讯站
invoke GetModuleHandle, NULL yXh海岸线网络安全资讯站
mov hInstance,eax yXh海岸线网络安全资讯站
invoke GetCommandLineyXh海岸线网络安全资讯站
mov CommandLine,eax yXh海岸线网络安全资讯站
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT yXh海岸线网络安全资讯站
invoke ExitProcess,eax yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD yXh海岸线网络安全资讯站
LOCAL wc:WNDCLASSEX yXh海岸线网络安全资讯站
LOCAL msg:MSG yXh海岸线网络安全资讯站
LOCAL hwnd:HWND yXh海岸线网络安全资讯站
mov wc.cbSize,SIZEOF WNDCLASSEX yXh海岸线网络安全资讯站
mov wc.style, CS_HREDRAW or CS_VREDRAW yXh海岸线网络安全资讯站
mov wc.lpfnWndProc, OFFSET WndProc yXh海岸线网络安全资讯站
mov wc.cbClsExtra,NULL yXh海岸线网络安全资讯站
mov wc.cbWndExtra,NULL yXh海岸线网络安全资讯站
push hInst yXh海岸线网络安全资讯站
pop wc.hInstance yXh海岸线网络安全资讯站
mov wc.hbrBackground,COLOR_WINDOW+1 yXh海岸线网络安全资讯站
mov wc.lpszMenuName,OFFSET MenuName ; Put our menu name here yXh海岸线网络安全资讯站
mov wc.lpszClassName,OFFSET ClassName yXh海岸线网络安全资讯站
invoke LoadIcon,NULL,IDI_APPLICATION yXh海岸线网络安全资讯站
mov wc.hIcon,eax yXh海岸线网络安全资讯站
mov wc.hIconSm,eax yXh海岸线网络安全资讯站
invoke LoadCursor,NULL,IDC_ARROW yXh海岸线网络安全资讯站
mov wc.hCursor,eax yXh海岸线网络安全资讯站
invoke RegisterClassEx, addr wc yXh海岸线网络安全资讯站
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ yXh海岸线网络安全资讯站
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ yXh海岸线网络安全资讯站
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ yXh海岸线网络安全资讯站
hInst,NULL yXh海岸线网络安全资讯站
mov hwnd,eax yXh海岸线网络安全资讯站
invoke ShowWindow, hwnd,SW_SHOWNORMAL yXh海岸线网络安全资讯站
invoke UpdateWindow, hwnd yXh海岸线网络安全资讯站
.WHILE TRUE yXh海岸线网络安全资讯站
invoke GetMessage, ADDR msg,NULL,0,0 yXh海岸线网络安全资讯站
.BREAK .IF (!eax) yXh海岸线网络安全资讯站
invoke DispatchMessage, ADDR msg yXh海岸线网络安全资讯站
.ENDW yXh海岸线网络安全资讯站
mov eax,msg.wParam yXh海岸线网络安全资讯站
ret yXh海岸线网络安全资讯站
WinMain endp yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM yXh海岸线网络安全资讯站
.IF uMsg==WM_DESTROY yXh海岸线网络安全资讯站
invoke PostQuitMessage,NULL yXh海岸线网络安全资讯站
.ELSEIF uMsg==WM_COMMAND yXh海岸线网络安全资讯站
mov eax,wParam yXh海岸线网络安全资讯站
.IF ax==IDM_TEST yXh海岸线网络安全资讯站
invoke MessageBox,NULL,ADDR Test_string,OFFSET AppName,MB_OK yXh海岸线网络安全资讯站
.ELSEIF ax==IDM_HELLO yXh海岸线网络安全资讯站
invoke MessageBox, NULL,ADDR Hello_string, OFFSET AppName,MB_OK yXh海岸线网络安全资讯站
.ELSEIF ax==IDM_GOODBYE yXh海岸线网络安全资讯站
invoke MessageBox,NULL,ADDR Goodbye_string, OFFSET AppName, MB_OK yXh海岸线网络安全资讯站
.ELSE yXh海岸线网络安全资讯站
invoke DestroyWindow,hWnd yXh海岸线网络安全资讯站
.ENDIF yXh海岸线网络安全资讯站
.ELSE yXh海岸线网络安全资讯站
invoke DefWindowProc,hWnd,uMsg,wParam,lParam yXh海岸线网络安全资讯站
ret yXh海岸线网络安全资讯站
.ENDIF yXh海岸线网络安全资讯站
xor eax,eax yXh海岸线网络安全资讯站
ret yXh海岸线网络安全资讯站
WndProc endp yXh海岸线网络安全资讯站
end start yXh海岸线网络安全资讯站
***************************************************************** yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
Menu.rc yXh海岸线网络安全资讯站
*****************************************************************yXh海岸线网络安全资讯站
#define IDM_TEST 1 yXh海岸线网络安全资讯站
#define IDM_HELLO 2 yXh海岸线网络安全资讯站
#define IDM_GOODBYE 3 yXh海岸线网络安全资讯站
#define IDM_EXIT 4 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
FirstMenu MENU yXh海岸线网络安全资讯站
{ yXh海岸线网络安全资讯站
POPUP "&PopUp" yXh海岸线网络安全资讯站
{ yXh海岸线网络安全资讯站
MENUITEM "&Say Hello",IDM_HELLO yXh海岸线网络安全资讯站
MENUITEM "Say &GoodBye", IDM_GOODBYE yXh海岸线网络安全资讯站
MENUITEM SEPARATOR yXh海岸线网络安全资讯站
MENUITEM "E&xit",IDM_EXIT yXh海岸线网络安全资讯站
} yXh海岸线网络安全资讯站
MENUITEM "&Test", IDM_TEST yXh海岸线网络安全资讯站
} yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
分析:yXh海岸线网络安全资讯站
我们先来分析资源文件:yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
#define IDM_TEST 1 /* equal to IDM_TEST equ 1*/ yXh海岸线网络安全资讯站
#define IDM_HELLO 2 yXh海岸线网络安全资讯站
#define IDM_GOODBYE 3 yXh海岸线网络安全资讯站
#define IDM_EXIT 4 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
上面的几行定义了菜单项的ID号。只要注意菜单项ID号必须唯一外,您可以给ID号任何值。 yXh海岸线网络安全资讯站
FirstMenu MENU yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
用关键字MENU定义菜单。 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
POPUP "&PopUp" yXh海岸线网络安全资讯站
{ yXh海岸线网络安全资讯站
MENUITEM "&Say Hello",IDM_HELLO yXh海岸线网络安全资讯站
MENUITEM "Say &GoodBye", IDM_GOODBYE yXh海岸线网络安全资讯站
MENUITEM SEPARATOR yXh海岸线网络安全资讯站
MENUITEM "E&xit",IDM_EXIT yXh海岸线网络安全资讯站
} yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
定义一个有四个菜单项的子菜单,其中第三个菜单项是一个分隔线。 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
MENUITEM "&Test", IDM_TEST yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
定义主菜单中的一项。下面我们来看看源代码yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
MenuName db "FirstMenu",0 ; The name of our menu in the resource file. yXh海岸线网络安全资讯站
Test_string db "You selected Test menu item",0 yXh海岸线网络安全资讯站
Hello_string db "Hello, my friend",0 yXh海岸线网络安全资讯站
Goodbye_string db "See you again, bye",0 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
MenuName是资源文件中指定的菜单的名字。因为您可以在脚本文件中定义任意多个菜单,所以在使用前必须指定您要使用那一个,接下来的行是在选中菜单项时显示在相关对话框中的字符串。yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
IDM_TEST equ 1 ; Menu IDs yXh海岸线网络安全资讯站
IDM_HELLO equ 2 yXh海岸线网络安全资讯站
IDM_GOODBYE equ 3 yXh海岸线网络安全资讯站
IDM_EXIT equ 4 yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
定义用在WINDOWS窗口过程中的菜单项ID号。这些值必须和脚本文件中的相同。 yXh海岸线网络安全资讯站
.ELSEIF uMsg==WM_COMMAND yXh海岸线网络安全资讯站
mov eax,wParam yXh海岸线网络安全资讯站
.IF ax==IDM_TEST yXh海岸线网络安全资讯站
invoke MessageBox,NULL,ADDR Test_string,OFFSET AppName,MB_OK yXh海岸线网络安全资讯站
.ELSEIF ax==IDM_HELLO yXh海岸线网络安全资讯站
invoke MessageBox, NULL,ADDR Hello_string, OFFSET AppName,MB_OK yXh海岸线网络安全资讯站
.ELSEIF ax==IDM_GOODBYE yXh海岸线网络安全资讯站
invoke MessageBox,NULL,ADDR Goodbye_string, OFFSET AppName, MB_OK yXh海岸线网络安全资讯站
.ELSE yXh海岸线网络安全资讯站
invoke DestroyWindow,hWnd yXh海岸线网络安全资讯站
.ENDIF yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
在本窗口过程中我们处理WM_COMMAND消息。当用户选择了一个菜单项时,该菜单项的ID放入参数wParam中被同时送到WINDOWS的窗口过程,我们把它保存到eax寄存器中以便和预定义的菜单项ID比较用。前三种情况下,当我们选中Test、Say Hello、Say GoodBye菜单项时,会弹出一个对话框其中显示一个相关的字符串,选择Exit菜单项时,我们就调用函数DestroyWindow,其中的参数是我们窗口的句柄,这样就销毁了窗口。就像您所看到的,通过在一个窗口类中指定菜单名的方法来给一个应用程序生成一个菜单是简单而直观的。除此方法外您还可以用另一种方法,其中资源文件是一样的,源文件中也只有少数的改动,这些改动如下:yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
.data? yXh海岸线网络安全资讯站
hInstance HINSTANCE ? yXh海岸线网络安全资讯站
CommandLine LPSTR ? yXh海岸线网络安全资讯站
hMenu HMENU ? ; handle of our menu yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
定义了一个变量来保存我们的菜单的句柄,然后: yXh海岸线网络安全资讯站
invoke LoadMenu, hInst, OFFSET MenuName yXh海岸线网络安全资讯站
mov hMenu,eax yXh海岸线网络安全资讯站
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ yXh海岸线网络安全资讯站
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ yXh海岸线网络安全资讯站
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,hMenu,\ yXh海岸线网络安全资讯站
hInst,NULL yXh海岸线网络安全资讯站
yXh海岸线网络安全资讯站
调用LoadMenu函数,该函数需要实例句柄和菜单名的字符串,调用的结果返回指向菜单的句柄,然后传给函数CreateWindowEx刚返回的菜单句柄就可以了。yXh海岸线网络安全资讯站