• 资源文件的“源文件”是 .rc 的脚本文件

菜单和加速健

1.菜单和加速键的组成

  • 加速健就是快捷键
  • /# sharp
  • 这里有一个工具 resedit-x64
1
2
闪退:
在文件:ResEdit.xml中查找行"<autoCheckupdate value="true"/>",并将其替换为"<autocheckUpdate value="false" />"
1
2
设置中文
ctrl+P 在第一个地方把语言 english设置成chinese

ok用这个工具,创建一个菜单

1
2
$F -> 
\t -> tab健

image-20230504163520949

2.菜单和加速键的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#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_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
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN ICON "Main.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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
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)\tF1", 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
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

1.)菜单的定义

1
2
3
4
5
菜单ID MENU [DISCARDABLE] 
BEGIN
菜单项定义
...
END

在上面的代码就是

1
2
3
4
5
6
#define	IDM_MAIN		0x2000	//菜单

IDM_MAIN menu discardable
BEGIN
...
END
  • API函数在检测参数的时候,发现小于10000H的时候就把他认为是数值型,大于10000H的时候就把他当作字符串指针处理

  • discardable 是菜单的存属性,表示菜单在不使用的时候可以展示从内存中释放来节省空间

  • begin 和 end 可以用 { } 来代替

菜单项的定义有3种

1
2
3
4
5
6
7
MENUITEM    菜单文字,命令ID [,选项列表] (用法1)
MENUITEM SEPARATOR (用法2)
POPUP 菜单文字 [,选项列表] (用法3)
BEGIN
item-definitions
...
END

用法1定义的是普通菜单项

●选项——用来定义菜单项的各种属性,它可以是下列数值:

■CHECKED——表示打上选定标志(对钩)。

■GRAYED——表示菜单项是灰化的。

■INACTIVE——表示菜单项是禁用的。

■MENUBREAK或MENUBARBREAK——表示将这个菜单项和以后的菜单项列到新的列中

用法2定义的是菜单项之间的分隔线。

用法3定义弹出式菜单

popup菜单的选项列表可以是以下的值:

●GRAYED——表示菜单项是灰化的。

●INACTIVE——表示菜单项是禁用的

●HELP——表示本项和以后的菜单项是右对齐的

2.)加速键的定义

1
2
3
4
5
加速键ID ACCELERATORS 
BEGIN
键名, 命令ID [,类型] [,选项]
...
END

上面的代码就是

1
2
3
4
5
6
IDA_MAIN	accelerators
BEGIN
VK_F1, IDM_HELP, VIRTKEY //这个是使用头文件里面包含好了的,加速键的定义方式
"B", IDM_SETCOLOR,VIRTKEY,CONTROL,ALT
"F", IDM_SETFONT,VIRTKEY,ALT
END
  • 加速键ID同样可以是一个字符串或者是1~65 535之间的数字
  • 整个定义内容也是用begin和end(或花括号)包含起来

字段的含义如下所示

●键名——表示加速键对应的按键,可以有3种方式定义。

■”^字母”:表示Ctrl键加上字母键。

■”字母”:表示字母,这时类型必须指明是VIRTKEY。

■数值:表示ASCII码为该数值的字母,这时类型必须指明为ASCII。

●命令ID——按下加速键后,Windows向程序发送的命令ID。如果想把加速键和菜单项关联起来,这里就是要关联菜单项的命令ID。

●类型——用来指定键的定义方式,可以是VIRTKEY和ASCII,分别用来表示“键名”字段定义的是虚拟键还是ASCII码。

●选项——可以是Alt,Control或Shift中的单个或多个,如果指定多个,则中间用逗号隔开,表示加速键是按键加上这些控制键的组合键。

3.)使用菜单和加速键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Menu.asm
; 菜单资源的使用例子
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Menu.asm
; rc Menu.rc
; Link /subsystem:windows Menu.obj Menu.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.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
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_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
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
.if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endif
.endw
ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start

emmm,我们不需要用这个东西来开发,所以我们看得懂就好啦

内容有点繁琐,看看书啦