All pastes #745333 Raw Edit

Moddy

public text v1 · immutable
·published 2007-10-22 09:37 UTC
rendered paste body
;21st October 2007 - 23:55
;Moddy - Second ever MASM app. First with WinAPI.
.486 
.model flat, stdcall 
option casemap :none 

;standard includes
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 

includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 

;Function Prototypes
WinMain proto :DWORD, :DWORD, :DWORD, :DWORD  ;WinMain = Required Windows Main Function
ExitMsg proto :DWORD   ;My little "wannabe error-handling" function.

 .data 
 	;Windows requirements...
	ClassName   db "WinClass", 0 
	AppName   db "Sandbox Application", 0
	;Quit Messages... 
	QuitMsg   db "Successfully Quiting!", 0
	FailMsg db "Application Failed", 0

;Uninitialised data
.data?
	;hInstance stores the handle to the module to be associated with the applicated :/ 
	hInstance   HINSTANCE ? 
	stat UINT ?
	
.code 
start: 
	;Run GetModelHandle, Then move the return from it into hInstance. [The return of course, being in eax]
	invoke GetModuleHandle, NULL 
	mov hInstance, eax 
	;Run WinMain, The Main Windows Process,
	invoke WinMain, hInstance, NULL, NULL, 0 
	invoke ExitProcess, eax 

;Obligatory WinMain function 
  WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD 
	;3 Local Variables
	local wc:WNDCLASSEX 
	local msg:MSG 
	local hwnd:HWND 
	
	;Fill up the WNDCLASSEX class with the required information
	mov    wc.cbSize, SIZEOF WNDCLASSEX 
	mov    wc.style, CS_HREDRAW or CS_VREDRAW 
	mov    wc.lpfnWndProc, offset WndProc 
	mov    wc.cbClsExtra, NULL 
	mov    wc.cbWndExtra, NULL 
	;Use push and pop to move hInstance into wc.hInstance. REMEMBER: mov wont do memory to memory, just reg <-> mem, and reg <-> reg!
	push   hInstance 
	pop    wc.hInstance 
	mov    wc.hbrBackground, COLOR_WINDOW+1 
	mov    wc.lpszMenuName, NULL 
	mov    wc.lpszClassName, offset ClassName 
	;Invoke LoadIcon - Used to choose the icon for the application
	invoke LoadIcon, NULL, IDI_APPLICATION 
	
	mov    wc.hIcon, eax 
	mov    wc.hIconSm, eax 
	;LoadCursor - Used to choose the cursor for the application
	invoke LoadCursor, NULL, IDC_ARROW 
	
	mov    wc.hCursor, eax 
	;CreateWindowEx - Registers a windows class for use when we call CreateWindowEx
	invoke RegisterClassEx, addr wc 

	;Create our Window!
	invoke CreateWindowEx, 0, addr ClassName, addr AppName, WS_OVERLAPPEDWINDOW or WS_VISIBLE, CW_USEDEFAULT, 
	                                                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL 
  	;Move the return from CreateWindowEx [which is currently in eax] into hwnd 
	mov   hwnd, eax 
	
	;Create a loop which won't stop running unless someone clicks something...
	.while TRUE 
	;Which will send a message to the app, Which GetMessage will catch...
	invoke GetMessage, addr msg, NULL, 0, 0 
	.break .if (!eax) 
	;And TranslateMessage will convert into characters...
	invoke TranslateMessage, addr msg
	;For DispatchMessage to deal with. [i.e Send it to WndProc]
	invoke DispatchMessage, addr msg
	.endw 
	
	mov eax, msg.wParam 
	ret 
WinMain endp 

;This is where the messages are passed to be handed.
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
;If the message is WM_DESTROY then push 0, and call ExitMsg [Push 0 so ExitMsg can pop it off after its called]
	.if uMsg == WM_DESTROY 
	xor eax, eax 
	mov stat, eax 
	invoke ExitMsg, hWnd
;DefWindowProc = The defualt message handler. So should the message NOT be WM_DESTROY - Pass it on to DefWindowProc.
	.else 
	invoke DefWindowProc, hWnd, uMsg, wParam, lParam 
	ret 
;Make eax 0 [xor by itself] then return.
	.endif 
	xor eax, eax 
	ret 
WndProc endp 

;This is my *attempt* at an error handling function :P
ExitMsg proc hWnd:HWND
	;Check our stat variable...
	.if (stat == 0)
	;So we can output our messagebox with the good message, and then exit.
	invoke MessageBox, hWnd, addr QuitMsg, addr QuitMsg, MB_OK  
	invoke ExitProcess, 0
	ret
	.endif
	;But if we get here, then we can't have been supplied zero. So all is NOT good.. We call MessageBox with the bad message then exit with the value that was supplied to us
	invoke MessageBox, hWnd, addr FailMsg, NULL, MB_OK ;By setting the 3rd arg as NULL, It will display the default. [Default = "Error"]
	invoke ExitProcess, stat
	ret
ExitMsg endp

end start