《Windows环境下32位汇编语言程序设计(第2版)》-chapter5-基本框架

第五章开始创建一个带菜单的窗口,自己把代码打出来又做了注释,只是粘贴到代码段后格式有点乱,对齐什么的,强迫症飘过,暂时没找到好办法整理或者避免……

菜单的资源文件(资源文件的后缀是rs,只是CSDN无法识别这个,就改成txt了)

# include 
   
   
    
    
# define IDM_MAIN		 0x2000
# define IDA_MAIN		 0x2000 

# define IDM_OPEN		 0x4101
# define IDM_OPTION		 0x4102
# define IDM_EXIT		 0x4103
# define IDM_SETFONT	 0x4201
# define IDM_SETCOLOR	 0x4202
# define IDM_INACT		 0x4203
# define IDM_GRAY		 0x4204
# define IDM_BIG		 0x4205
# define IDM_SAMLL		 0x4206
# define IDM_LIST		 0x4207
# define IDM_DETAIL		 0x4208

# define IDM_TOOLBAR	 0x4209	
# define IDM_TOOLBARTEXT 0x4210	
# define IDM_INPUTBAR	 0x4211	
# define IDM_STATUSBAR   0x4212

# define IDM_HELP		 0x4301
# define IDM_ABOUT		 0x4302

IDM_MAIN	menu		discardable
BEGIN
		popup	"文件(&F)"
		BEGIN
			menuitem 	"打开文件(&O)", IDM_OPEN
			menuitem	"关闭文件(&C)", IDM_OPTION
			menuitem	separator
			menuitem	"退出(&X)", IDM_EXIT
		END
		
		popup	"查看(&V)"
		BEGIN
			menuitem	"字体(&F)\tAlt+F", IDM_SETFONT			//&表示在字母下面添加下划线,默认为快捷键
			menuitem	"背景色(&B)\tCtrl+Alt+B", IDM_SETCOLOR //\t会使后面的字符串右对齐
			menuitem	separator
			menuitem	"被禁用的菜单项", IDM_INACT, INACTIVE	//CHECKED,GRAYED,INACTIVE,MENUBREAK,MENUBARBREAK(以下部分另起一列)
			menuitem	"被灰化的菜单项", IDM_GRAY, GRAYED
			menuitem	separator
			menuitem	"大图标(&G)", IDM_BIG
			menuitem	"小图标(&M)", IDM_SAMLL
			menuitem	"列表(&L)", IDM_LIST
			menuitem	"详细资料(&D)", IDM_DETAIL
			menuitem	separator
			popup	"工具栏(&T)"
			BEGIN
				menuitem	"标准按钮(&S)", IDM_TOOLBAR
				menuitem	"文字标签(&C)", IDM_TOOLBARTEXT 
				menuitem	"命令栏(&T)", IDM_INPUTBAR	
				menuitem	"状态栏(&U)", IDM_STATUSBAR
			END		
		END
		
		popup	"帮助(&H)"										 //popup ”” [,GRAYED][,INACTIVE][,HELP(右对齐)]
		BEGIN
			menuitem	"帮助主题(&H)", IDM_HELP
			menuitem	separator
			menuitem	"关于本程序(&A)", IDM_ABOUT
		END
END

IDA_MAIN accelerators
BEGIN
	VK_F1, IDM_HELP, VIRTKEY									//"^X" = ctrl + X
	"B", IDM_SETCOLOR, VIRTKEY, CONTROL, ALT					//"X" = X, VIRTKEY       	
	"F", IDM_SETFONT, VIRTKEY, ALT								//数值	表示Ascii为该数值的字母,ASCII
																//[,CONTROL][,ALT][,SHIFT]
																//VK_F1 = F1
																//VK_BACK
																//VK_ESCAPE
																//VK_DELETE
																//VK_RETURN
END
   
   

主程序文件

				.386
				.model flat, stdcall
				option casemap: none
