.386 ;告诉编译器程序所用指令集,(.386P)带P表示使用特权级指令。
.model flat,stdcall;内存模式平坦的4G空间
                   ;参数传递方式C从右往左,调用者恢复堆栈指针。
                   ;PSCAL从左往右,被调用者恢复堆栈指针。
                   ;stdcall从右往左传递,但是堆栈指针由被调用者恢复。
option casemap:none;区分标志的大小写
include windows.inc;各种常量,宏的定义 
include user32.inc 
includelib user32.lib            ; calls to functions 
in user32.lib and kernel32.lib 
include kernel32.inc 
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib

RGB macro Red,Green,Blue 
    xor eax,eax
    mov ah,Blue
    shl eax,
8
    mov ah,Green
    mov al,Red
endm

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 

.DATA                     ; initialized data 
ClassName db 
"SimpleWinClass",0        ; the name of our window class 
AppName db 
"Our First Window",0        ; the name of our window 
OurText db 
"彭小虎是个SB!",0           ; the text of our client
FontName db 
"script",0
MouseClick db 
0

.DATA
?                    ; Uninitialized data 
hInstance HINSTANCE 
?        ; Instance handle of our program 
CommandLine LPSTR 
?
hitpoint POINT 
<>
.CODE                ; Here begins our code 
start: 
invoke GetModuleHandle, NULL            ; 获取一个应用程序或动态链接库的模块句柄,返回值存储在eax
                                                                       ; Under Win32, hmodule
==hinstance mov hInstance,eax 
mov hInstance,eax 
invoke GetCommandLine                        ; 获得指向当前命令行缓冲区的一个指针 
                                                                    
mov CommandLine,eax 
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function,第三个参数表示窗口初始状态 
invoke ExitProcess, eax                           ; quit our program. The exit code 
is returned in eax from WinMain. 
;
---------------------------------------------------------------------------
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
    LOCAL wc:WNDCLASSEX                                            ; create local variables on stack 
    LOCAL msg:MSG 
    LOCAL hwnd:HWND

    mov   wc.cbSize,SIZEOF WNDCLASSEX                   ; fill values 
in members of wc 
    mov   wc.style, CS_HREDRAW or CS_VREDRAW 
    mov   wc.lpfnWndProc, OFFSET WndProc 
    mov   wc.cbClsExtra,NULL 
    mov   wc.cbWndExtra,NULL 
    push  hInstance 
    pop   wc.hInstance 
    mov   wc.hbrBackground,COLOR_WINDOW
+1 
    mov   wc.lpszMenuName,NULL 
    mov   wc.lpszClassName,OFFSET ClassName 
    invoke LoadIcon,NULL,IDI_APPLICATION 
    mov   wc.hIcon,eax 
    mov   wc.hIconSm,eax 
    invoke LoadCursor,NULL,IDC_ARROW 
    mov   wc.hCursor,eax 
    invoke RegisterClassEx, addr wc                       ; register our window 
class 
    invoke CreateWindowEx,NULL,\ 
                ADDR ClassName,\ ;窗口类名
                ADDR AppName,\   ;窗口标题栏名
                WS_OVERLAPPEDWINDOW,\ ;窗口样式
                ;窗口位置与高宽设置
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                CW_USEDEFAULT,\ 
                NULL,\ ;双亲句柄
                NULL,\ ;菜单句柄
                hInst,\ ;实例句柄
                NULL 
    mov   hwnd,eax 
    invoke ShowWindow, hwnd,CmdShow               ; display our window on desktop 
    invoke UpdateWindow, hwnd                                 ; refresh the client area 

    .WHILE TRUE                                                         ; Enter message loop 
                invoke GetMessage, ADDR msg,NULL,
0,0 
                .BREAK.IF (
!eax)
                invoke TranslateMessage, ADDR msg 
                invoke DispatchMessage, ADDR msg 
   .ENDW 
    mov     eax,msg.wParam                                            ; 
return exit code in eax 
    ret 
WinMain endp 
;
---------------------------------------------------------------------------
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
    LOCAL hdc:HDC
    LOCAL ps:PAINTSTRUCT
   
    LOCAL hfont:HFONT

    .IF uMsg
==WM_DESTROY                           ; if the user closes our window 
        invoke PostQuitMessage,NULL             ; quit our application 

    .ELSEIF uMsg
==WM_LBUTTONDOWN
        mov eax,lParam
        and eax,0FFFFh 
        mov hitpoint.x,eax 
        mov eax,lParam 
        shr eax,
16 
        mov hitpoint.y,eax 
        mov MouseClick,TRUE 
        invoke InvalidateRect,hWnd,NULL,TRUE  

        .ELSEIF uMsg
==WM_PAINT
        invoke BeginPaint,hWnd,ADDR ps          ;返回设备句柄
        mov hdc,eax                             ;取得设备句柄
        invoke CreateFont,
50,16,270,0,FW_DEMIBOLD,0,0,0,GB2312_CHARSET,\ 
                                       OUT_CHARACTER_PRECIS,CLIP_DEFAULT_PRECIS,\ 
                                       DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\ 
                                       ADDR FontName 
        invoke SelectObject,hdc,eax
        mov hfont,eax;保存
        RGB    
8,80,8
        invoke SetBkColor,hdc,eax 
        invoke TextOut,hdc,
80,120,ADDR OurText,SIZEOF OurText
        invoke SelectObject,hdc, hfont;恢复

        .IF MouseClick 
            invoke lstrlen,ADDR OurText 
            invoke TextOut,hdc,hitpoint.x,hitpoint.y,ADDR OurText,eax
        .ENDIF

        invoke EndPaint,hWnd, ADDR ps 
    .ELSE 
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing 
        ret 
    .ENDIF 
    xor eax,eax 
    ret 
WndProc endp 
;
---------------------------------------------------------------------------
end start