【学习笔记】菜单学习
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
includelibgdi32.lib
include user32.inc
includelibuser32.lib
include kernel32.inc
includelibkernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; EQU等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000h ;图标
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_SETCOLORequ 4202h ;设置颜色
IDM_INACT equ 4203h ;禁用菜单
IDM_GRAY equ 4204h ;灰化菜单
IDM_BIG equ 4205h ;大图标
IDM_SMALL equ 4206h ;小图标
IDM_LIST equ 4207h ;列表
IDM_DETAIL equ 4208h ;细节
IDM_TOOLBAR equ 4209h ;工具按钮
IDM_TOOLBARTEXT equ 4210h ;文本标签
IDM_INPUTBARequ 4211h ;命令栏
IDM_STATUSBARequ 4212h ;状态栏
IDM_HELP equ 4301h ;帮助
IDM_ABOUT equ 4302h ;关于
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstancedd ?
hWinMain dd ?
hMenu dd ?
hSubMenu dd ?
.const
szClassNamedb 'Menu Example',0 ;窗口类名称
szCaptionMain db 'Menu',0 ;主窗口标题
szMenuHelpdb '帮助主题(&H)',0
szMenuAboutdb '关于本程序(&A)...',0
szCaptiondb '菜单选择',0
szFormat db '您选择了菜单命令:%08x',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 显示菜单项目
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_DisplayMenuItem proc _dwCommandID ;_dwCommandID是参数
local @szBuffer:byte ;申请缓存空间
pushad ;保存所有寄存器的值
invokewsprintf,addr @szBuffer,\
addr szFormat,_dwCommandID ;将字符串格式化输出到缓冲区
invokeMessageBox,hWinMain,\
addr @szBuffer,offset szCaption,MB_OK ;用弹出消息显示选择的菜单消息
popad ;还原所有寄存器的值
ret
_DisplayMenuItem endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 退出程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Quit proc
invokeDestroyWindow,hWinMain ;摧毁窗口
invokePostQuitMessage,NULL ;退出消息循环
ret
_Quit endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam ;窗口过程开始
local @stPos:POINT ;POINT结构体存储鼠标坐标x.y
local @hSysMenu ;准备存储系统菜单句柄
mov eax,uMsg
;********************************************************************
.if eax ==WM_CREATE ;处理创建窗口的消息
invokeGetSubMenu,hMenu,1 ;获取子菜单句柄(索引为1的菜单)
mov hSubMenu,eax ;存储起来用来弹出右键菜单
;********************************************************************
; 在系统菜单中添加菜单项
;********************************************************************
invokeGetSystemMenu,hWnd,FALSE ;获取系统菜单句柄
mov @hSysMenu,eax ;存储
invokeAppendMenu,@hSysMenu,\
MF_SEPARATOR,0,0 ;添加一条分隔线
invokeAppendMenu,@hSysMenu,0,\
IDM_HELP,offset szMenuHelp ;在最后的菜单下添加帮助
invokeAppendMenu,@hSysMenu,0,\
IDM_ABOUT,offset szMenuAbout ;在最后的菜单下添加关于
;********************************************************************
; 处理菜单及加速键消息
;********************************************************************
.elseifeax== WM_COMMAND ;处理菜单命令
invoke_DisplayMenuItem,wParam ;调用_DisplayMenuItem子程序并把wParam当参数传入
mov eax,wParam ;将wParam里面的命令值存储
movzx eax,ax ;将菜单和加速键的通知码统一
.if eax ==IDM_EXIT
call _Quit ;调用退出子程序
.elseifeax >=IDM_TOOLBAR &&\
eax <=IDM_STATUSBAR ;eax==wParam 消息值大于4209h并且小于4212h为真
mov ebx,eax ;将eax==wParam 的消息值存储值ebx
invokeGetMenuState,hMenu,\;该函数取得与指定菜单项相联系的菜单标志
ebx,MF_BYCOMMAND ;获取ebx消息的状态:MF_CHECKED为选取标记
.if eax ==MF_CHECKED ;返回值eax是标记或者非标记状态,ebx是消息值.
mov eax,MF_UNCHECKED
.else
mov eax,MF_CHECKED
.endif
invokeCheckMenuItem,\ ;修改菜单项目的状态
hMenu,ebx,eax ;ebx值为要修改的菜单,eax值为需要修改的状态.
.elseifeax >=IDM_BIG &&\
eax <=IDM_DETAIL ;eax==wParam 消息值大于4205h并且小于4208h为真
invokeCheckMenuRadioItem,\;设置菜单的互斥状态
hMenu,IDM_BIG,\ ;将消息值4205h到4208h的状态清空
IDM_DETAIL,eax,\ ;并且将eax菜单值设置为标记状态
MF_BYCOMMAND
.endif
;********************************************************************
; 处理系统菜单消息
;********************************************************************
.elseifeax ==WM_SYSCOMMAND ;处理系统菜单消息
mov eax,wParam ;存储系统菜单消息至eax寄存器
movzx eax,ax ;将加速键和菜单消息的通知码统一
.if eax ==IDM_HELP ||\
eax ==IDM_ABOUT ;菜单消息eax如果等于4301h或者4302h则为真
invoke_DisplayMenuItem,wParam ;调用子程序_DisplayMenuItem并带入参数wParam
.else
invokeDefWindowProc,hWnd,\
uMsg,wParam,lParam;WINDOWS默认处理其它的信息
ret
.endif
;********************************************************************
; 单击鼠标右键时弹出一个POPUP菜单
;********************************************************************
.elseifeax ==WM_RBUTTONDOWN ;处理单击右键消息
invokeGetCursorPos,addr @stPos ;获取鼠标坐标并放入结构体@stPos中
invokeTrackPopupMenu,hSubMenu,\ ;指定位置显示快捷菜单,并跟踪菜单项的选择,快捷菜单可出现在任何位置
TPM_LEFTALIGN,@stPos.x,\ ;TPM_LEFTALIGN:函数使快捷菜单的左边界与由参数X指定的坐标对齐
@stPos.y,NULL,hWnd,NULL ;hSubMenu里面存储的是【查看】菜单的句柄
;********************************************************************
.elseifeax ==WM_CLOSE ;处理关闭消息
call _Quit
;********************************************************************
.else
invokeDefWindowProc,hWnd,\
uMsg,wParam,lParam ;将剩下的消息交给WINDOWS处理
ret ;直接返回
.endif
;********************************************************************
xor eax,eax ;将EAX寄存器致零。
ret ;直接返回
_ProcWinMain endp ;窗口过程结束
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc ;主模块执行
local @stWndClass:WNDCLASSEX ;申请注册窗口类的结构体@stWndClass
local @stMsg:MSG ;申请消息结构体@stMsg
local @hAccelerator ;申请加速键存储空间
invokeGetModuleHandle,NULL ;获取本程序句柄
mov hInstance,eax ;保存句柄到hInstance变量
invokeLoadMenu,hInstance,IDM_MAIN ;获取菜单资源的句柄
mov hMenu,eax ;保存句柄到hMenu变量
invokeLoadAccelerators,hInstance,IDA_MAIN ;获取菜单加速键的句柄
mov @hAccelerator,eax ;保存句柄到@hAccelerator变量
invokeRtlZeroMemory,addr @stWndClass,sizeof @stWndClass ;将结构体@stWndClass全部清0
;********************************************************************
; 注册窗口类
;********************************************************************
invokeLoadIcon,hInstance,ICO_MAIN ;载入指定的图标资源
mov @stWndClass.hIcon,eax ;填充结构体的图标:应用程序
mov @stWndClass.hIconSm,eax ;填充结构体的图标:程序菜单栏
push hInstance ;将程序的实例句柄压栈
pop @stWndClass.hInstance ;将程序的实例句柄出栈存储到结构体中
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW ;类的风格 CS_HREDRAW当窗口水平方向的宽度变化时重绘整个窗口
; CS_VREDRAW 当窗口垂直方向的宽度变化时重绘整个窗口
mov @stWndClass.lpfnWndProc,offset _ProcWinMain ;窗口回调过程的地址存储到结构体中
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1 ;画刷:颜色是白色..后面规定要+1
mov @stWndClass.lpszClassName,offset szClassName ;给定类名称
invokeRegisterClassEx,addr @stWndClass ;注册窗口类
;********************************************************************
; 建立并显示窗口
;********************************************************************
invokeCreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,\;建立窗口窗口风格扩展client客户 + edge边缘,后面的是类名称
offset szCaptionMain,\ ;窗口标题
WS_OVERLAPPEDWINDOW,\ ;复合窗口风格
100,100,400,300,\
NULL,hMenu,hInstance,NULL ;添加了菜单句柄和程序句柄
mov hWinMain,eax ;将返回句柄存储到hWinMain
invokeShowWindow,hWinMain,SW_SHOWNORMAL ;显示窗口 SW_SHOWNORMAL普通状态显示
invokeUpdateWindow,hWinMain ;更新窗口
;********************************************************************
; 消息循环
;********************************************************************
.whileTRUE ;TRUE==1
invoke GetMessage,addr @stMsg,NULL,0,0 ;取得本程序所有的消息放入@stMsg
.break .if eax == 0 ;如果EAX返回0(收到退出函数就等于0)则立即中断并退出消息循环
invoke TranslateAccelerator,\
hWinMain,@hAccelerator,addr @stMsg ;转译加速键消息
.ifeax ==0
invoke TranslateMessage,addr @stMsg ;转译@stMsg里面的消息到窗口过程
invoke DispatchMessage,addr @stMsg ;派发@stMsg里面的消息到窗口过程
.endif
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain ;调用子程序_WinMain
invokeExitProcess,NULL ;退出程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start ;程序从start开始执行
RC文件
=======================================================================
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//宏命令
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#defineICO_MAIN 0x1000 //图标
#defineIDM_MAIN 0x2000 //菜单
#defineIDA_MAIN 0x2000 //加速键
#defineIDM_OPEN 0x4101 //打开
#defineIDM_OPTION 0x4102 //关闭
#defineIDM_EXIT 0x4103 //退出
#defineIDM_SETFONT 0x4201 //设置字体
#defineIDM_SETCOLOR 0x4202 //设置颜色
#defineIDM_INACT 0x4203 //禁用菜单
#defineIDM_GRAY 0x4204 //灰化菜单
#defineIDM_BIG 0x4205 //大图标
#defineIDM_SMALL 0x4206 //小图标
#defineIDM_LIST 0x4207 //列表
#defineIDM_DETAIL 0x4208 //细节
#defineIDM_TOOLBAR 0x4209 //工具按钮
#defineIDM_TOOLBARTEXT 0x4210 //文本标签
#defineIDM_INPUTBAR 0x4211 //命令栏
#defineIDM_STATUSBAR 0x4212 //状态栏
#defineIDM_HELP 0x4301 //帮助
#defineIDM_ABOUT 0x4302 //关于
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//菜单建立
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAINICON "Main.ico"
IDM_MAINmenu 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
menuitem separator
menuitem "被禁用的菜单项",IDM_INACT,INACTIVE
menuitem "被灰化的菜单项",IDM_GRAY,GRAYED
menuitem separator
menuitem "大图标(&G)",IDM_BIG
menuitem "小图标(&M)",IDM_SMALL
menuitem "列表(&L)",IDM_LIST
menuitem "详细资料(&D)",IDM_DETAIL
menuitem separator
popup "工具栏(&T)"
BEGIN
menuitem "标准按钮(&S)",IDM_TOOLBAR
menuitem "文字标签(&C)",IDM_TOOLBARTEXT
menuitem "命令栏(&I)",IDM_INPUTBAR
END
menuitem "状态栏(&U)",IDM_STATUSBAR
END
popup "帮助(&H)",HELP //HELP选项代表本项和以后的菜单项是右对齐的
BEGIN
menuitem "帮助主题(&H)\tF1",IDM_HELP
menuitem separator
menuitem "关于本程序(&A)...",IDM_ABOUT
END
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//虚拟键
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDA_MAINaccelerators
BEGIN
VK_F1, IDM_HELP,VIRTKEY
"B", IDM_SETCOLOR,VIRTKEY,CONTROL,ALT
"F", IDM_SETFONT,VIRTKEY,ALT
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
你学的是 8086 汇编 还是win32的哦:o 反汇编?然后做解释? 学习了 {:10_275:} {:10_254:}
页:
[1]