Hello!.
Intro:
Im new to this forum, so,
this will be the first attempt to share code.
-------------------------------------------------------------------
NASM is the coolest thing i have ever found.
Everytime im opening, starting to code with NASM,
i feel like im in front of some sort of powerfull and dreadfull crafting table,
and only thing, that is needed, is a knowledge, to do some magic.
![Smiley :)](http://forum.nasm.us/Smileys/default/smiley.gif)
-------------------------------------------------------------------
This is Basic Win32 API Window, it covers,
the basic win32 api window,
and how to manage your code (Seperate larger parts into files and include them)..
For_me:
If i would have, the example like this, it would help a lot,
problems was with stdcall convetion, parameter locations (ebp+).
But now im done with this, so, you can have it.
If you have some small glitches, then this might help.
.
Im_using:
- Code editor: SciTE (higlights asm syntax).
- NASM to make OJB files.
- ALINK to make final EXE file, link Win32 api function calls.
.
Code_management:
- main.asm (main compile file)
- ___RegisterClassEx.asm (include file)
- ___CreateWindowEx.asm (include file)
- ___MessageLoop.asm (include file)
- ___windowProcedure.asm (include file)
.
LET_CODE_BEGIN:
main.asm (main compile file)[BITS 32]
; Define import macro, to import function from external DLL files
%macro macro_import_function 2
import %2 %1
extern %2
%endmacro
; Define import functions
macro_import_function user32.dll, LoadIconA
macro_import_function user32.dll, LoadCursorA
macro_import_function user32.dll, RegisterClassExA
macro_import_function user32.dll, MessageBoxA
macro_import_function user32.dll, CreateWindowExA
macro_import_function user32.dll, GetMessageA
macro_import_function user32.dll, TranslateMessage
macro_import_function user32.dll, DispatchMessageA
macro_import_function user32.dll, DefWindowProcA
macro_import_function user32.dll, ShowWindow
macro_import_function user32.dll, UpdateWindow
macro_import_function user32.dll, SendMessageA
macro_import_function user32.dll, PostQuitMessage
macro_import_function user32.dll, DestroyWindow
macro_import_function kernel32.dll, ExitProcess
macro_import_function kernel32.dll, GetModuleHandleA
macro_import_function kernel32.dll, GetCommandLineA
; Define come constants
CS_VREDRAW equ 0x0001
CS_HREDRAW equ 0x0002
IDI_APPLICATION equ 32512
COLOR_WINDOW equ 5
IDC_ARROW equ 32512
MB_OK equ 0x00000000
MB_ICONEXCLAMATION equ 0x00000030
WS_SYSMENU equ 0x00080000
SW_SHOW equ 5
WM_CREATE equ 0x1
WM_DESTROY equ 0x2
WM_CLOSE equ 0x0010
[SEGMENT .DATA USE32]
mainWindowClassName db "mainWindowClass",0
mainWindowName db "mainWindow",0
error_title db "~Error:",0
error_registerClassEx db "Register class error",0
error_createWindowEx db "Create window error",0
[SEGMENT .BSS USE32]
hInstance resb 4
commandLine resb 4
mainWindowClassEx resb 12*4
mainMessageStruct resb 7*4
windowHandle resb 4
[SEGMENT .TEXT USE32]
..start:
; Get instance, once and for all
push dword 0
call [GetModuleHandleA]
mov [hInstance],eax
; Get command line argument
call [GetCommandLineA]
mov [commandLine],eax
; Include external file
; Create window class and register
%include "___RegisterClassEx.asm"
; Include external file
; Create window
%include "___CreateWindowEx.asm"
; Include external file
; Do message loop
%include "___MessageLoop.asm"
jmp quitProgram
; Error handler for RegisterClassEx failure
registerClassError:
push dword MB_OK + MB_ICONEXCLAMATION
push dword error_title
push dword error_registerClassEx
push dword 0
call [MessageBoxA]
jmp quitProgram
; Error handler for CreateWindowEx failure
createWindowError:
push dword MB_OK + MB_ICONEXCLAMATION
push dword error_title
push dword error_createWindowEx
push dword 0
call [MessageBoxA]
; Quit program label
quitProgram:
push dword 0
call [ExitProcess]
ret
; Include external file
; Window procedure goes here
%include "___windowProcedure.asm"
___RegisterClassEx.asm (include file); Fill main WNDCLASSEX structure ----------------------------------------------------------------
; -----------------------------------------------------------------------------------------------
; 1. WNDCLASSEX.cbSize
mov [mainWindowClassEx + 0], dword 12*4
; 2. WNDCLASSEX.style
mov [mainWindowClassEx + 4], dword CS_VREDRAW + CS_HREDRAW
; 3. WNDCLASSEX.lpfnWndProc
mov [mainWindowClassEx + 8], dword windowProcedure
; 4. WNDCLASSEX.cbClsExtra
mov [mainWindowClassEx + 12], dword 0
; 5. WNDCLASSEX.cbWndExtra
mov [mainWindowClassEx + 16], dword 0
; 6. WNDCLASSEX.hInstance
mov eax,dword [hInstance]
mov [mainWindowClassEx + 20],eax
; 7. WNDCLASSEX.hIcon
push dword IDI_APPLICATION
push dword 0 ; This parameter must be NULL when a standard icon is being loaded.
call [LoadIconA]
mov [mainWindowClassEx + 24],eax
; 8. WNDCLASSEX.hIcon
push dword IDC_ARROW
push dword 0 ; This parameter must be NULL when a standard cursor is being loaded.
call [LoadCursorA]
mov [mainWindowClassEx + 28],eax
; 9. WNDCLASSEX.hbrBackground
mov [mainWindowClassEx + 32],dword COLOR_WINDOW
; 10. WNDCLASSEX.lpszMenuName
mov [mainWindowClassEx + 36],dword 0
; 11. WNDCLASSEX.lpszClassName
mov [mainWindowClassEx + 40],dword mainWindowClassName
; 12. WNDCLASSEX.hIcon
push dword IDC_ARROW
push dword [hInstance]
call [LoadCursorA]
mov [mainWindowClassEx + 44],eax
; Try Register
push dword mainWindowClassEx
call [RegisterClassExA]
cmp eax,0
je registerClassError
___CreateWindowEx.asm (include file)
push dword 0 ;LPVOID lpParam // pointer to window-creation data
push dword 0 ;HINSTANCE hInstance, // handle to application instance
push dword 0 ;HMENU hMenu, // handle to menu, or child-window identifier
push dword 0 ;HWND hWndParent, // handle to parent or owner window
push dword 480 ;int nHeight, // window height
push dword 640 ;int nWidth, // window width
push dword 128 ;int y, // vertical position of window
push dword 128 ;int x, // horizontal position of window
push dword WS_SYSMENU ;DWORD dwStyle, // window style
push dword mainWindowName ;LPCTSTR lpWindowName, // pointer to window name
push dword mainWindowClassName ;LPCTSTR lpClassName, // pointer to registered class name
push dword 0 ;DWORD dwExStyle, // extended window style
call [CreateWindowExA]
mov [windowHandle],eax
cmp eax,0
je createWindowError
___MessageLoop.asm (include file)
mainMessageLoop:
push dword 0
push dword 0
push dword 0
push dword mainMessageStruct
call [GetMessageA]
cmp eax,0
jle quitProgram
;push dword mainMessageStruct
;call [TranslateMessage]
push dword mainMessageStruct
call [DispatchMessageA]
jmp mainMessageLoop
___windowProcedure.asm (include file); Main window procedure
windowProcedure:
push ebp
mov ebp,esp
; Window procedure is stdcall convetion, so,
; the parameters are located at these kind of offsets.
; 4 Parameters
%define ebp_hwnd ebp+8
%define ebp_message ebp+12
%define ebp_wparam ebp+16
%define ebp_lparam ebp+20
; Switch\jump table
cmp [ebp_message],dword WM_CLOSE
je .onClose
cmp [ebp_message],dword WM_DESTROY
je .onDestroy
cmp [ebp_message],dword WM_CREATE
je .onCreate
.defaultProcedure:
push dword [ebp_lparam]
push dword [ebp_wparam]
push dword [ebp_message]
push dword [ebp_hwnd]
call [DefWindowProcA]
mov esp,ebp
pop ebp
ret 16 ; stdcall convetion requres pop all parameters from stack 4*4 = 16 bytes
.onCreate:
push dword SW_SHOW
push dword [ebp_hwnd]
call [ShowWindow]
push dword [ebp_hwnd]
call [UpdateWindow]
mov eax,0
mov esp,ebp
pop ebp
ret 16 ; stdcall convetion requres pop all parameters from stack 4*4 = 16 bytes
.onClose:
push dword [ebp_hwnd]
call [DestroyWindow]
mov eax,0
mov esp,ebp
pop ebp
ret 16 ; stdcall convetion requres pop all parameters from stack 4*4 = 16 bytes
.onDestroy:
push dword 0
call [PostQuitMessage]
mov eax,0
mov esp,ebp
pop ebp
ret 16 ; stdcall convetion requres pop all parameters from stack 4*4 = 16 bytes
.
LET_CODE_COMPILE:
Put all those files in same directory, copy nasm and alink exe files too, to this same directory.
NASM: Make OBJ file, cmd command: "nasm -fobj main.asm"
ALINK: Make Win32 Exe file, cmd command: "alink -c -oPE -subsys windows main.obj"
.
IF:
If you use code editor SciTE, you can set Menu->Language->Assembler.
Open Menu->Options->asm.properties, at the end of document you can find similarites,
and replace with something like this:
command.compile.$(file.patterns.asm)=nasm -fobj $(FileNameExt)
command.name.0.*.asm=Link
command.0.*.asm=alink -c -oPE -subsys windows $(FileName)
So, now open your main.asm file, then Tools->Compile, Link, and execute your program.
Here is some helpfull link, will help you to begin with win32 and nasm:
http://mathimaaran.angelfire.com/helloworld_tutorial.htmALINK you can get here:
http://alink.sourceforge.net/download.html.
CODE:
This code is NOT, ALL mine, i dont claim the rights to this,
the only thing what i did,
is to build, collect information of "my" own WORKING version of basic win32 application.
Use it at your own risk.
![Smiley :)](http://forum.nasm.us/Smileys/default/smiley.gif)
It is your responsibility to evaluate this information and dont blow up your monitor.
![Smiley :)](http://forum.nasm.us/Smileys/default/smiley.gif)
It seems here is no way to attach files, so, im skipping that part.