;--- a simple 16-bit Windows "hello world".
;--- assemble: JWasm Win16.asm
;--- link: wlink format windows file Win16.obj library libw.lib
;---
;--- alternatively the MS OMF linker can be used as well:
;--- link16 /A:16 Win16.obj,,,libw.lib,Win16.def;
;---
;--- libw.lib is the name of the import library for Win16 API calls.
;--- if libw.lib isn't available, create one with Open Watcom WLIB:
;--- wlib -ino -p=16 libw.lib + krnl386.exe + user.exe + gdi.exe
;--- (files krnl386.exe, user.exe and gdi.exe can be found in the Windows
;--- system directory).
.286
.model small
.386
option casemap:none
WINAPI equ <FAR PASCAL>
UINT typedef WORD
HINSTANCE typedef WORD
HWND typedef WORD
HMENU typedef WORD
HDC typedef WORD
WPARAM typedef WORD
LPARAM typedef DWORD
LPSTR typedef FAR PTR BYTE
NULL equ 0
WS_OVERLAPPED equ 000000000h
WS_MAXIMIZEBOX equ 000010000h
WS_MINIMIZEBOX equ 000020000h
WS_THICKFRAME equ 000040000h
WS_SYSMENU equ 000080000h
WS_CAPTION equ 000C00000h
WS_OVERLAPPEDWINDOW equ WS_OVERLAPPED + WS_CAPTION + WS_SYSMENU + WS_THICKFRAME + WS_MINIMIZEBOX + WS_MAXIMIZEBOX
CS_VREDRAW equ 0001h
CS_HREDRAW equ 0002h
WM_DESTROY equ 0002h
WM_PAINT equ 000Fh
WM_COMMAND equ 0111h
CW_USEDEFAULT equ 8000h
SW_SHOWNORMAL equ 1
COLOR_WINDOW equ 5
IDC_ARROW equ 32512
dt_CENTER EQU 01h
dt_VCENTER EQU 04h
dt_SINGLELINE EQU 20h
MSG struct
hwnd HWND ?
message UINT ?
wParam WPARAM ?
lParam LPARAM ?
time dd ?
pt dd ?
MSG ends
WNDCLASS struct
style dw ?
lpfnWndProc dd ?
cbClsExtra dw ?
cbWndExtra dw ?
hInstance HINSTANCE ?
hIcon dw ?
hCursor dw ?
hbrBackground dw ?
lpszMenuName LPSTR ?
lpszClassName LPSTR ?
WNDCLASS ends
RECT struct
left dw ?
top dw ?
right dw ?
bottom dw ?
RECT ends
PAINTSTRUCT struct
hdc HDC ?
fErase dw ?
rcPaint RECT <>
fRestore dw ?
fIncUpdate dw ?
rgbReserved db 16 dup(?)
PAINTSTRUCT ends
BeginPaint proto WINAPI :HWND, :far ptr PAINTSTRUCT
CreateWindow proto WINAPI lpszClass:LPSTR, lpszName:LPSTR, style:DWORD,
x:WORD, y:WORD, cx_:WORD, cy:WORD,
parent:HWND, menu:HMENU, hInst:HINSTANCE, lParam:LPARAM
DefWindowProc proto WINAPI :HWND, msg:UINT, wParam:WPARAM, lParam:LPARAM
DispatchMessage proto WINAPI :far ptr MSG
DrawText proto WINAPI :HDC, :LPSTR, :WORD, :far ptr RECT, :WORD
EndPaint proto WINAPI :HWND, :far ptr PAINTSTRUCT
GetClientRect proto WINAPI :HWND, :far ptr RECT
GetMessage proto WINAPI :far ptr MSG, hWnd:HWND, msgfrom:WORD, msgto:WORD
InitApp proto WINAPI :HINSTANCE
InitTask proto WINAPI
LoadCursor proto WINAPI :HINSTANCE, :LPSTR
PostQuitMessage proto WINAPI :WORD
RegisterClass proto WINAPI :far ptr WNDCLASS
ShowWindow proto WINAPI :HWND, :WORD
TranslateMessage proto WINAPI :far ptr MSG
WaitEvent proto WINAPI :WORD
.data
dw 0,0,5,0,0,0,0,0 ;DGROUP first 16 bytes used by Windows
.const
szClass db "WndClassName",0
szWnd db "Windows 16-bit sample in ASM",0
szHello db "Hello, world",0
.code
;*** WM_COMMAND handler
OnCommand proc stdcall hWnd:HWND,wParam:WPARAM,lParam:LPARAM
xor ax, ax
cwd
ret
OnCommand endp
;*** window procedure - must be FAR PASCAL
WndProc proc WINAPI <LOADDS> hWnd:HWND,message:UINT,wParam:WPARAM,lParam:LPARAM
local ps:PAINTSTRUCT
mov ax,message
.if (ax == WM_COMMAND)
invoke OnCommand,hWnd,wParam,lParam
.elseif (ax == WM_PAINT)
invoke BeginPaint, hWnd, addr ps
invoke GetClientRect, hWnd, addr ps.rcPaint
invoke DrawText, ps.hdc, addr szHello, -1, addr ps.rcPaint, DT_CENTER or DT_VCENTER or DT_SINGLELINE
invoke EndPaint, hWnd, addr ps
xor ax, ax
cwd
.elseif (ax == WM_DESTROY)
invoke PostQuitMessage, 0
xor ax,ax
cwd
.else
invoke DefWindowProc, hWnd,message,wParam,lParam
.endif
ret
WndProc endp
;*** InitApplication: register window class
InitApplication proc stdcall hInstance:HINSTANCE
local wc:WNDCLASS
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov word ptr wc.lpfnWndProc+0, offset WndProc
mov word ptr wc.lpfnWndProc+2, cs
xor ax,ax
mov wc.cbClsExtra,ax
mov wc.cbWndExtra,ax
mov ax,hInstance
mov wc.hInstance,ax
mov wc.hIcon, NULL
invoke LoadCursor, 0, IDC_ARROW
mov wc.hCursor,ax
mov ax,COLOR_WINDOW + 1
mov wc.hbrBackground,ax
xor eax,eax
mov wc.lpszMenuName,eax
mov word ptr wc.lpszClassName+0, offset szClass
mov word ptr wc.lpszClassName+2, ds
invoke RegisterClass, addr wc
exit:
ret
InitApplication endp
;*** InitInstance: create application window and show it
InitInstance proc stdcall hInstance:HINSTANCE
invoke CreateWindow, addr szClass, addr szWnd,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, 0
.if (ax)
push ax
invoke ShowWindow, ax, SW_SHOWNORMAL
pop ax
.endif
ret
InitInstance endp
;--- WinMain: create application window, enter message loop
WinMain proc pascal hInstance:HINSTANCE,hPrevInstance:HINSTANCE,lpszCmdline:LPSTR,cmdshow:UINT
local msg:MSG
.if hPrevInstance == 0 ;1. Instance?
invoke InitApplication, hInstance
and ax,ax
jz exit
.endif
invoke InitInstance, hInstance
and ax,ax
jz exit
.while 1
invoke GetMessage, addr msg, 0, 0, 0
.break .if (ax == 0)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
exit:
ret
WinMain endp
;--- program entry: SS=DS=DGROUP
start:
invoke InitTask
and ax,ax
jz error
push es ;es:bx -> cmdline
pusha
invoke WaitEvent, 0
invoke InitApp, di
popa
pop es
invoke WinMain, di, si, es::bx, dx
mov ah,4ch
int 21h
error:
mov ax,4c01h
int 21h
end start
|