▶ 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互
● 代码,四种消息框
1 INCLUDE Irvine32.inc 2 3 .data 4 captionW BYTE "Warning", 0 ; 标题 5 warningMsg BYTE "皮一下很开心", 0 ; 消息框内容,支持 Unicode 6 7 captionQ BYTE "Question", 0 8 questionMsg BYTE "皮一下很开心?", 0 9 10 captionC BYTE "Information", 0 11 infoMsg BYTE "那皮一下?", 0dh, 0ah, "不皮也行", 0 12 13 captionH BYTE "Halt", 0 14 haltMsg BYTE "没皮成,被打了", 0 15 16 .code 17 main PROC 18 INVOKE MessageBox, NULL, ADDR warningMsg, ADDR captionW, MB_OK + MB_ICONEXCLAMATION ; 警告图标,OK 按钮 19 20 INVOKE MessageBox, NULL, ADDR questionMsg, ADDR captionQ, MB_YESNO + MB_ICONQUESTION ; 问号图标,Yes / No 按钮 21 cmp eax, IDYES ; 返回值在 eax 中 22 23 INVOKE MessageBox, NULL, ADDR infoMsg, ADDR captionC, MB_YESNOCANCEL + MB_ICONINFORMATION + MB_DEFBUTTON2 ; i 图标,Yes / No / Cancel 按钮 24 25 INVOKE MessageBox, NULL, ADDR haltMsg, ADDR captionH, MB_OK + MB_ICONSTOP ; 叉叉图标, OK 按钮 26 27 call WaitMsg 28 exit 29 main ENDP 30 END main
● 使用 ReadConsole 从终端输入
1 INCLUDE Irvine32.inc 2 3 BufSize = 80 4 5 .data 6 buffer BYTE BufSize DUP(?) 7 stdInHandle HANDLE ? 8 bytesRead DWORD ? 9 10 .code 11 main PROC 12 INVOKE GetStdHandle, STD_INPUT_HANDLE 13 mov stdInHandle, eax ; 注意保存返回的句柄 14 INVOKE ReadConsole, stdInHandle, ADDR buffer, BufSize, ADDR bytesRead, 0 ; 参数分别为:句柄,存储内存地址,最大字符数,未使用 15 16 mov esi, OFFSET buffer ; 显示保存的字符串 17 mov ecx, bytesRead 18 mov ebx, TYPE buffer 19 call DumpMem ; 注意结尾有 0Dh, 0Ah,即为 "\r\n", 0 20 21 call WaitMsg 22 exit 23 main ENDP 24 END main
● 使用WriteConsole 输出到终端,参数与输入差不多
1 INCLUDE Irvine32.inc 2 3 .data 4 endl EQU <0dh,0ah> ; 换行符 5 6 message LABEL BYTE BYTE "Some words", endl 7 messageSize DWORD ($-message) 8 9 consoleHandle HANDLE 0 10 bytesWritten DWORD ? 11 12 .code 13 main PROC 14 INVOKE GetStdHandle, STD_OUTPUT_HANDLE 15 mov consoleHandle,eax 16 17 INVOKE WriteConsole, consoleHandle, ADDR message, messageSize, ADDR bytesWritten, 0 18 19 call waitmsg 20 INVOKE ExitProcess, 0 21 main ENDP 22 END main
● 键盘单键测试
1 INCLUDE Irvine32.inc 2 INCLUDE Macros.inc 3 4 .code 5 main PROC 6 INVOKE GetKeyState, VK_NUMLOCK ; 检测数字键盘锁定状态 7 call DumpRegs 8 test al, 1 9 .IF !Zero? 10 mWrite <"NumLock ON",0dh,0ah> 11 .ELSE 12 mWrite <"NumLock OFF",0dh,0ah> 13 .ENDIF 14 15 INVOKE GetKeyState, VK_LSHIFT ; 检测左 Shift 锁定状态 16 call DumpRegs 17 test eax, 80000000h 18 .IF !Zero? 19 mWrite <"L-Shift DOWN",0dh,0ah> 20 .ELSE 21 mWrite <"L-Shift UP",0dh,0ah> 22 .ENDIF 23 24 call WaitMsg 25 exit 26 main ENDP 27 END main
● 文件读写(有点问题,尚未完成)
1 INCLUDE Irvine32.inc 2 INCLUDE macros.inc 3 4 BUFFER_SIZE = 500 5 6 .data 7 buffer BYTE "abcdef", 0 8 filename BYTE "output.txt", 0 9 fileHandle HANDLE ? 10 stringLength DWORD ? 11 bytesWritten DWORD ? 12 13 .code 14 main PROC 15 16 mov edx, OFFSET filename 17 call CreateOutputFile 18 mov fileHandle, eax 19 cmp eax, INVALID_HANDLE_VALUE ; 错误检查 20 jne file_ok1 21 mWrite <"Failed to create output file",0dh,0ah> 22 jmp quit 23 24 file_ok1: 25 mov eax, fileHandle ; 写入文件 26 mov edx, OFFSET buffer 27 mov ecx, SIZEOF buffer 28 call WriteToFile 29 mov bytesWritten, eax ; 返回写入字符串长度 30 call CloseFile 31 32 mWrite <"Bytes written to file [output.txt]: "> ; 显示写入字符串长度 33 mov eax, bytesWritten 34 call WriteDec 35 call Crlf 36 call WaitMsg 37 38 mov eax, SIZEOF filename ; 打开文件 39 mov edx, OFFSET filename 40 call OpenInputFile 41 mov fileHandle, eax 42 43 cmp eax, INVALID_HANDLE_VALUE ; 错误检查 44 jne file_ok2 45 mWrite <"Failed to open the file",0dh,0ah> 46 jmp quit 47 48 file_ok2: 49 mov edx, OFFSET buffer ; 读取文件 50 mov ecx, BUFFER_SIZE 51 call ReadFromFile 52 jnc check_buffer_size 53 mWrite <"Failed to read the file.", 0dh, 0ah> 54 call WriteWindowsMsg 55 jmp close_file 56 57 check_buffer_size: ; 检查是否超出缓冲区大小 58 cmp eax, BUFFER_SIZE 59 jb buf_size_ok 60 mWrite <"Failed to read the file into buffer", 0dh, 0ah> 61 jmp quit 62 63 buf_size_ok: 64 mov buffer[eax],0 ; insert null terminator 65 mWrite "File size: " 66 call WriteDec ; display file size 67 call Crlf 68 69 mWrite <"Buffer:",0dh,0ah,0dh,0ah> 70 mov edx,OFFSET buffer ; display the buffer 71 call WriteString 72 call Crlf 73 74 close_file: 75 mov eax, fileHandle 76 call CloseFile 77 78 quit: 79 call WaitMsg 80 exit 81 main ENDP 82 END main