汇编语言实例:Windows图形化程序

下面通过实例来演示一下如何通过汇编语言来创建 Windows 图形化程序。不要担心这个程序的长度,其中大部分的代码在任何 MS-Windows 应用程序中都是一样的:
  1. ; Windows 应用程序 (WinApp.asm)
  2. ; 本程序显示一个可调大小的应用程序窗口和几个弹出消息框
  3. .386
  4. INCLUDE Irvine32.inc
  5. INCLUDE GraphWin.inc
  6.  
  7. ;==================== DATA =======================
  8. .data
  9.  
  10. AppLoadMsgTitle BYTE "Application Loaded",0
  11. AppLoadMsgText BYTE "This window displays when the WM_CREATE "
  12. BYTE "message is received",0
  13.  
  14. PopupTitle BYTE "Popup Window",0
  15. PopupText BYTE "This window was activated by a "
  16. BYTE "WM_LBUTTONDOWN message",0
  17.  
  18. GreetTitle BYTE "Main Window Active",0
  19. GreetText BYTE "This window is shown immediately after "
  20. BYTE "CreateWindow and UpdateWindow are called.",0
  21.  
  22. CloseMsg BYTE "WM_CLOSE message received",0
  23.  
  24. ErrorTitle BYTE "Error",0
  25. WindowName BYTE "ASM Windows App",0
  26. className BYTE "ASMWin",0
  27.  
  28. ; 定义应用程序的窗口类结构
  29. MainWin WNDCLASS <NULL,WinProc,NULL,NULL,NULL,NULL,NULL, \
  30. COLOR_WINDOW,NULL,className>
  31.  
  32. msg MSGStruct <>
  33. winRect RECT <>
  34. hMainWnd DWORD ?
  35. hInstance DWORD ?
  36.  
  37. ;=================== CODE =========================
  38. .code
  39. WinMain PROC
  40. ; 获得当前过程的句柄
  41. INVOKE GetModuleHandle, NULL
  42. mov hInstance, eax
  43. mov MainWin.hInstance, eax
  44.  
  45. ; 加载程序的图标和光标
  46. INVOKE LoadIcon, NULL, IDI_APPLICATION
  47. mov MainWin.hIcon, eax
  48. INVOKE LoadCursor, NULL, IDC_ARROW
  49. mov MainWin.hCursor, eax
  50.  
  51. ; 注册窗口类
  52. INVOKE RegisterClass, ADDR MainWin
  53. .IF eax == 0
  54. call ErrorHandler
  55. jmp Exit_Program
  56. .ENDIF
  57.  
  58. ; 创建应用程序的主窗口
  59. INVOKE CreateWindowEx, 0, ADDR className,
  60. ADDR WindowName,MAIN_WINDOW_STYLE,
  61. CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
  62. CW_USEDEFAULT,NULL,NULL,hInstance,NULL
  63. mov hMainWnd,eax
  64.  
  65. ; 若 CreateWindowEx 失败,则显示消息并退出
  66. .IF eax == 0
  67. call ErrorHandler
  68. jmp Exit_Program
  69. .ENDIF
  70.  
  71. ; 保存窗口句柄,显示并绘制窗口
  72. INVOKE ShowWindow, hMainWnd, SW_SHOW
  73. INVOKE UpdateWindow, hMainWnd
  74.  
  75. ; 显示欢迎消息
  76. INVOKE MessageBox, hMainWnd, ADDR GreetText,
  77. ADDR GreetTitle, MB_OK
  78.  
  79. ; 启动程序的连续消息处理循环
  80. Message_Loop:
  81. ; 从队列中取出下一条消息
  82. INVOKE GetMessage, ADDR msg, NULL,NULL,NULL
  83.  
  84. ; 若没有其他消息则退出
  85. .IF eax == 0
  86. jmp Exit_Program
  87. .ENDIF
  88.  
  89. ; 将消息传递给程序的 WinProc
  90. INVOKE DispatchMessage, ADDR msg
  91. jmp Message_Loop
  92.  
  93. Exit_Program:
  94. INVOKE ExitProcess,0
  95. WinMain ENDP
  96.  
  97. ;-----------------------------------------------------
  98. WinProc PROC,
  99. hWnd:DWORD, localMsg:DWORD, wParam:DWORD, lParam:DWORD
  100. ; 应用程序的消息处理过程,处理应用程序特定的消息。
  101. ; 其他所有消息则传递给默认的 windows 消息处理过程
  102. ;-----------------------------------------------------
  103. mov eax, localMsg
  104.  
  105. .IF eax == WM_LBUTTONDOWN ; 鼠标按钮?
  106. INVOKE MessageBox, hWnd, ADDR PopupText,
  107. ADDR PopupTitle, MB_OK
  108. jmp WinProcExit
  109. .ELSEIF eax == WM_CREATE ; 创建窗口?
  110. INVOKE MessageBox, hWnd, ADDR AppLoadMsgText,
  111. ADDR AppLoadMsgTitle, MB_OK
  112. jmp WinProcExit
  113. .ELSEIF eax == WM_CLOSE ; 关闭窗口?
  114. INVOKE MessageBox, hWnd, ADDR CloseMsg,
  115. ADDR WindowName, MB_OK
  116. INVOKE PostQuitMessage,0
  117. jmp WinProcExit
  118. .ELSE ; 其他消息?
  119. INVOKE DefWindowProc, hWnd, localMsg, wParam, lParam
  120. jmp WinProcExit
  121. .ENDIF
  122.  
  123. WinProcExit:
  124. ret
  125. WinProc ENDP
  126.  
  127. ;---------------------------------------------------
  128. ErrorHandler PROC
  129. ; 显示合适的系统错误消息
  130. ;---------------------------------------------------
  131. .data
  132. pErrorMsg DWORD ? ; 错误消息指针
  133. messageID DWORD ?
  134. .code
  135. INVOKE GetLastError ; 用EAX返回消息ID
  136. mov messageID,eax
  137.  
  138. ; 获取相应的消息字符串
  139. INVOKE FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + \
  140. FORMAT_MESSAGE_FROM_SYSTEM,NULL,messageID,NULL,
  141. ADDR pErrorMsg,NULL,NULL
  142.  
  143. ; 显示错误消息
  144. INVOKE MessageBox,NULL, pErrorMsg, ADDR ErrorTitle,
  145. MB_ICONERROR+MB_OK
  146.  
  147. ; 释放错误消息字符串
  148. INVOKE LocalFree, pErrorMsg
  149. ret
  150. ErrorHandler ENDP
  151.  
  152. END WinMain

运行程序

第一次加载程序时,显示如下消息框:


当用户点击 OK 来关闭 Application Loaded 消息框时,则显示另一个消息框:


当用户关闭 Main Window Active 消息框时,就会显示程序的主窗口 :


当用户在主窗口的任何位置点击鼠标时,显示如下消息框:


当用户关闭该消息框,并点击主窗口右上角上的 X 时,那么在窗口关闭之前将显示如下消息框:


当用户关闭了这个消息框后,则程序结束。