ASM32 11 计算机
代码实现
新建空白工程
在工程处新建菜单
打开Res文件夹
在文件名处输入MENU1后保存
选择确定
完成后资源处会增加菜单
点击打开菜单编辑器然后输入标题选择插入然后确定
插入成功后发现新建的菜单资源已成功写入
1 | .386 |
运行结果
在菜单下添加open,然后按右箭头表示在File的下级(此时前面会出现..)
选择快捷键
在工程中选中快捷键
添加快捷键
在工程中选择导入中的文件
导入文件
添加成功
1 | .386 |
运行结果
直接按快捷键Ctrl+O即可运行Open
计算机完整代码
1 | .386 |
运行结果
计算1+2
代码分析
1.段落说明
1 | .386 |
- **
.386
**:指定处理器架构为 80386。 - **
.model flat,stdcall
**:平坦内存模型,使用stdcall
调用约定。 - **
option casemap:none
**:禁止大小写转换。
2. 引用 Windows API 和库
1 | include windows.inc |
include
和 **includelib
**:包含必要的 Windows API 头文件和库,以支持程序的窗口、按钮、消息处理、内存管理等功能。
3. 常量定义
1 | IDR_MENU EQU 10000 |
- **
EQU
**:定义了菜单、加速器和命令的常量,表示唯一的资源 ID。
1 | .const |
.const
定义了多个常量字符串,用于窗口类名、按钮类名和其他 UI 元素的名称。ASM_EDIT
定义了一个唯一的编辑框 ID(30000),用于标识编辑控件。
4. 数据段
1 | .data |
- **
.data
**:定义了全局变量,g_hInstance
用于存储应用程序实例句柄,ASM_OP1
用于存储第一个操作数。
5. 程序入口 ENTRY
1 | ENTRY proc |
- **
ENTRY
**:定义了程序的入口函数。函数内部定义了多个局部变量,使用@
前缀,比如@msg
、@bRet
、@wc
等。这些变量用于窗口创建和消息循环的管理。
1 | invoke GetModuleHandle,NULL |
- **
GetModuleHandle
**:获取当前模块的句柄,并将其存储到局部变量@hInstance
和全局变量g_hInstance
。
6. 窗口类的注册
1 | mov @wc.style,0 |
- 这里通过设置
WNDCLASS
结构的各个字段,注册了窗口类,包括窗口过程地址WndProc
、光标、背景色和菜单等信息。
7. 创建窗口
1 | invoke CreateWindowEx,NULL,offset ASM_CLASS_NAME,offset ASM_WND_NAME,WS_OVERLAPPEDWINDOW,0,0,\ |
- **
CreateWindowEx
**:创建一个窗口,大小设置为4*64
宽度和6*64
高度。创建成功后,窗口句柄存储在@hWnd
中。
8. 消息循环
1 | WHILE1: |
- 消息循环:不断调用
GetMessage
,获取消息并分发给相应的窗口过程。循环一直运行,直到收到退出消息。
9. 消息处理函数 WndProc
1 | WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM |
- **
WndProc
**:窗口过程处理不同的消息,比如WM_CREATE
、WM_CLOSE
、WM_COMMAND
等,通过调用相应的函数(如OnCreate
、OnClose
)处理消息。
10. 创建按钮和编辑框(OnCreate
)
1 | OnCreate proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM |
- **
OnCreate
**:在窗口创建时调用,创建按钮和编辑框。 - **
@id
**:从 20000 开始递增,用于给每个按钮分配一个唯一的 ID。 - **
@x
和@y
**:用于计算按钮的坐标位置。 - 循环创建按钮:每个按钮的数字显示为
@num
,并通过CreateWindowEx
函数动态创建子窗口(按钮)。
我们继续从上次的地方逐行分析代码。接下来,我们着重分析与窗口创建和消息处理相关的部分。
11. OnCommand
处理不同的命令消息
1 | OnCommand proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM |
OnCommand
函数根据传递的wParam
来确定用户点击的按钮,并执行相应的操作:- **
ax == IDM_OPEN
**:如果命令是打开操作(IDM_OPEN
),则调用OnOpen
函数并显示对话框。 - **
ax >= 20000 && ax <= 20009
**:如果用户按了数字按钮,则将数字写入编辑框 (ASM_EDIT
) 中。wParam
包含按钮的ID
,这里通过减去 20000 获得按钮编号,并通过SetDlgItemInt
函数将该值显示在编辑框内。 ax == 20010
(即+
按钮):点击加号按钮时,获取当前编辑框中的数值,并将其保存在ASM_OP1
中。然后清空编辑框的内容,准备下一个操作数的输入。ax == 20011
(即=
按钮):当按下等号按钮时,获取当前编辑框中的数值并与ASM_OP1
的值相加,然后将结果显示在编辑框中。
- **
12. 创建窗口子元素 OnCreate
1 | OnCreate proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM |
- **
OnCreate
**:当窗口被创建时,会调用此函数来创建子窗口元素,比如按钮和编辑框。这里定义了一些局部变量用于控制窗口布局:- **
@id
**:从 20000 开始,用于分配给按钮的唯一ID
。 - **
@x
和@y
**:用于指定每个按钮的横纵坐标。 - **
@num
**:用于跟踪按钮上显示的数字。
- **
创建按钮和编辑框的过程
1 | mov @row,0 |
- 循环创建按钮:外层循环控制行(
@row
),内层循环控制列(@col
),每次循环都生成一个按钮。按钮的文本内容是数字@num
,使用sprintf
格式化到@buf
中。 - 按钮位置:按钮的
x
坐标是@col * 64
,y
坐标是@row * 64
,即每个按钮的大小为64x64
像素。 - 创建按钮:
CreateWindowEx
函数创建一个按钮,每个按钮都有唯一的ID
,从 20000 开始递增。
创建最后一行的按钮
1 | invoke crt_sprintf,addr @buf,offset ASM_FORMAT,9 |
9
按钮:在最后一行第一个位置创建了数字9
的按钮。+
和=
按钮:在第二和第三个位置分别创建了加号和等号按钮。- 编辑框:在最后一行创建了一个编辑框,占用了整行的宽度。
13. 消息处理函数 WndProc
1 | WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM |
WndProc
是窗口过程函数,负责处理各种窗口消息,比如:- **
WM_CLOSE
**:当窗口关闭时,调用OnClose
函数,销毁窗口。 - **
WM_DESTROY
**:当窗口被销毁时,调用OnDestroy
,发送退出消息。 - **
WM_CREATE
**:当窗口创建时,调用OnCreate
来生成按钮和编辑框。 - **
WM_COMMAND
**:当用户点击按钮或选择菜单项时,调用OnCommand
进行处理。
- **
- 如果没有特殊处理的消息,调用默认的窗口过程
DefWindowProc
进行处理。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hexo!