Win32汇编:创建Win32窗体

1.一个最简单的窗体的创建

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386
        .model flat,stdcall
        option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows.inc
include        gdi32.inc
includelib    gdi32.lib
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?
hInstance    dd        ?
hWinMain    dd        ?

    .const

szClassName db MyClass,0
szCaptionMain db
My first Window !,0
szText db
Win32 Assembly, Simple and powerful !,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
代码段
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
窗口过程
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
local
@stPs:PAINTSTRUCT
local
@stRect:RECT
local @hDc

    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    eax,uMsg

;********************************************************************
.if eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax

        invoke    GetClientRect,hWnd,addr @stRect
        invoke    DrawText,@hDc,addr szText,-</span><span style="color: #800080;">1</span><span style="color: #000000;">,\
            addr @stRect,\
            DT_SINGLELINE </span><span style="color: #0000ff;">or</span> DT_CENTER <span style="color: #0000ff;">or</span><span style="color: #000000;"> DT_VCENTER

        invoke    EndPaint,hWnd,addr @stPs

;
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;

.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret

_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local
@stWndClass:WNDCLASSEX
local
@stMsg:MSG

    invoke    GetModuleHandle,NULL
    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    hInstance,eax
    invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

;
;
注册窗口类
;

invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;
;
建立并显示窗口
;

invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,
WS_OVERLAPPEDWINDOW,
100,100,600,400,
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;
;
消息循环
;

.while TRUE
invoke GetMessage,addr @stMsg,NULL,
0,0
.break .if eax ==
0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start

View Code

 

2.在窗体上添加一个按钮

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .386
        .model flat,stdcall
        option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include        windows.inc
include        gdi32.inc
includelib    gdi32.lib
include        user32.inc
includelib    user32.lib
include        kernel32.inc
includelib    kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        .data?

hInstance dd ?
hWinMain dd ?

    .const

szClassName db MyClass,0
szCaptionMain db
My first Window !,0
szText db
Win32 Assembly, Simple and powerful !,0
szButton db
button,0
szButtonText db
&OK,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
代码段
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
窗口过程
;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
local
@stPs:PAINTSTRUCT
local
@stRect:RECT
local @hDc

    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    eax,uMsg

;********************************************************************
.if eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax

        invoke    GetClientRect,hWnd,addr @stRect
        invoke    DrawText,@hDc,addr szText,-</span><span style="color: #800080;">1</span><span style="color: #000000;">,\
            addr @stRect,\
            DT_SINGLELINE </span><span style="color: #0000ff;">or</span> DT_CENTER <span style="color: #0000ff;">or</span><span style="color: #000000;"> DT_VCENTER

        invoke    EndPaint,hWnd,addr @stPs

;
;
建立一个按钮
;

.elseif eax == WM_CREATE
invoke CreateWindowEx,NULL,
offset szButton,offset szButtonText,
WS_CHILD
or WS_VISIBLE,
10,10,65,22,
hWnd,
1,hInstance,NULL
;
.elseif eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
;

.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret

_ProcWinMain endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local
@stWndClass:WNDCLASSEX
local
@stMsg:MSG

    invoke    GetModuleHandle,NULL
    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    hInstance,eax
    invoke    RtlZeroMemory,addr @stWndClass,sizeof @stWndClass

;
;
注册窗口类
;

invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
;
;
建立并显示窗口
;

invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,
WS_OVERLAPPEDWINDOW,
100,100,600,400,
NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;
;
消息循环
;

.while TRUE
invoke GetMessage,addr @stMsg,NULL,
0,0
.break .if eax ==
0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret

_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start

View Code

 

3.自定位代码生成的窗口

; RemoteCode.asm
; 一段自定位的代码,可以用来创建一个窗口
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
REMOTE_CODE_START    equ this byte

_lpLoadLibrary dd ? ;导入函数地址表
_lpGetProcAddress dd ?
_lpGetModuleHandle dd ?

_lpDestroyWindow dd ?
_lpPostQuitMessage dd ?
_lpDefWindowProc dd ?
_lpLoadCursor dd ?
_lpRegisterClassEx dd ?
_lpCreateWindowEx dd ?
_lpShowWindow dd ?
_lpUpdateWindow dd ?
_lpGetMessage dd ?
_lpTranslateMessage dd ?
_lpDispatchMessage dd ?

