Netwide Assembler (NASM) >> Assembly (x86) >> Win32 API >> Dialog
Create Window
參考資訊:
1. nasm
2. masm32
Windows的視窗可以分成:Dialog、Single Document Interface(SDI)、Multiple Document Interface(MDI)三種類別,相較於SDI、MDI這兩類別的程式,Dialog類別是比較容易上手學習的一個類別,相當適合初學者入門學習,而Windows程式設計的精髓就是,學會其中一個類別,其餘類別都可以很容易上手,Windows控制項(如:Button、Edit)也是此類道理,比較需要注意的是,Windows視窗程式設計的核心是圍繞着事件處理(處理Message),任何的視窗設定或者溝通都是以事件導向為原則,因此,寫出一個簡單的視窗框架,將有助於了解Windows視窗程式的運作
main.asm
[bits 32] global _start extern _ExitProcess@4 extern _GetMessageA@16 extern _MessageBoxA@16 extern _GetCommandLineA@0 extern _CreateWindowExA@48 extern _GetModuleHandleA@4 extern _DispatchMessageA@4 %define GetMessage _GetMessageA@16 %define MessageBox _MessageBoxA@16 %define ExitProcess _ExitProcess@4 %define GetCommandLine _GetCommandLineA@0 %define CreateWindowEx _CreateWindowExA@48 %define GetModuleHandle _GetModuleHandleA@4 %define DispatchMessage _DispatchMessageA@4 struc POINT .x: resd 1 .y: resd 1 .SIZE: endstruc struc MSG .hwnd: resd 1 .message: resd 1 .wParam: resd 1 .lParam: resd 1 .time: resd 1 .pt: resb POINT.SIZE .SIZE: endstruc WC_DIALOG equ 8002h SW_SHOWNORMAL equ 1h WS_OVERLAPPED equ 0h WS_CAPTION equ 0c00000h WS_SYSMENU equ 80000h WS_THICKFRAME equ 40000h WS_MINIMIZEBOX equ 20000h WS_MAXIMIZEBOX equ 10000h WS_VISIBLE equ 10000000h WS_EX_LEFT equ 00000000h WS_OVERLAPPEDWINDOW equ WS_OVERLAPPED | \ WS_CAPTION | \ WS_SYSMENU | \ WS_THICKFRAME | \ WS_MINIMIZEBOX | \ WS_MAXIMIZEBOX section .drectve info _entry db "/entry:start " _gdi32 db "/defaultlib:c:\\masm32\\lib\\gdi32.lib " _user32 db "/defaultlib:c:\\masm32\\lib\\user32.lib " _kernel32 db "/defaultlib:c:\\masm32\\lib\\kernel32.lib " segment .data szCaption db "main",0 hInstance dd 0 CommandLine dd 0 msg istruc MSG at .hwnd, dd 0 at .message, dd 0 at .wParam, dd 0 at .lParam, dd 0 at .time, dd 0 at .pt, dd 0, 0 iend segment .text WinMain: push ebp mov ebp, esp push 0 push 0 push 0 push 0 push 300 push 300 push 0 push 0 push WS_OVERLAPPEDWINDOW | WS_VISIBLE push szCaption push WC_DIALOG push WS_EX_LEFT call CreateWindowEx .loop: push 0 push 0 push 0 push msg call GetMessage cmp eax, 0 je .exit push msg call DispatchMessage jmp .loop .exit: mov eax, [msg + MSG.wParam] leave ret 16 _start: push 0 call GetModuleHandle mov [hInstance], eax call GetCommandLine mov [CommandLine], eax push SW_SHOWNORMAL push dword [CommandLine] push 0 push dword [hInstance] call WinMain push eax call ExitProcess
Line 20~34:struc用來定義Struct
Line 64~71:istruc則是宣告資料(Instance)的意思,at用來指定初始化的資料內容,如果沒有想要做資料初始化,可以省略at
Line 78~90:在建立Windows視窗時,需要指定對應的Class,如:Edit、Button,除了可以使用系統預設的Class之外,也可以註冊自定義的Class,上面例子使用的WC_DIALOG,就是系統預設定義的Dialog Class,WS_OVERLAPPEDWINDOW代表視窗有標題、最大化、最小化的按鈕,WS_VISIBLE是建立一個可視化的視窗
Line 93~97:從Queue提取Message(包含視窗、系統事件)
Line 101~102:分發Message到處理視窗事件的副程式,由於目前的Dialog視窗並沒有對應的處理副程式,因此,無法處理任何Message,包含關閉視窗的Message,所以執行後,必須使用kill命令強制關閉該視窗
Line 111~116:一般習慣是在程式進入時,保存Instance、CommandLine的內容
Line 118~122:呼叫自定義的WinMain(),模擬C語言的WinMain(),當然也可以把內容都寫在start()裡面
Makefile
export WINEPREFIX=/home/user/.wine_amd64 TARGET=main MYWINE=box86 wine NASM32=/home/user/.wine_amd64/drive_c/nasm MASM32=/home/user/.wine_amd64/drive_c/masm32 all: ${MYWINE} ${NASM32}/bin/nasm.exe -fwin32 ${TARGET}.asm ${MYWINE} ${MASM32}/bin/link.exe /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text ${TARGET}.obj run: ${MYWINE} ${TARGET}.exe clean: rm -rf ${TARGET}.exe ${TARGET}.obj
編譯、執行
$ make $ make run