.386 ;用于告诉编译器在本程序中使用的指令集 ,使用特权指令 .386p
.Model Flat,StdCall ;用来定义程序工作的模式 / stdcall是子程序的调用方式,它指出调用子程序或WIN32 API时参数传递的次序和堆栈平衡的方法
Option CaseMap:None ;定义程序的变量和子程序名是否对大小写敏感,Win32 API中的API名称是区分大小写的
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include gdi32.inc
include user32.inc
include kernel32.inc ;函数的预先声明
includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib ;DLL库正确的定位信息
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
.const
szClassName db 'MyClass',0
szCaptionMain db 'My First Winddow !', 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
mov eax, uMsg
;Windows内部将ebx edi esi ebp 寄存器当作指针使用,如果返回时改变了他们的值,程序会马上崩溃。proc后面的uses伪操作在子程序进入和退出
;时自动安插push和pop寄存器指令,来保护这些寄存器的值。所有应用程序提供给Windows的回调函数都必须遵循这个规定。
;hWnd为窗口句柄
;uMsg为消息标识,指定的消息有一定的范围,Windows标志窗口中已经预定义的值在 0~03ffh之间,用户可以通过SendMessage等函数传给窗口过程
;做自定义的处理工作。这时的值从0400h开始, 技巧: WM_USER就定义为00000400h,当程序员定义多个用户消息的时候,一般使用 WM_USER+1
;WM_USER+2
;wParam和lParam参数是消息所附属的参数,随消息的不同而不同,从手册中查明
;***************************************************************
.if eax == WM_PAINT
invoke BeginPaint, hWnd, addr @stPs
mov @hDc, eax
invoke GetClientRect ,hWnd,addr @stRect
invoke DrawText ,@hDc, addr szText,-1,/
addr @stRect,/
DT_SINGLELINE or DT_CENTER or 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
;HMODULE GetModuleHandle(
; LPCTSTR lpModuleName // address of module name to return handle for
; )
;使用参数NULL调用GetModuleHandle,那么得到的是调用者本模块的句柄,如果要获得其他模块的句柄,要取模块的地址,即在前面加addr
;句柄的定义:Windows用来表示各种资源的编号
mov hInstance, eax
invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass
; VOID RtlZeroMemory
; (
; VOID* Destination,
; SIZE_T Length
; ) Set a block of memory with 0's
;************************************************************************
;注册窗口类
;************************************************************************
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 ;when use the color value you must be add 1 with value
mov @stWndClass.lpszClassName, offset szClassName
invoke RegisterClassEx ,addr @stWndClass
;HCURSOR LoadCursor(
; HINSTANCE hInstance, // handle of application instance
; LPCTSTR lpCursorName // name string or cursor resource identifier
; );
;Value Description
;IDC_APPSTARTING Standard arrow and small hourglass
;IDC_ARROW Standard arrow //can try different value
;WNDCLASSEX
;The WNDCLASSEX structure contains window class information.
;It is used with the the RegisterClassEx and GetClassInfoEx functions.
;typedef struct _WNDCLASSEX {
; UINT cbSize; //Specifies the size, in bytes, of this structure.
; UINT style; //Specifies the class style(s) also can try to use differnt values
; WNDPROC lpfnWndProc; //Points to the window procedure.
; int cbClsExtra;
; int cbWndExtra;
; HANDLE hInstance; //Identifies the instance that the window procedure of this class is within.
; HICON hIcon; //Identifies the class icon.
; HCURSOR hCursor; //dentifies the class cursor.
; HBRUSH hbrBackground; //dentifies the class background brush.
; LPCTSTR lpszMenuName;
; LPCTSTR lpszClassName; //If lpszClassName is a string, it specifies the window class name.
; HICON hIconSm; //Handle to a small icon that is associated with the window class.
;} WNDCLASSEX;
;*********************************************************
;建立并显示窗口
;****************************************************
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
;****************************
;HWND CreateWindowEx(
;
; DWORD dwExStyle, // extended window style
; LPCTSTR lpClassName, // pointer to registered class name
; LPCTSTR lpWindowName, // pointer to window name 指向表示窗口名称的字符串,其指向的字符会出现在标题栏上
; DWORD dwStyle, // window style
; ;int x, // horizontal position of window
; int y, // vertical position of window
; int nWidth, // window width
; int nHeight, // window height
; HWND hWndParent, // handle to parent or owner window
; HMENU hMenu, // handle to menu, or child-window identifier
; HINSTANCE hInstance, // handle to application instance
; LPVOID lpParam // pointer to window-creation data
; );
;****************************
;****************************
;BOOL ShowWindow(
;
; HWND hWnd, // handle of window
; int nCmdShow // show state of window
; );
;****************************
;****************************
;The UpdateWindow function updates the client area of the specified window by sending a WM_PAINT message to the window
;if the window's update region is not empty.
;The function sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue.
;If the update region is empty, no message is sent.
;BOOL UpdateWindow(
;
; HWND hWnd // handle of window
; );
;****************************
;****************************
;消息循环
;****************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0 ;如果消息队列中WM_QUIT则退出消息循环
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage, addr @stMsg
.endw
ret
_WinMain endp
;消息循环里面要用到MSG
;The MSG structure contains message information from a thread's message queue.
;
;typedef struct tagMSG { // msg
; HWND hwnd;
; UINT message; //Specifies the message number. 消息标识符,在头文件中以WM_开头的预定义值
; WPARAM wParam;
; LPARAM lParam;
; DWORD time; //Specifies the time at which the message was posted. 消息放入消息队列的时间
; POINT pt; //Specifies the cursor position, in screen coordinates, when the message was posted.
; //一个POINT数据结构,表示消息放入消息队列时的鼠标坐标
;} MSG;
;
;BOOL GetMessage(
;
; LPMSG lpMsg, // address of structure with message
; HWND hWnd, // handle of window
; UINT wMsgFilterMin, // first message
; UINT wMsgFilterMax // last message;
; );
; Return Values
;If the function retrieves a message other than WM_QUIT, the return value is nonzero.
;If the function retrieves the WM_QUIT message, the return value is zero.
;If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle.
;The TranslateMessage function translates virtual-key messages into character messages.
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start