_hInstance dd ?
_hWinMain dd ?
_szClassName db RemoteClass,0
_szCaptionMain db
RemoteWindow,0
_szDllUser db
User32.dll,0
_szDestroyWindow db
DestroyWindow,0
_szPostQuitMessage db
PostQuitMessage,0
_szDefWindowProc db
DefWindowProcA,0
_szLoadCursor db
LoadCursorA,0
_szRegisterClassEx db
RegisterClassExA,0
_szCreateWindowEx db
CreateWindowExA,0
_szShowWindow db
ShowWindow,0
_szUpdateWindow db
UpdateWindow,0
_szGetMessage db
GetMessageA,0
_szTranslateMessage db
TranslateMessage,0
_szDispatchMessage db
DispatchMessageA,0,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_RemoteThread proc uses ebx edi esi lParam
local @hModule

    </span><span style="color: #0000ff;">call</span><span style="color: #000000;">    @F
    </span><span style="color: #008080;">@@:</span>
    <span style="color: #0000ff;">pop</span><span style="color: #000000;">    ebx
    </span><span style="color: #0000ff;">sub</span><span style="color: #000000;">    ebx,offset @B

;
_invoke [ebx + _lpGetModuleHandle],NULL
mov [ebx + _hInstance],eax
lea eax,[ebx + offset _szDllUser]
_invoke [ebx + _lpGetModuleHandle],eax
mov @hModule,eax
lea esi,[ebx + offset _szDestroyWindow]
lea edi,[ebx + offset _lpDestroyWindow]
.while TRUE
_invoke [ebx + _lpGetProcAddress],@hModule,esi
mov [edi],eax
add edi,4
@@:
lodsb
or al,al
jnz @B
.break .if ! byte ptr [esi]
.endw
;

call _WinMain
ret

_RemoteThread endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam

    </span><span style="color: #0000ff;">call</span><span style="color: #000000;">    @F
    </span><span style="color: #008080;">@@:</span>
    <span style="color: #0000ff;">pop</span><span style="color: #000000;">    ebx
    </span><span style="color: #0000ff;">sub</span><span style="color: #000000;">    ebx,offset @B

;
mov eax,uMsg
.if eax == WM_CLOSE
_invoke [ebx + _lpDestroyWindow],hWnd
_invoke [ebx + _lpPostQuitMessage],NULL
;

.else
_invoke [ebx + _lpDefWindowProc],hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
xor eax,eax
ret

_ProcWinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ZeroMemory proc _lpDest,_dwSize

    </span><span style="color: #0000ff;">push</span><span style="color: #000000;">    edi
    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    edi,_lpDest
    </span><span style="color: #0000ff;">mov</span><span style="color: #000000;">    ecx,_dwSize
    </span><span style="color: #0000ff;">xor</span><span style="color: #000000;">    eax,eax
    </span><span style="color: #0000ff;">cld</span>
    <span style="color: #0000ff;">rep</span>    <span style="color: #0000ff;">stosb</span>
    <span style="color: #0000ff;">pop</span><span style="color: #000000;">    edi
    </span><span style="color: #0000ff;">ret</span><span style="color: #000000;">

_ZeroMemory endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc uses ebx esi edi _lParam
local
@stWndClass:WNDCLASSEX
local
@stMsg:MSG

    </span><span style="color: #0000ff;">call</span><span style="color: #000000;">    @F
    </span><span style="color: #008080;">@@:</span>
    <span style="color: #0000ff;">pop</span><span style="color: #000000;">    ebx
    </span><span style="color: #0000ff;">sub</span><span style="color: #000000;">    ebx,offset @B

;
invoke _ZeroMemory,addr @stWndClass,sizeof @stWndClass
_invoke [ebx + _lpLoadCursor],
0,IDC_ARROW
mov @stWndClass.hCursor,eax
push [ebx + _hInstance]
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
lea eax,[ebx + offset _ProcWinMain]
mov @stWndClass.lpfnWndProc,eax
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
lea eax,[ebx + offset _szClassName]
mov @stWndClass.lpszClassName,eax
lea eax,@stWndClass
_invoke [ebx + _lpRegisterClassEx],eax
;

;
建立并显示窗口
;

lea eax,[ebx + offset _szClassName]
lea ecx,[ebx + offset _szCaptionMain]
_invoke [ebx + _lpCreateWindowEx],WS_EX_CLIENTEDGE,eax,ecx,
WS_OVERLAPPEDWINDOW,
100,100,600,400,
NULL,NULL,[ebx + _hInstance],NULL
mov [ebx + _hWinMain],eax
_invoke [ebx + _lpShowWindow],[ebx + _hWinMain],SW_SHOWNORMAL
_invoke [ebx + _lpUpdateWindow],[ebx + _hWinMain]
;

;
消息循环
;
********************************************************************
.while TRUE
lea eax,@stMsg
_invoke [ebx + _lpGetMessage],eax,NULL,
0,0
.break .if eax ==
0
lea eax,@stMsg
_invoke [ebx + _lpTranslateMessage],eax
lea eax,@stMsg
_invoke [ebx + _lpDispatchMessage],eax
.endw
ret

_WinMain endp
REMOTE_CODE_END equ this byte
REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View Code

 

代码摘抄:琢石成器-Win32汇编语言程序设计 仅供收藏