To create a window you need to use the RegisterClassEx function which accepts one parameter, a pointer to the WNDCLASSEX struct, which you can find more info here
.386p ; 80386 instruction set.
.model flat, stdcall ; Memory model.
; API functions we’ll be using
extrn GetModuleHandle : PROC
extrn RegisterClassExA : PROC
.DATA
msg MSG
wc WNDCLASSEX
; handles
hMain dd 0 ; handle for the window
hInst dd 0 ; handle to the instance
; strings
szProgName db ''An OSI production'',0
szMainClass db ''ASMWINDOW'',0
All pretty self explanatory so far
.CODE
start:
call GetModuleHandleA, 0 ; retrieve the Instance handle
mov hInst, eax ; save ot
mov [wc.style], CS_HREDRAW + CS_VREDRAW
mov [wc.lpfnWndProc], offset WndProc
mov [wc.cbClsExtra], 0
mov [wc.cbWndExtra], 0
mov eax, [hInst]
mov [wc.hInstance], eax
; Load the icon for my application
call LoadIconA, 0, IDI_APPLICATION
mov [wc.hIcon], eax ; save here
; Load the cursor for my application
call LoadCursorA, 0, IDC_ARROW
mov [wc.hCursor], eax ;save here
mov [wc.hbrBackground], COLOR_WINDOW + 1
mov dword ptr [wc.lpszMenuName], 0
mov dword ptr [wc.lpszClassName], offset szMainClass
push offset wc
call RegisterClassExA
GetModuleHandle() as the comment says, retrieves the handle of our window, this is pretty important, a lot of win32 functions need the handle as a parameter to perform their task, RegisterClassExA() as previously mentioned, is needed to register a window class, once we’ve done this we can use the CreateWindowExA() function to actually create the window, it takes 12 params, MSDN defines it as;
HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
In ASM this looks like;
call CreateWindowExA, 0,
offset szMainClass,
offset szProgName,
WS_VISIBLE OR WS_CAPTION OR WS_SYSMENU,
100, ;X position
50, ;Y position
300, ;width of the window
100, ;height of the window
0, ;handle to parent''s window if there is one
0, ;handle to the window''s menu
hInst, ;the instance handle
0 ;lparam
mov hMain, eax ; store the handle
So now we have a window handle (stored in hMain), the window, by default, is hidden, we need to use the ShowWindow() function to make it visible, then the UpdateWindow() function whenever it needs redrawing
call ShowWindow, hMain, SW_SHOWNORMAL
call UpdateWindow, hMain
Now we have a visible, working window, we now need to implement a skeleton message handler for it.
msg_loop:
call GetMessageA, offset msg, 0, 0, 0
cmp ax, 0
je end_loop
call TranslateMessage, offset msg
call DispatchMessageA, offset msg
jmp msg_loop
end_loop:
call ExitProcess, 0
WndProc proc Hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD
movzx eax, WORD PTR wmsg
.if eax == WM_DESTROY
jmp wmdestroy
.else
call DefWindowProcA, Hwnd, wmsg, wparam, lparam
jmp @@End
.endif
xor eax, eax
@@End:
ret
wmdestroy:
call PostQuitMessage, 0
xor eax, eax
ret
WndProc endp
public WndProc
This responds to each message the program gets sent, the DefWindowProcA() function discards anything irrelevant to the program, seeing as this is a skeleton app we only need to deal with the WM_DESTROY message, which is sent when an app is quitting.
This article was originally written by pigsbig78 |