This is just a Win32 application skeleton with a small procedure that manages fatal errors, by displaying an information message box and terminating the process.
I think the code is pretty much self explanatory and I commented it to some
degree, so there's not much to say. To close the black window just hit ESCAPE.
The only one thing that isn't that quite right is the fact that you have to
code the line numbers by hand and so if you change anything above previously
coded numbers, you'll have to do them again... oh well!
To assemble get the MASM32 package from: {http://www.pbq.com.au/home/hutch/}
--8<---------------------------------------------------------------------------
; SKELETON.ASM
; Win32 AppFatalExit Skeleton
; by Chili for APJ #8
; August 11, 2000
;#############################################################################
; Compiler Options
;#############################################################################
title Win32 AppFatalExit Skeleton
.386
.model flat, stdcall ; 32-bit memory model
option casemap :none ; case sensitive
;#############################################################################
; Includes
;#############################################################################
;// Include Files
include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
;// Libraries
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
;#############################################################################
; Equates
;#############################################################################
;// Basic
NULL equ 0
FALSE equ 0
TRUE equ 1
;#############################################################################
; Local Prototypes
;#############################################################################
;// Main Program Procedures.
WinMain PROTO :DWORD, :DWORD, :DWORD, :DWORD
WndProc PROTO :DWORD, :DWORD, :DWORD, :DWORD
AppFatalExit PROTO :DWORD, :DWORD
;#############################################################################
; Local Macros
;#############################################################################
;// Return a value in EAX.
return MACRO arg
IFNB <arg>
mov eax, arg
ENDIF
ret
ENDM
;// Memory-to-memory MOV.
m2m MACRO m1:REQ, m2:REQ
push m2
pop m1
ENDM
;// Memory copy.
mcopy MACRO destination:REQ, source:REQ
cld
lea esi, source
lea edi, destination
mov ecx, sizeof source
rep movsb
ENDM
;// Insert zero terminated string into code section.
szText MACRO name:REQ, text:VARARG
LOCAL lbl
jmp lbl
name db text, 0
lbl:
ENDM
;// Insert zero terminated string into .data section.
dszText MACRO name:REQ, text:VARARG
.data
name db text, 0
.code
ENDM
;// Return in EBX the ASCII size of a DWORD value
dwsize MACRO value:REQ
xor ebx, ebx
mov eax, value
.if eax == 0
inc ebx
.else
mov ecx, 10
.while eax > 0
xor edx, edx
div ecx
inc ebx
.endw
.endif
ENDM
;#############################################################################
; Initialized Data Section
;#############################################################################
.data
;#############################################################################
; Uninitialized Data Section
;#############################################################################
.data?
;#############################################################################
; Constants Section
;#############################################################################
.const
;#############################################################################
; Code Section
;#############################################################################
.code
;==============================================================================
; Beginning of executable code
;==============================================================================
start proc
;// Do some base initialization for the WinMain function and upon its
;// ending, terminate process.
LOCAL hModule :DWORD
;// Get handle to current instance.
invoke GetModuleHandle, NULL
.IF eax == NULL
dszText szGetModuleHandle_157, "GetModuleHandle, ln #157"
invoke AppFatalExit, addr szGetModuleHandle_157,
sizeof szGetModuleHandle_157
.ENDIF
mov hModule, eax
;// Get pointer to the command-line string for the current process.
invoke GetCommandLine
;// Call initial entry point for a Win32-based application.
invoke WinMain, hModule, NULL, eax, SW_SHOWMAXIMIZED
;// End process and all its threads.
invoke ExitProcess, eax
start endp
;==============================================================================
; WinMain Function (Called by the system as the initial entry point for a
; Win32-based application)
;==============================================================================
WinMain proc hInstance :DWORD, ;// handle to current instance
hPrevInstance :DWORD, ;// handle to previous instance
lpCmdLine :DWORD, ;// pointer to command line
nCmdShow :DWORD ;// show state of window
;// Perform initialization, create and display a main window and enter a
;// message retrieval-and-dispatch loop.
LOCAL wc :WNDCLASSEX
LOCAL hwndMain :DWORD
LOCAL msg :MSG
;// Register the window class for the main window.
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_OWNDC
mov wc.lpfnWndProc, offset MainWndProc
mov wc.cbClsExtra, 0
mov wc.cbWndExtra, 0
m2m wc.hInstance, hInstance
invoke LoadIcon, NULL, IDI_APPLICATION
.if eax == NULL
dszText szLoadIcon_203, "LoadIcon, ln #203"
invoke AppFatalExit, addr szLoadIcon_203, sizeof szLoadIcon_203
.endif
mov wc.hIcon, eax
invoke LoadCursor, NULL, IDC_ARROW
.if eax == NULL
dszText szLoadCursor_209, "LoadCursor, ln #209"
invoke AppFatalExit, addr szLoadCursor_209, sizeof szLoadCursor_209
.endif
mov wc.hCursor, eax
invoke GetStockObject, BLACK_BRUSH
.if eax == NULL
dszText szGetStockObject_215, "GetStockObject, ln #215"
invoke AppFatalExit, addr szGetStockObject_215,
sizeof szGetStockObject_215
.endif
mov wc.hbrBackground, eax
mov wc.lpszMenuName, NULL
dszText szClassName, "MainWndClass"
mov wc.lpszClassName, offset szClassName
mov wc.hIconSm, NULL
invoke RegisterClassEx, addr wc
.if eax == 0
dszText szRegisterClassEx_227, "RegisterClassEx, ln #227"
invoke AppFatalExit, addr szRegisterClassEx_227,
sizeof szRegisterClassEx_227
.endif
;// Create the main window.
dszText szDisplayName, "Win32 AppFatalExit Skeleton"
invoke CreateWindowEx, NULL, addr szClassName, addr szDisplayName,
WS_POPUP or WS_CLIPSIBLINGS or WS_MAXIMIZE or \
WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
hInstance, NULL
;// If the main window cannot be created, terminate the application.
.if eax == NULL
dszText szCreateWindowEx_237, "CreateWindowEx, ln #237"
invoke AppFatalExit, addr szCreateWindowEx_237,
sizeof szCreateWindowEx_237
.endif
mov hwndMain, eax
;// Show the window and paint its contents.
invoke ShowWindow, hwndMain, nCmdShow
invoke UpdateWindow, hwndMain
.if eax == NULL
dszText szUpdateWindow_255, "UpdateWindow, ln #255"
invoke AppFatalExit, addr szUpdateWindow_255,
sizeof szUpdateWindow_255
.endif
;// Start the message loop.
.while TRUE
invoke PeekMessage, addr msg, NULL, 0, 0, PM_REMOVE
.if (eax != 0)
.break .if msg.message == WM_QUIT
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endif
.endw
;// Return the exit code to Windows.
return msg.wParam
WinMain endp
;==============================================================================
; WindowProc Function (Application-defined callback function that processes
; messages sent to a window)
;==============================================================================
MainWndProc proc hwnd :DWORD, ;// handle of window
uMsg :DWORD, ;// message identifier
wParam :DWORD, ;// first message parameter
lParam :DWORD ;// second message paramater
;// Dispatch the messages that can be received.
.if uMsg == WM_KEYDOWN
;// Process keyboard input by means of a key press.
.if wParam == VK_ESCAPE
;// Clean up window-specific data objects.
invoke PostQuitMessage, NULL
return 0
.endif
.elseif uMsg == WM_DESTROY
;// Clean up window-specific data objects.
invoke PostQuitMessage, NULL
return 0
.endif
;// Process other messages.
invoke DefWindowProc, hwnd, uMsg, wParam, lParam
ret
MainWndProc endp
;==============================================================================
; Application Fatal Exit Procedure
;==============================================================================
AppFatalExit proc lpszCaption :DWORD, ;// pointer to string to display in
\ ;// caption of the message box
nSize :DWORD ;// size of caption
;// Display a message box and terminate.
LOCAL uExitCode :DWORD
LOCAL lpBuffer :DWORD
LOCAL szFatalMessage [256]:BYTE
LOCAL nSizeMsg :DWORD
LOCAL szFatalCaption [64]:BYTE
;// Get the calling thread's last-error code value.
invoke GetLastError
mov uExitCode, eax
;// Obtain error message string.
invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or \
FORMAT_MESSAGE_FROM_SYSTEM, NULL, uExitCode, 0,
addr lpBuffer, 0, NULL
.if eax == NULL
dwsize uExitCode
mov nSizeMsg, ebx
invoke GetLastError
push eax
dwsize eax
add nSizeMsg, ebx
pop eax
dszText szDoubleFmt, "#%lu [& %lu]"
invoke wsprintf, addr szFatalMessage, addr szDoubleFmt, uExitCode, eax
add nSizeMsg, 7
.if eax != nSizeMsg
dszText szDoubleMessage, "??? [& ???]"
mcopy szFatalMessage, szDoubleMessage
.endif
.else
mov nSizeMsg, eax
dwsize uExitCode
add nSizeMsg, ebx
dszText szFmt, "%lu - %s"
invoke wsprintf, addr szFatalMessage, addr szFmt, uExitCode, lpBuffer
add nSizeMsg, 4
.if eax != nSizeMsg
dszText szMessage, "#??? - ?????"
mcopy szFatalMessage, szMessage
.endif
invoke LocalFree, lpBuffer ;// Possible errors in LocalFree ignored
.endif
;// Display the application fatal exit message box.
dszText szCaptionFmt, "Fatal: %s"
invoke wsprintf, addr szFatalCaption, addr szCaptionFmt, lpszCaption
add nSize, 6
.if eax != nSize
dszText szCaption, "Fatal: ?????, ln #???"
mcopy szFatalCaption, szCaption
.endif
invoke MessageBox, NULL, addr szFatalMessage, addr szFatalCaption,
MB_ICONHAND or MB_SYSTEMMODAL
;// End process and all its threads.
invoke ExitProcess, eax
AppFatalExit endp
end start
---------------------------------------------------------------------------8<--
|