微机原理课程设计32位汇编学习之二(创建简单的窗口)

在桌面显示一个窗口的步骤:

  1. 得到您应用程序的句柄(必需);
  2. 得到命令行参数(如果您想从命令行得到参数,可选);
  3. 注册窗口类(必需,除非您使用 Windows 预定义的窗口类,如 MessageBox 或 dialog box;
  4. 产生窗口(必需);
  5. 在桌面显示窗口(必需,除非您不想立即显示它);
  6. 刷新窗口客户区;
  7. 进入无限的获取窗口消息的循环;
  8. 如果有消息到达,由负责该窗口的窗口回调函数处理;
  9. 如果用户关闭窗口,进行退出处理。

.386 ;告诉编译器程序使用80386指令集编写的
.model flat,stdcall ;告诉MASM 我们用的内存寻址模式,此处也可以加入stdcall告诉MASM我们所用的参数传递约定
option casemap:none ;告诉编译器要区分标号的大小写

include windows.inc ; windows.inc 包含了 WIN32 编程所需要的常量和结构体的定义。 但是它不包含函数原型的定义
include kernel32.inc ;函数原型声明的头文件 kernel.inc
includelib kernel32.lib ;仅仅是告诉编译器您的程序引用了哪个库
include user32.inc
includelib user32.lib

WinMain proto:DWORD,:DWORD,:DWORD,:DWORD


.data
 ClassName db "SimpleWinClass",0 ;Windows 类名
 AppName    db "Our First Window",0 ;窗口的名字
 
.data? ;存放未进行初始化的变量
 hInstance HINSTANCE ? ;代表应用程序的句柄
 CommandLine LPSTR ? ;保存从命令行传入的参数

.code
start:
 invoke GetModuleHandle,NULL ;查找我们应用程序的句柄,可以把实例句柄看成是您的应用程序的 ID 号,特别注意:WIN32下的实例句柄实际上是您应用程序在内存中的线性地址。WIN32 中函数的函数如果有返回值,那它是通过 eax 寄存器来传递的
 mov hInstance,eax
 invoke GetCommandLine  ;如果您的应用程序不处理命令行那么就无须调用 GetCommandLine,这里只是告诉您如果要调用应该怎么做
 mov CommandLine,eax
 invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
 invoke ExitProcess,eax
 
 
WinMain proc hInst:HINSTANCE,hPreInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
 
 LOCAL wc:WNDCLASSEX ;伪指令为局部变量在栈中分配内存空间,所有的 LOCAL 指令必须紧跟在 PROC 之后。LOCAL 后跟声明的变量,其形式是 变量名:变量类型。
 LOCAL msg:MSG  ;譬如 LOCAL wc:WNDCLASSEX 即是告诉 MASM 为名字叫 wc 的局部边量在栈中分配长度为 WNDCLASSEX 结构体长度的内存空间,然后我们在用该局部变量是无须考虑堆栈的问题
 LOCAL hwnd:HWND
 
  mov   wc.cbSize,SIZEOF WNDCLASSEX   ;窗口类(window class),一个窗口类就是一个有关窗口的规范,这个规范定义了几个主要的窗口的元素,如:图标、光标、背景色、和负责处理该窗口的函数。您产生一个窗口时就必须要有这样的一个窗口类
  mov   wc.style, CS_HREDRAW or CS_VREDRAW
  mov   wc.lpfnWndProc, OFFSET WndProc
  mov   wc.cbClsExtra,NULL
  mov   wc.cbWndExtra,NULL
  push  hInstance
  pop   wc.hInstance
  mov   wc.hbrBackground,COLOR_WINDOW+1
  mov   wc.lpszMenuName,NULL
         mov   wc.lpszClassName,OFFSET ClassName
         invoke LoadIcon,NULL,IDI_APPLICATION
         mov   wc.hIcon,eax
         mov   wc.hIconSm,eax
         invoke LoadCursor,NULL,IDC_ARROW
         mov   wc.hCursor,eax
         invoke RegisterClassEx, addr wc   ;注册窗口类                    
         invoke CreateWindowEx,NULL,/  ;注册窗口类后,我们将调用CreateWindowEx来产生实际的窗口。请注意该函数有12个参数
          ADDR ClassName,/
                ADDR AppName,/
                WS_OVERLAPPEDWINDOW,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                CW_USEDEFAULT,/
                NULL,/
                NULL,/
                hInst,/
                NULL
  mov   hwnd,eax  ;调用CreateWindowEx成功后,窗口句柄在eax中。我们必须保存该值以备后用。我们刚刚产生的窗口不会自动显示,所以必须调用 ShowWindow 来按照我们希望的方式来显示该窗口。接下来调用 UpdateWindow 来更新客户区。
  invoke ShowWindow, hwnd,CmdShow
  invoke UpdateWindow, hwnd
 
  .WHILE TRUE
   invoke GetMessage, ADDR msg,NULL,0,0
   .BREAK .IF (!eax)
   invoke TranslateMessage, ADDR msg ;TranslateMessage 函数是一个是实用函数,它从键盘接受原始按键消息,然后解释成 WM_CHAR,在把 WM_CHAR 放入消息队列,由于经过解释后的消息中含有按键的 ASCII 码,这比原始的扫描码好理解得多。如果您的应用程序不处理按键消息的话,可以不调用该函数
   invoke DispatchMessage, ADDR msg  ;DispatchMessage 会把消息发送给负责该窗口过程的函数
  .endw
   mov     eax,msg.wParam
 ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM  ;窗口处理函数
 
 .IF uMsg==WM_DESTROY                          
  invoke PostQuitMessage,NULL            
 .ELSE
  invoke DefWindowProc,hWnd,uMsg,wParam,lParam 
  ret
 .ENDIF
 xor eax,eax     
 ret
WndProc endp


end start

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值