;-----------------------------------------------------------------------	
include		  	windows.inc
include		  	gdi32.inc
includelib 	  	gdi32.lib
include 	  	user32.inc
includelib	  	user32.lib
include 	  	kernel32.inc
includelib    	kernel32.lib
;-----------------------------------------------------------------------
IDM_MAIN		equ	2000h
IDA_MAIN		equ 2000h 

IDM_OPEN		equ 	4101h
IDM_OPTION		equ 	4102h
IDM_EXIT		equ 	4103h
IDM_SETFONT	 	equ 	4201h
IDM_SETCOLOR	equ 	4202h
IDM_INACT		equ 	4203h
IDM_GRAY		equ 	4204h
IDM_BIG		 	equ 	4205h
IDM_SAMLL		equ 	4206h
IDM_LIST		equ 	4207h
IDM_DETAIL		equ 	4208h

IDM_TOOLBAR	 	equ 	4209h	
IDM_TOOLBARTEXT equ 	4210h	
IDM_INPUTBAR	equ 	4211h	
IDM_STATUSBAR   equ 	4212h

IDM_HELP		equ 	4301h
IDM_ABOUT		equ 	4302h
;-----------------------------------------------------------------------
				.data
hInstance 	  	dd 		?
hWinMain  	  	dd 		?
hMenu   	  	dd 		?
hSubMenu  	  	dd 		?
				.const
szClassName   	db 		'MyClass', 0
szCaptionMain 	db 		'My first window', 0 
szText		  	db 		'Win32 Assemply, Simple and powerful!', 0
szMenuHelp		db		'帮助主题(&H)', 0
szMenuAbout		db		'关于本程序(&A)', 0
szCaption 		db		'MenuDisply', 0
szFormat		db 		'what you choose is:%08x', 0					;@08x最少8位的16进制
;-----------------------------------------------------------------------
				.code
;-----------------------------------------------------------------------	
;_DisplayMenuItem实现弹出一个指定格式内容的窗口			
;-----------------------------------------------------------------------				
_DisplayMenuItem 		proc 	_dwCommandID							;_dwCommandID是形式参数,此处未指明类型
				local 	@szBuffer[256]: byte
				
				pushad													;保护现场
				invoke 	wsprintf, addr @szBuffer, addr szFormat,\		;wsprintf(szBuffer, szFormat, _dwCommandID);
						_dwCommandID									;wParam有32位,低16位是命令id(资源ID),高16位是通知码,全0为菜单消息,全1为快捷键消息
				invoke 	MessageBox, hWinMain, addr @szBuffer, \			;MessageBox(hWinMain, szBuffer, szCaption, MB_OK);
						offset szCaption, MB_OK							;			模块句柄,显示内容,窗口标题,窗口模式
				popad													;保护现场
				ret														;相当于return,自动实现堆栈平衡
				
_DisplayMenuItem 		endp
;-----------------------------------------------------------------------
;_Quit单独实现了退出功能,可以再加上一些判断。利用call调用即可
;-----------------------------------------------------------------------
_Quit 			proc
				
				invoke 	DestroyWindow, hWinMain							;DestroyWindow(hWndMain);销毁窗口
				invoke 	PostQuitMessage, 0								;PostQuitMessage(0);	 终止进程	
				ret
				
