0
点赞
收藏
分享

微信扫一扫

汇编中的资源文件脚本


     菜单,图表与对话框都是可执行文件的组成部分,他们是以资源的形式存放在文件中的,但这些资源并不存放在数据段中,而是单独的放在一个节区当中。

    资源文件是以".rc"为扩展名的脚本文件,由资源文件rc.exe编译成res为扩展名的二进制的资源文件,最后在link.exe文件链入可执行文件。

#define ICO_MAIN                     0x1000           //图标

#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_SMALL 0x4206

#define IDM_LIST 0x4207

#define IDM_DETALL 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
#define IDM_DETAIL 0x4303

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

//ICO_MAIN ICON "Main.ico"

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

IDM_MAIN menu discardable//disacrdable表明在不适用菜单时,可以从内存中卸载

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;顶级菜单

BEGIN

menuitem "帮助主题(&H)\F1", IDM_HELP

menuitem separator

menuitem "关于本程序(&A)…", IDM_ABOUT

END

END

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

IDA_MAIN accelerators;加速键,或者说定义在资源文件中的快捷键

BEGIN

; VK_F1, IDM_HELP, VIRTKEY

"B", IDM_SETCOLOR, VIRTKEY, CONTROL, ALT

"F", IDM_SETFONT, VIRTKEY, ALT

END
//菜单的属性
//CHECKED---表示打上选定标志
//GRAYED----表示菜单式灰色的
//INACTIVE--表示菜单式禁用的
//MENUBREAK或者MENUBARBREAK--表示菜单项和以后的菜单项列到新的列中
//键名,命令ID,类型,选项
//例如: "^C"表示Ctrl加上字母键
// "字母",这时必须指明是VIRTKEY
// "数字",表示ASCII码为该数值的字母,类型中必须指明是ASCII
// 类型中可以是VIRTKEY,ASCII 这两个,表明键名字段是虚拟键还是ASCII
// 选项可以是 ALT,CONTROL或者是SHIFT中的一个或者多个

    这里面有resource.h文件,该文件并不是系统文件,而是自己写的,其中定义了各种ID的数值,如果在.rc文件加入了控件的ID,则不再使用resource.h

下面是演示的win32汇编代码:

.386

.model flat,stdcall

option casemap:none

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Include 文件定义

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include windows.inc

include user32.inc

includelib user32.lib

include kernel32.inc

includelib kernel32.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_SETCOLOR equ 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_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 'Menu Example',0

szCaptionMain db 'Menu',0

szMenuHelp db '帮助主题(&H)',0

szMenuAbout db '关于本程序(&A)...',0

szCaption db '菜单选择',0

szFormat db '您选择了菜单命令:%08x',0

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 代码段

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

.code

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 弹出窗口,显示菜单命令ID

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_DisplayMenuItem proc _dwCommandID

local @szBuffer[256]:byte



pushad

invoke wsprintf, addr @szBuffer, addr szFormat, _dwCommandID

invoke MessageBox, hWinMain, addr @szBuffer, offset szCaption, MB_OK

popad

ret

_DisplayMenuItem endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 退出

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_Quit proc

invoke DestroyWindow, hWinMain

invoke PostQuitMessage, NULL

ret

_Quit endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; 窗口过程

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_ProcWinMain proc uses ebx edi esi, hWnd, uMsg, wParam, lParam

local @stPos:POINT

local @hSysMenu



mov eax,uMsg

;*************************************************************************

.if eax == WM_CREATE

invoke GetSubMenu, hMenu, 1

mov hSubMenu, eax

;***************************************************************************

; 在系统菜单中添加菜单项

;***************************************************************************

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

invoke _DisplayMenuItem, wParam

mov eax, wParam

movzx eax, ax

.if eax == IDM_EXIT

call _Quit

.elseif eax >= IDM_TOOLBAR && eax <= IDM_STATUSBAR

mov ebx, eax

invoke GetMenuState, hMenu, ebx, MF_BYCOMMAND

.if eax == MF_CHECKED

mov eax, MF_UNCHECKED

.else

mov eax, MF_CHECKED

.endif

invoke CheckMenuItem, hMenu, ebx, eax

.elseif eax >= IDM_BIG && eax <= IDM_DETAIL

invoke CheckMenuRadioItem, hMenu, IDM_BIG, IDM_DETAIL, eax, MF_BYCOMMAND

.endif

;***************************************************************************

; 处理系统菜单消息

;***************************************************************************

.elseif eax == WM_SYSCOMMAND

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

;***************************************************************************

; 单击鼠标右键时弹出一个POPUP菜单

;***************************************************************************

.elseif eax == WM_RBUTTONDOWN

invoke GetCursorPos, addr @stPos

invoke TrackPopupMenu, hSubMenu, TPM_LEFTALIGN, @stPos.x, @stPos.y, NULL, hWnd, NULL

;***************************************************************************

.elseif eax == WM_CLOSE

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

mov hInstance,eax

invoke LoadMenu, hInstance, IDM_MAIN ;获取菜单句柄

mov hMenu, eax ;把菜单句柄存储于hMenu变量

invoke LoadAccelerators, hInstance,IDA_MAIN

mov @hAccelerator, eax



invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

;**************************************************************************

; 注册窗口类

;**************************************************************************

; invoke LoadIcon, hInstance, ICO_MAIN

mov @stWndClass.hIcon, eax

mov @stWndClass.hIconSm, eax

invoke LoadCursor, 0, IDC_ARROW

mov @stWndClass.hCursor, eax

push hInstance

pop @stWndClass.hInstance

mov @stWndClass.cbSize, sizeof WNDCLASSEX

mov @stWndClass.style, CS_HREDRAW or CS_VREDRAW

mov @stWndClass.lpfnWndProc, offset _ProcWinMain

mov @stWndClass.hbrBackground,COLOR_WINDOW + 1

mov @stWndClass.lpszClassName, offset szClassName

invoke RegisterClassEx, addr @stWndClass

;***************************************************************************

; 建立并显示窗口

;***************************************************************************

invoke CreateWindowEx, WS_EX_CLIENTEDGE, \

offset szClassName, offset szCaptionMain, \

WS_OVERLAPPEDWINDOW, \

100, 100, 400, 300, \

NULL, hMenu, hInstance, NULL;;注意,在这儿为窗口加入了菜单项

mov hWinMain,eax

invoke ShowWindow,hWinMain,SW_SHOWNORMAL

invoke UpdateWindow,hWinMain

;**************************************************************************

; 消息循环

;**************************************************************************

.while TRUE

invoke GetMessage, addr @stMsg, NULL, 0, 0

.break .if eax == 0

invoke TranslateAccelerator, hWinMain, @hAccelerator, addr @stMsg;每次消息循环都加入了检测是否有快捷键的消息,如果是加速键中定义的 ;消息,则不再向窗口发送消息,,但自行向窗口发送WM_COMMAND或者WM_SYSCOMMAND,并返回FALSE,并非加速键定义的消息才会进行TranslateMessage和DispatchMessage

.if     eax == 0

invoke TranslateMessage, addr @stMsg

invoke DispatchMessage, addr @stMsg

.endif

.endw

ret

_WinMain endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

start:

call _WinMain

invoke ExitProcess, NULL

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

end start

WM_COMMAND消息的两个参数是:

wParam的高位是wNotifyCOde

wParam的低位是发送命令控件ID

举报

相关推荐

0 条评论