Skeleton is a sample program for MS Windows which uses Graphic User Interface (GUI) and Windows resources (menu and icon).
It displays a white window with standard menu on the top and simple status bar on the bottom.
Program can be assembled in ANSI or WIDE (UNICODE) version, which is selected by
EUROASM UNICODE=
option in the Header
. No other intervention in source text is required,
because all strings are defined with unspecified character width, and all system calls
are managed by macro WinABI, which automatically selects ANSI or WIDE version.
..\objlib\winapi.libyet,
prowin32subdirectory with command
euroasm dll2lib.htm
...\objlib\skelet.rcwith command
euroasm skelet64.htm
in directory ..\prowin64\,
..\objlib\skelet.rc
..\objlib\skelet.reswith command
rc.exe skelet.rc
in directory ..\objlib\.
..\prowin64\directory with command
euroasm skelet64.htm
.skelet64.exe
The header specifies program format, included macrolibraries, linked import library and other modules.
Included macrolibraries are available in subdirectory
..\maclib\.If you don't have the linked import library
..\objlib\winapi.lib, you can create it with sample project DLL2LIB.If you don't have the linked resource module
..\objlib\skelet.res, you can create it withrc.exe ..\objlib\skelet.rc
.
The header defines numeric menu identificators %MenuId*
which will be used both in resource script (skelet PROGRAM
) and in the window procedure of the main skelet64 PROGRAM
. That is why they have the form of preprocessing %variables rather than EQU symbols.
Menu identificator values are chosen arbitrary,
they are biased by the constant WM_APP to avoid collision
with other internal MS Windows message identifiers.
EUROASM UNICODE=Enabled ; This option selects ANSI or WIDE version. EUROASM CPU=X64,SIMD=Yes,DumpWidth=32 INCLUDE "winsgui.htm" ; This file defines the constant WM_APP. %IconResName %SET SkeletIcon %MenuResName %SET SkeletMenu %MenuIdExit %SETA WM_APP + 1 %MenuIdHelp %SETA WM_APP + 2 %MenuIdAbout %SETA WM_APP + 3 %StatusBarId %SETA WM_APP + 9 ;; skelet64 PROGRAM Format=PE, Subsystem=GUI, Width=64, Entry=WinMain INCLUDE winabi.htm, wins.htm, winsgui.htm, fastcall.htm, \ cpuext.htm, cpuext64.htm LINK winapi.lib, skelet.res
Resources of this project are defined here in the form of text file
skelet.rc
created by an embedded program block named skelet.
The resource script skelet.rc
will be created in subdirectory ..\objlib\
and it has to be compiled to ..\objlib\skelet.res
by an external
resource compiler (EuroAssembler cannot compile resources).
Resource script may be written in ANSI or UNICODE encoding (OEM or WIDE),
because Microsoft Resource Compiler rc.exe
available in
[WindowsSDK]
treats both variants equally.
skelet PROGRAM Format=BIN, OutFile="..\objlib\skelet.rc" D ' /* Resource definition for skeleton programs ',13,10 D ' which are shipped with EuroAssembler. */ ',13,10 D '%IconResName ICON "..\objlib\skelet.ico" ',13,10 D '%MenuResName MENU ',13,10 D ' BEGIN ',13,10 D ' POPUP "&File" ',13,10 D ' BEGIN ',13,10 D ' MENUITEM "E&xit [Esc]",%MenuIdExit',13,10 D ' END ',13,10 D ' POPUP "&Help" ',13,10 D ' BEGIN ',13,10 D ' MENUITEM "&Help [F1]",%MenuIdHelp ',13,10 D ' MENUITEM "&About [F2]",%MenuIdAbout',13,10 D ' END ',13,10 D ' END ',13,10 ENDPROGRAM skelet
This is the main program entry procedure which represents the target executable
skelet64.exe
.
[.data] InfoText D "Skeleton of Windows program written in EuroAssembler." DU 0 ; This NUL character works both for ANSI and WIDE variants. HelpText D "Press [F1] to show this help.",13,10, \ "Press [F2] to show information about this program.",13,10, \ "Press [Esc] to quit the program.",0 %IF %^UNICODE %Char %SET UNICODE %ELSE %Char %SET ANSI %ENDIF AboutText D "This %Char %^WIDTH[]bit program %^PROGRAM.exe was created",13,10, \ "by EuroAssembler ver.%^VERSION %^EUROASMOS",13,10, \ "on %^DATE[7..8].%^DATE[5..6].%^DATE[1..4] %^TIME[1..2]:%^TIME[3..4] UTC.",0 StatusInfo D "Status bar displays information about menu items.",0 [.bss] Msg D MSG ; Window message. [.text] WinMain PROC ; Program entry point. Clear SEGMENT#[.bss],Size=SIZE#[.bss] ; Make sure to start with zeroed memory of uninitialized reserved data. CALL WndCreate ; Initialize the program window. .MsgLoop: WinABI GetMessage, Msg,0,0,0 TEST RAX JZ .MsgQuit: ; ZF signalizes message WM_QUIT - request for program termination. WinABI TranslateMessage, Msg ; Remap character keys from national keyboards. WinABI DispatchMessage, Msg ; Let Windows call our WndProc. JMP .MsgLoop: ; Wait for another message. .MsgQuit: TerminateProgram Errorlevel=[Msg.wParam] ENDPROC WinMain
[%hWnd], [%uMsg], [%wParam], [%lParam]
), too, in the entire WndProc body.
Messages obtained from Windows are dispatched by WndProc to their handlers.
Unhandled messages are passed to DefWindowProc.
[.bss] PaintStruct DS PAINTSTRUCT ; Structured variable used in painting. hDC D QWORD ; Handle of device context used in painting. [.text] WndProc Procedure hWnd, uMsg, wParam, lParam ; These parameters are provided in RCX,RDX,R8,R9. SaveToShadow Uses RBX,RSI,RDI ; It's only necessary if some of callee-save registers was used in this fastcalled procedure. ; Fork message uMsg=RDX to its handler using macro Dispatch: Dispatch EDX, WM_CREATE, WM_DESTROY, WM_PAINT, WM_KEYDOWN, WM_COMMAND, WM_MENUSELECT .Def:WinABI DefWindowProc,[%hWnd],[%uMsg],[%wParam],[%lParam] ; Pass ignored event to DefWindowProc with unchanged arguments. JMP .Ret: ; Go to EndProcedure with result value RAX as returned from DefWindowProc. ; All message handlers terminate with a jump to label .Def: or .Ret0:. .WM_CREATE: ; The main window is being created. WinABI SendMessage,[hStatusBar],SB_SIMPLE,1,0 ; Tell the status bar to be simple. WinABI SendMessage,[hWindow],WM_MENUSELECT,0,0 ; Initialize status bar with StatusInfo. JMP .Ret0: .WM_PAINT: ; Window needs to repaint its contents. WinABI BeginPaint,[hWindow],PaintStruct MOV [hDC],RAX WinABI TextOut,RAX,30,30,InfoText,SIZE# (InfoText) << %^UNICODE ; TextOutW expects text size in characters.>> ; That's why the size in bytes is right-shifted by 1 when %^UNICODE is -1. WinABI EndPaint,[hWindow],PaintStruct JMP .Ret0: .WM_COMMAND: ; User selected menu item identified by R8=wParam. Dispatch R8, %MenuIdExit, %MenuIdHelp, %MenuIdAbout JMP .Def: ; Pass unhandled items to WinAPI DefWindowProc. .WM_KEYDOWN: ; Non-character hot key R8=wParam was pressed. Dispatch R8, VK_ESCAPE, VK_F1, VK_F2 JMP .Def: ; Pass ignored keys to WinAPI DefWindowProc. .%MenuIdExit: ; Menu Exit selected. .VK_ESCAPE: ; Esc pressed. WinABI SendMessage,RCX,WM_DESTROY,0,0 JMP .Ret0: .%MenuIdHelp: ; Menu Help selected. .VK_F1: ; F1 pressed. WinABI MessageBox,RCX,HelpText,WndClassName,MB_ICONINFORMATION JMP .Ret0: .%MenuIdAbout: ; Menu About selected. .VK_F2: ; F2 pressed. WinABI MessageBox,RCX,AboutText,WndClassName,MB_ICONINFORMATION JMP .Ret0: .WM_MENUSELECT: ; User unrolled a menu item. Show online help in status bar. MenuStatus PROC ; Namespace MenuStatus is used to avoid collision in %MenuId* labels. AND R8,0x0000_FFFF ; Menu identifier is in the low word of wParam. Dispatch R8,%MenuIdExit,%MenuIdHelp,%MenuIdAbout MOV R10,StatusInfo ; Use neutral StatusInfo help text for undispatched menu items. .ShowStatus:WinABI SendMessage,[hStatusBar],SB_SETTEXT,SB_SIMPLEID,R10 JMP WndProc.Ret0: .%MenuIdExit: MOV R10,="Terminate program." JMP .ShowStatus: .%MenuIdHelp: MOV R10,="Show help information." JMP .ShowStatus: .%MenuIdAbout:MOV R10,="Show information about this program." JMP .ShowStatus: ENDP MenuStatus .WM_DESTROY: ; Program terminates. WinABI PostQuitMessage,0 ; Tell Windows to quit this program with errorlevel 0. ; JMP .Ret0: .Ret0:XOR EAX,EAX .Ret:EndProcedure WndProc
skelet64.exeuses one graphical window. Procedure WndCreate constructs the window class and window object.
[.data] WndClassName D "SKELET",0 [.bss] WndClassEx DS WNDCLASSEX ; Definition of the window class structure. hWindow D QWORD ; Handle of the window object. hStatusBar D QWORD ; Handle of the status bar. [.text] WndCreate PROC ; Register class SKELET for the main window. MOV [WndClassEx.cbSize],SIZE# WNDCLASSEX MOV [WndClassEx.lpszClassName],WndClassName MOV [WndClassEx.style],CS_HREDRAW|CS_VREDRAW MOV [WndClassEx.lpfnWndProc],WndProc WinABI GetModuleHandle,0 MOV [WndClassEx.hInstance],RAX MOV RDX,="%IconResName" ; Icon name used in resources. WinABI LoadIcon,RAX,RDX ; Load icon handle from resources. MOV [WndClassEx.hIcon],RAX WinABI LoadCursor,0,IDC_HAND ; Load cursor handle from stock. MOV [WndClassEx.hCursor],RAX WinABI GetStockObject,WHITE_BRUSH ; Default window background colour. MOV [WndClassEx.hbrBackground],RAX MOV [WndClassEx.lpszMenuName], ="%MenuResName" ; Menu name used in resources. WinABI RegisterClassEx, WndClassEx ; Define the main window. WinABI CreateWindowEx, WS_EX_CLIENTEDGE, \ WndClassName, WndClassName, WS_OVERLAPPEDWINDOW, \ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, \ 0, 0, [WndClassEx.hInstance], 0 MOV [hWindow],RAX ; Define status bar as the child of the main window. WinABI CreateStatusWindow,WS_CHILD+WS_BORDER+WS_VISIBLE, \ StatusInfo, [hWindow], %StatusBarId MOV [hStatusBar],RAX WinABI ShowWindow, [hWindow], SW_SHOWNORMAL WinABI UpdateWindow, [hWindow] RET ENDP WndCreate
ENDPROGRAM skelet64