_Quit			endp
;-----------------------------------------------------------------------		
_ProcWinMain    proc  	uses ebx edi esi, hWnd, uMsg, wParam, lParam
			    local 	@stPs: PAINTSTRUCT
				local 	@stRect: RECT
				local 	@hDc
				local 	@stPos: POINT
				local 	@hSysMenu
			  
				mov 	eax, uMsg											;载入消息
				;-----------------------------------------------------------
				.if   	eax == WM_PAINT										;感兴趣的自己处理	
						invoke  BeginPaint, hWnd, addr @stPs
						mov	    @hDc, eax
					
						invoke  GetClientRect, hWnd, addr @stRect
						invoke  DrawText, @hDc, addr szText, -1,\
								addr @stRect,\
								DT_SINGLELINE or DT_CENTER or DT_VCENTER
					
						invoke  EndPaint, hWnd, addr @stPs
				;-----------------------------------------------------------	
				.elseif eax == WM_CREATE
						;为了右键菜单使用,实际上应该自己定义一个
						invoke 	GetSubMenu, hMenu, 1
						mov		hSubMenu, eax
						
						;在系统菜单中添加自己的菜单(右键标题栏)
						;此菜单发送WM_SYSCOMMAND
						;invoke 	GetSystemMenu, hWnd, FALSE
						;mov		@hSysMenu, eax
						;invoke 	AppendMenu, @hSysMenu, MF_SEPARATOR, 0, NULL
						;invoke 	AppendMenu, @hSysMenu, 0, IDM_HELP, offset szMenuHelp
						;invoke 	AppendMenu, @hSysMenu, 0, IDM_ABOUT, offset szMenuAbout
						
				;-----------------------------------------------------------
				.elseif eax == WM_COMMAND									;用户选择一个菜单项(非系统菜单),用户按下一个快捷键(非系统键),都处理成返回到主窗口处理
						;通知用户按下菜单的ID----------------------------
						invoke 	_DisplayMenuItem, wParam					;wParam里保存着通知码和ID值(菜单项和对应的快捷键返回同一个wParam)
																			;WM_COMMAND就是这样定义的
						;取出ID,进行判断----------------------------------
						mov		eax, wParam
						movzx 	eax, ax										
						.if		eax == IDM_EXIT
								call 	_Quit
						.endif						
				;-----------------------------------------------------------
				.elseif eax == WM_SYSCOMMAND								;用户选择一个系统菜单,用户按下一个系统快捷键,都处理成返回到主窗口处理
						;取出ID,进行判断----------------------------------
						mov		eax, wParam
						movzx 	eax, ax
						.if 	eax == IDM_HELP || eax == IDM_ABOUT
								invoke 	_DisplayMenuItem, wParam
						.else												;除了系统快捷键和自己定义的系统菜单外,其他交给系统去处理,一下为套路
								invoke 	DefWindowProc, hWnd, uMsg, wParam, lParam
								ret
						.endif
				;-----------------------------------------------------------
				.elseif eax == WM_RBUTTONDOWN
						;BOOL GetCursorPos(LPPOINT lpPoint);
						;把光标所在坐标存入POINT中
						invoke 	GetCursorPos, addr @stPos
						;BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, int nReserved, HWND hWnd, CONST RECT* prcRect);
						;hMenu:此句柄可为调用CreatePopupMenu创建的新快捷菜单的句柄,也可以为调用GetSubMenu取得的与一个已存在菜单项相联系的子菜单的句柄。
						;uFlags:TPM_CENTERALIGN:x居中放置,TPM_LEFTALIGN:左边界与X对齐,TPM_RIGHTALIGN:右边界与X对齐
						;NReserved:保留值,必须为零
						;HWnd:拥有快捷菜单的窗口的句柄,hInstance,在_ProcWinMain中是hWnd
						;prcRect:NULL,在菜单外单击菜单消失
						invoke 	TrackPopupMenu, hSubMenu, TPM_LEFTALIGN, @stPos.x, @stPos.y, 0, hWnd, NULL
				;-----------------------------------------------------------
				.elseif eax == 	WM_CLOSE									;套路
						;invoke 	DestroyWindow, hWinMain
						;invoke 	PostQuitMessage, NULL
						call 	_Quit
				;-----------------------------------------------------------
				.else
						invoke 	DefWindowProc, hWnd, uMsg, wParam, lParam	;不感兴趣交给系统处理
						ret
				.endif
				;-----------------------------------------------------------
				xor		eax, eax											;清零返回
				ret
				
