Photo by Serge Kutuzov on Unsplash
Contents
Getting started
Now that we have Win32Lib installed, let’s use it to write a complete application from start to finish. We’ll be cloning everyone’s favorite text editor, Notepad! You may be surprised how much work goes into such a simple application.
The code I’m showing here will require that you’ve followed Clean up your code by fixing up Win32Lib.
Fire up Notepad++ and open click File > New. Then click File > Save As… and name it notepad.exw
.
You can download the complete code from this article here: notepad1.exw (1kB)
Basic layout
The arrangement of a Win32Lib application typically goes like this:
- include files
- define controls
- assign events
- run main loop
Include files
These are the basic files we’ll need to include:
Win32Lib.ew
is, of course, the main library with all of the GUI routinesstd/filesys.e
provides routines to easily parse file name partsstd/io.e
provides routines to easily load and save text filesstd/win32/msgbox.e
provides a standard Windows interface
include Win32Lib.ew
include std/filesys.e
include std/io.e
include std/win32/msgbox.e
Define controls
We’ll need a few controls to get started:
Main
is aWindow
– our main windowEditor
is anMleText
– a Multi-Line Edit text controlStatus
is ourStatusBar
– this sits at the bottom of the window
The create
routine accepts eight parameters:
integer ctype
– the control type to be createdsequence text
– the text to be assigned to the controlinteger parent
– the parent control IDobject left
– the left position of the controlobject top
– the top position of the controlobject width
– the width of the controlobject height
– the height of the controlobject style
– additional or default styles for the control
We’re going to need a couple extra window styles:
ES_NOWORDWRAP
usesWS_HSCROLL
andES_AUTOHSCROLL
to disable word wrappingSBARS_SIZEGRIP
adds a grip to theStatusBar
, but is not included in Win32Lib by default
Win32Lib adds a few styles to controls by default that looked good on previous versions of Windows but they don’t look so great on Windows 10. We’ll turn those off with the removeStyle
routine.
constant ES_NOWORDWRAP = WS_HSCROLL+ES_AUTOHSCROLL
constant SBARS_SIZEGRIP = 256
constant
Main = create( Window, "Notepad", 0, Center, Center, 960, 600 ),
Editor = create( MleText, "", Main, ,,,, ES_NOWORDWRAP ),
Status = create( StatusBar, "", Main, ,,,, SBARS_SIZEGRIP ),
$
removeStyle( Editor, {WS_BORDER,WS_EX_CLIENTEDGE} )
Assign events
We didn’t give our Editor
control any position or size values, so if you ran this application right now, the control would be nowhere to be found. We can fix that by handling the OnResize
event and giving the control some boundaries.
Every Win32Lib event handler is a procedure
that requires three parameters:
integer self
– the control ID of the control generating the event; generated by thecreate
routineinteger event
– the event ID of the event type being generated; constants declared asw32H
-event namesequence params
– a list of optional parameters unique to each event
Events are assigned using the setHandler
routine, which accepts three parameters:
object id
– one control ID or a sequence of control IDs to be assigned to this handler; same as aboveobject event
– one event ID or a sequence of control IDs to be assigned to this handler; same as aboveobject rtn_id
– one routine ID or a sequence of routine IDs to handle the event(s); useroutine_id
In most cases you’ll assign one control and one event to a handler routine. You could also assign many controls to the same handler for the same event, and then branch the handler with if
or switch
blocks, which we’ll see later. I typically name my event handler something obvious like ControlName_EventType
but that’s entirely up to you.
Resize event
Now, back to our resize problem. We’ll catch the OnResize
event and then use setRect
to put the control into place.
The setRect
routine accepts six parameters:
integer id
– the ID of the control to be resizedobject left
– the new left position of the controlobject top
– the new top position of the controlobject width
– the new width of the controlobject height
– the new height of the controlinteger repaint
– a flag indicating to repaint the control after it’s resized
The setRect
routine also has a few tricks up its sleeve for each of the size parameters:
- Specify an
interger
value as an absolute position - Specify an
atom
value between0.0
and1.0
as a percentage - Specify the constant
w32Edge
to align the control’s parent edge - Specify the constant
w32AltEdge
to align the control’s parent opposite edge - Specify a sequence
{ constant, value }
where:constant
isw32Edge
orw32AltEdge
value
is aninteger
oratom
to offset from that edge
As it turns out, setRect
is pretty powerful. I recommend experimenting with these options to get the hang of it.
We’re just going to use setRect
to dock the Editor
control to the outer bounds of the window with w32Edge
.
procedure Main_OnResize( integer self, integer event, sequence params )
-- dock the Editor to the outer bounds and force it to repaint
setRect( Editor, w32Edge, w32Edge, w32Edge, w32Edge, w32True )
end procedure
setHandler( Main, w32HResize, routine_id("Main_OnResize") )
The main loop
Now that we have some controls defined and an event handler for OnResize
, we can run our application with WinMain
.
The WinMain
routine accepts two parameters:
integer id
– the control ID of theWindow
to be the main windowinteger style
– the initial state of the window:Normal
,Minimized
, orMaximized
Add this line to the end of our file, save it, and press your Run in Euphoria key (mine is F6
).
WinMain( Main, Normal )
Hello, Notepad! In the next part, we’ll add some menus and fill out the basic file loading routines.