Let’s Learn: Assembly –> Simple Window



Windows programs rely heavily on API functions for their GUI. This approach benefits both users and programmers. For users, they don’t have to learn how to navigate the GUI of each new programs, the GUI of Windows programs are alike. For programmers, the GUI codes are already there, tested, and ready for use. The downside for programmers is the increased complexity involved. In order to create or manipulate any GUI objects such as windows, menu or icons, programmers must follow a strict recipe. But that can be overcome by modular programming or OOP paradigm.

I’ll outline the steps required to create a window on the desktop below:

  1. Get the instance handle of your program (required)
  2. Get the command line (not required unless your program wants to process a command line)
  3. Register window class (required ,unless you use predefined window types, eg. MessageBox or a dialog box)
  4. Create the window (required)
  5. Show the window on the desktop (required unless you don’t want to show the window immediately)
  6. Refresh the client area of the window
  7. Enter an infinite loop, checking for messages from Windows
  8. If messages arrive, they are processed by a specialized function that is responsible for the window
  9. Quit program if the user closes the window
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib            ; calls to functions in user32.lib and kernel32.lib 
include \masm32\include\kernel32.inc 
includelib \masm32\lib\kernel32.lib

.DATA                     ; initialized data 
ClassName   db “SimpleWinClass”,0        ; the name of our window class 
AppName     db “Our First Window”,0        ; the name of our window

.DATA?                    ; Uninitialized data 
hInstance HINSTANCE ?     ; Instance handle of our program 
CommandLine LPSTR   ? 

.CODE                                   ; Here begins our code 
invoke GetModuleHandle, NULL            ; get the instance handle of our program. 
                                        ; Under Win32, hmodule==hinstance mov hInstance,eax 
mov hInstance,eax 
invoke GetCommandLine                   ; get the command line. You don’t have to call this function IF 
                                        ; your program doesn’t process the command line. 
mov CommandLine,eax 
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        ; call the main function 
invoke ExitProcess, eax                                           ; quit our program. The exit code is returned in eax from WinMain.

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
    LOCAL wc:WNDCLASSEX                                            ; create local variables on stack 
    LOCAL msg:MSG 
    LOCAL hwnd:HWND

    mov   wc.cbSize,SIZEOF WNDCLASSEX                   ; fill values in members of wc 
    mov   wc.style, CS_HREDRAW or CS_VREDRAW 
    mov   wc.lpfnWndProc, OFFSET WndProc 
    mov   wc.cbClsExtra,NULL 
    mov   wc.cbWndExtra,NULL 
    push  hInstance 
    pop   wc.hInstance 
    mov   wc.hbrBackground,COLOR_WINDOW+1 
    mov   wc.lpszMenuName,NULL 
    mov   wc.lpszClassName,OFFSET ClassName 
    invoke LoadIcon,NULL,IDI_APPLICATION 
    mov   wc.hIcon,eax 
    mov   wc.hIconSm,eax 
    invoke LoadCursor,NULL,IDC_ARROW 
    mov   wc.hCursor,eax 
    invoke RegisterClassEx, addr wc                       ; register our window class 
    invoke CreateWindowEx,NULL,\ 
                ADDR ClassName,\ 
                ADDR AppName,\ 
    mov   hwnd,eax 
    invoke ShowWindow, hwnd,CmdShow                         ; display our window on desktop 
    invoke UpdateWindow, hwnd                               ; refresh the client area

    .WHILE TRUE                                             ; Enter message loop 
                invoke GetMessage, ADDR msg,NULL,0,0 
                .BREAK .IF (!eax) 
                invoke TranslateMessage, ADDR msg 
                invoke DispatchMessage, ADDR msg 
    mov     eax,msg.wParam                                   ; return exit code in eax 
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
    .IF uMsg==WM_DESTROY                                    ; if the user closes our window 
        invoke PostQuitMessage,NULL             ; quit our application 
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam     ; Default message processing 
    xor eax,eax 
WndProc endp

end start

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s