_ProcWinMain 	endp
;-----------------------------------------------------------------------	
_WinMain		proc
				local 	@stWndClass: WNDCLASSEX
				local 	@stMsg: MSG
				local 	@hAccelerator
	
				;注册窗口类-----------------------------------------------
				;获取本模块句柄-------------------------------------------
				invoke 	GetModuleHandle, NULL	;获取本模块句柄存入eax中
				mov		hInstance, eax			;存入全局变量hInstance中
				;获取菜单句柄---------------------------------------------
				;HMENU LoadMenu(HINSTANCE hlnstance,LPCTSTR lpMenuName);
				;若函数调用成功,则返回所加载的菜单句柄,若函数调用失败,则返回值为NULL
				;hlnstance:含有被加载菜单资源的实例模块的句柄
				;LpMenuName:低位字16bit资源标识符,高位字16bit全零
				;-----------------------------------------------------------
				invoke 	LoadMenu, hInstance, IDM_MAIN						;必须获取菜单句柄 
				mov 	hMenu, eax											
				;获取快捷键句柄-------------------------------------------
				;HACCEL LoadAccelerators(HINSTANCE hlnstance,LPCTSTR lpTableName);
				;lpTableName:低位字16bit资源标识符,高位字16bit全零
				;-----------------------------------------------------------
				invoke 	LoadAccelerators, hInstance, IDA_MAIN				;必须获取快捷键句柄
				mov 	@hAccelerator, eax									;必须改写消息循环
				;-----------------------------------------------------------
				
				invoke 	RtlZeroMemory, addr @stWndClass, sizeof @stWndClass ;必须初始化局部变量			
				;															;hIcon!!!
				;															;hCursor!!!	
				;															;lpszMenuName!!!									
				push 	hInstance											;hInstance
				pop		@stWndClass.hInstance	
				mov 	@stWndClass.cbSize, sizeof WNDCLASSEX				;cbsize
				mov 	@stWndClass.style, CS_HREDRAW or CS_VREDRAW			;style!!!
				mov 	@stWndClass.lpfnWndProc, offset _ProcWinMain		;lpfnWndProc
				mov 	@stWndClass.hbrBackground, COLOR_WINDOW + 1			;hbrBackground!!!
				mov 	@stWndClass.lpszClassName, offset szClassName		;lpszClassName
				;															;cbWndExtra
				;															;cbClsExtra
				invoke 	RegisterClassEx, addr @stWndClass					;stWndClass是一个结构体
				;-----------------------------------------------------------
				;创建窗口--------------------------------------------------
				invoke 	CreateWindowEx, WS_EX_CLIENTEDGE,\					;dwExStyle!!!
						offset szClassName, offset szCaptionMain,\			;lpClassName, lpWindowMain
						WS_OVERLAPPEDWINDOW,\								;dwStyle!!!
						100, 100, 600, 400,\								;x, y, nWight, nHeight
						NULL, hMenu, hInstance, NULL						;hWndParent!!!, hMenu!!!, hInstance, lpParam!!!
				mov 	hWinMain, eax
				;显示窗口--------------------------------------------------
				invoke 	ShowWindow, hWinMain, SW_SHOWNORMAL					;SW!!!
				;更新窗口--------------------------------------------------
				invoke 	UpdateWindow, hWinMain
				;-----------------------------------------------------------
				;消息循环--------------------------------------------------
				;|--------------------------------------------------------------------------------------------------------------|
				;|.while 	TRUE																							   	|
				;|		invoke GetMessage, addr @stMsg, NULL, 0, 0			;lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax			|
				;|															;addr @stMsg										|
				;|															;hWnd NULL 本程序所属窗口							|
				;|															;wMsgFilterMax = wMsgFilterMin = 0 获取所有消息 	|
				;|		.break .if eax == 0									;WM_QUIT eax = 0, 退出消息循环					|
				;|		invoke TranslateMessage, addr @stMsg				;WM_CHAR, WM_SYSCHAR, 键盘消息转换					|
				;|		invoke DispatchMessage, addr @stMsg					;发送到窗口过程函数								|
				;|.endw																											|
				;|--------------------------------------------------------------------------------------------------------------|
				.while 	TRUE
						invoke 	GetMessage, addr @stMsg, NULL, 0, 0			
						.break 	.if eax == 0
						
						;系统自动完成快捷键检测功能----------------------
						;int TranslateAccelerator(HWND hWnd,HACCEL hAccTable,LPMSG IpMsg);
						;若函数调用成功,则返回非零值;若函数调用失败,则返回值为零(没找到快捷键的消息)
						;hWnd:消息被发送到这个窗口处理
						;hAccTable:快捷键表句柄
						;lpMsg:从GetMessage或PeekMessage从消息队列获取的消息
						;---------------------------------------------------
						invoke 	TranslateAccelerator, hWinMain, @hAccelerator, addr @stMsg
						.if		eax == 0
								invoke 	TranslateMessage, addr @stMsg				
								invoke 	DispatchMessage, addr @stMsg					
						.endif
				.endw
				ret
				
