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


返回上一頁