_WinMain		endp
;-----------------------------------------------------------------------	
start:
				call 	_WinMain
				invoke 	ExitProcess, NULL				
end start
;-----------------------------------------------------------------------	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows环境32位汇编语言程序设计 第2(罗文斌) 完整光盘内容,包含每章内容的完整代码 本光盘所包含目录的说明 根目录下的 *.pdf ;附录A、B、C的电子文档 Chapter02\Test ;测试编译环境 Chapter03\HelloWorld ;Hello World Chapter04\FirstWindow ;用Win32汇编写第一个窗口 Chapter04\FirstWindow-1 ;用Win32汇编写第一个窗口 Chapter04\SendMessage ;窗口间的消息互发 Chapter04\SendMessage-1 ;窗口间的消息互发 Chapter05\Menu ;使用资源 - 使用菜单 Chapter05\Icon ;使用资源 - 使用图标 Chapter05\Dialog ;使用资源 - 使用对话框 Chapter05\Listbox ;使用资源 - 使用列表框 Chapter05\Control ;使用资源 - 使用子窗口控件 Chapter05\ShowVersionInfo ;使用资源 - 显示本信息资源的程序 Chapter05\VersionInfo ;使用资源 - 使用本信息资源 Chapter06\Timer ;定时器的使用 Chapter07\DcCopy ;在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 Chapter09\Toolbar ;使用工具栏 Chapter09\StatusBar ;使用状态栏 Chapter09\Richedit ;使用丰富编辑控件 Chapter09\Wordpad ;一个完整的文本编辑器例子 Chapter09\SubClass ;窗口的子类化例子 Chapter09\SuperClass ;窗口的超类化例子 Chapter10\MemInfo ;显示当前内存的使用情况 Chapter10\Fragment ;内存碎片化的演示程序 Chapter10\FindFile ;全盘查找文件的例子 Chapter10\FormatText ;文件读写例子 Chapter10\FormatText\FileMap ;使用内存映射文件进行文件读写的例子 Chapter10\MMFShare ;使用内存映射文件进行进程间数据共享 Chapter11\Dll\Dll ;最简单的动态链接库例子 - 编写 DLL Chapter11\Dll\MASM Sample ;最简单的动态链接库例子 - 使用 DLL Chapter11\Dll\VC++ Sample ;最简单的动态链接库例子 - 在VC++中使用汇编编写的DLL Chapter11\KeyHook ;Windows 钩子的例子 - 监听键盘动作 Chapter11\RecHook ;Windows 日志记录钩子的例子 - 监听键盘动作 Chapter12\Counter ;有问题的程序 - 一个计数程序 Chapter12\Thread ;用多线程的方
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值