The EuWinGUI Library


A GUI wrapper for Euphoria Win32 Applications.
Based on the original WinGUI C++ Library.

(C)2001-2006 by Andrea Cini.



Index of Contents:

Introduction
What's this?
Disclaimer & distribution
Installing EuWinGUI
How does it work - a simple example
EuWinGUI applications with multiple windows
Performing lengthy background operations
What about graphics?
Printing with EuWinGUI
The EWGUties.ew utility library
Binding and Compiling a EuWinGUI application
Hints and FAQ
Appendix A: EuWinGUI Global Variables
Appendix B: EuWinGUI Control Types
Appendix C: EuWinGUI Event Types
Appendix D: Other EuWinGUI Global Constants
Appendix E: EuWinGUI Functions and Procedures
Appendix F: Operating System Limits
Appendix G: Demo Applications
Credits


Introduction


EuWinGUI provides a very simple way for the creation of Windows GUI ANSI 32-bit applications with Euphoria.

A simple BASIC-like event checking procedure allows an easy handling of the most common events for the implemented controls, and the resulting application are much smaller than those generated using other very large libraries, making it ideal for the development of applications with simpler graphic interface or for novices of Windows programming.


What's this?


EuWinGUI is not a Win32Lib clone, it is not a reduced version of it and it is not even intended as a replacement of that library, which remains the most complete add-on actually available for Win32 programming in Euphoria.

EuWinGUI is made of completely new code and it is a direct translation in Euphoria language of the early versions of my original WinGUI Library for C++. EuWinGUI is a translation of Version 1.5.0 of the original WinGUI Library for C++ (which has reached up now Version 4.0.0, nearly 10000 lines of source code, advanced event handling, full subclassing, more than 50 different control types and a lot of advanced stuff), with some addictions from later Versions and some simplifications aimed to make the code as compact as possible.

I coded the original WinGUI Library for C++ because I needed a royalty-free GUI framework for my programs which was also "light" enough to be used even for very small applications without the need of shipping with them many additional commercial (often very large) DLLs.

Along the same lines, I decided to port to Euphoria the early versions of my C++ library because I believe that Win32Lib has become by now too big and sophisticated to use for simple GUI applications and too complicated to learn for novices of Windows programming. EuWinGUI is many, many times smaller in size than other existing libraries and can be freely shipped with your applications as well.

Of course, EuWinGUI is not as powerful as Win32Lib, but it comes handy when you have to code applications with simple GUI front-end, and using Win32Lib results simply too "heavy" and overcomplicated. You will probably be surprised by the features offered by this little library, and I hope you will give it a try.

The EuWinGUI code is not compatible with Win32Lib because is an almost exact translation of the original WinGUI library for C++, which nothing has in common with Win32Lib, but since it is made up of a fairly limited set of functions and procedures, an eventual translation from/to Win32Lib format shouldn't be too difficult to be made.

In some cases a few EuWinGUI/WinGUI functions have even the same name than similar functions in Win32Lib; this happens because often those names derive directly from the ones of the original Windows API functions, and from a programmer's point of view it's easier to reuse them than to invent each time brand new names....

Of course, EuWinGUI is distributed together with its own IDE (which uses the same library), Designer.exw. The Designer allows the visual creation of your program's GUI and generates the basic Euphoria code needed to build it making the creation of your program's interface the proverbial piece of cake.


Disclaimer & distribution


The EuWinGUI library is completely FREE for use and for shipping with your personal or commercial Euphoria applications. You are allowed to distribute the Euphoria applications created with the EuWinGUI wrapper ".ew" library(ies) AND the EuWinGUI.dll in either open/free or closed/commercial forms. I just ask you to add somewhere to the documentation of your EuWinGUI programs that they use "The EuWinGUI Library by Andrea Cini", or something similar.

The EuWinGUI library/package is ONLY released to be used for Euphoria programming. You are only allowed to use the EuWinGUI.dll with Euphoria-created applications. You are NOT allowed to create or distribute wrapper or import libraries for the EuWinGUI.dll with any other languages than Euphoria or to use the EuWinGUI.dll with any other languages than Euphoria without a written permission of the Author.

THOUGH VERY WELL TESTED, BEING RELEASED AS FREEWARE, THE EuWinGUI LIBRARY COMES WITH NO WARRANTIES OF ANY KIND. USE IT AT YOUR OWN RISK OR DO NOT USE IT. THE AUTHOR OF THIS LIBRARY CANNOT BE HELD RESPONSIBLE FOR ANY DAMAGE CAUSED BY THE PROPER OR IMPROPER USE OF THIS LIBRARY OR OF THE APPLICATIONS WHICH USE IT (etc. etc. etc..........)

The original WinGUI Library for C++
The EuWinGUI Library for Euphoria
All included demos, images, icons and the Window Designer
(C)2001-2006 by Andrea Cini.
eMail: andrea_cini@katamail.com


Installing EuWinGUI


Installing the EuWinGUI library is quite easy: just unzip the EuWinGUI.zip distribution package mantaining the archive's folder's structure into your main Euphoria directory. This will place the EuWinGUI.dll and icon inside your ...Euphoria\Bin\ folder, the EuWinGUI.ew and EWGUties.ew libraries into your ...Euphoria\Include\ directory and will create three additional folders ("EWG-Docs", "EWG-Demos" and "EWG-Designer") holding the library's documentation, the demos and the Window Designer. You can then move the three new folders where you like most on your system.

This will allow you to run, bind or compile any of the programs included with the package, while an "include EuWinGUI.ew" or "include EWGUties.ew" statement at the beginning of your applications' code will allow you to use inside them all the functions, procedures and variables described below.

In case you are going to distribute your compiled/bound programs, just make sure to distribute the EuWinGUI.dll library with them.


How does it work - a simple example


In EuWinGUI, you don't have to deal with the intricacies of Windows API programming at all. Basically, to interact with your program you just have to check out the current values of two global atoms (called Event and EventOwner) which allow you to determine if and how the user is "doing something" with the interface of your application.

To understand how to play with EuWinGUI, an example is better than ten thousand words. Below is the code of a simple (less than 20 executable lines) EuWinGUI application ("Button.exw", located inside the package's "Demos" folder). It shows a window with a button centered on it. By (left) clicking the button, a message box is shown.

    include EuWinGUI.ew
    atom button1 


    procedure EventLoop()

        while True do
                              
            WaitEvent()
                    
            if Event = Click then
                if EventOwner = button1 then
                InfoMsg("Programmed in Euphoria with the EuWinGUI Library!!","EuWinGUI")
                end if
            end if

        end while

    end procedure

    procedure WinMain()

        Window("EuWinGUI - The First Program",100,100,290,95)
        button1 = Control(Button,"Info",5,10,270,50)

        SetIcon("EuWinGUI.ICO")

        EventLoop()
        CloseApp(0)

    end procedure

    WinMain()

Let's examine the code.

- The include statement, adds the library to the program like any other Euphoria library, so nothing new here;

- the atom button1 will serve to store the handle (i.e. the identifier) of the single control created, a simple button. If more controls were needed, we'd have had to add more variables, one to store the handle of each control added;

- the procedure EventLoop() is the core of the system. Inside it we will check which "event" (i.e. the action generated by the user's interaction with the program's interface) has occurred to our application: the program will (and must) continue to execute this procedure until it terminates, so don't use any "return" statement inside it unless (and until) you want to terminate the program;

- the while True do statement makes sure that the code inside the while loop (the event checking) is repeated continuosly; this is equivalent to make a new call to the EventLoop() function at the end of the event checking code, but recursion in Euphoria could lead to memory leaks, so a simple infinite loop is more efficient in this case;

- the WaitEvent() EuWinGUI procedure is one of the most important of the entire library. It passes the program's flow control to Windows and doesn't return until one of the recognized "events" has occurred. Once one of the recognized events occurs, it sets the global atom Event to the type of event just occurred, and the global atom EventOwner to the handle (i.e. the identifier) of the controls to which the event belongs, then returns. By checking the value of Event and EventOwner once this procedure returns you are able to know which event occurred and to which control (see below which events are available for the various available control types);

- the if Event = Click then statement checks if the event just occurred is a left mouse click;

- the if EventOwner = button1 then statement checks if the click event recorded by WaitEvent() occurred to the button. In positive case, it shows an information message using the EuWinGUI procedure InfoMsg() (equivalent to the Euphoria "message_box()" statement but simpler to use);

- once the event in which we were interested (i.e. the left mouse button was clicked over the program's "Info" button) has been processed, the final end while statement causes to run again the event checking code, until the program terminates; in this case the program closes automatically when the default close ("X") button of the Main Window titlebar is clicked, but, in general, it is possible to terminate an EuWinGUI application at any time by simply exiting the EventLoop() procedure, using a "return" statement;

- inside the procedure WinMain() we build our program's interface (i.e. the main window and the child controls), set the created controls to some specific values (if needed), and finally call the EventLoop() procedure to start the event checking;

- the EuWinGUI Window() procedure is the first to be used when creating the program's interface. It creates the program's main (and only) window with the given caption (in our case "EuWinGUI - The First Program"), position on screen (in our case position 100,100) and dimensions (in our case 290 pixels wide and 95 pixels high). No controls can be added until this procedure is used. Once the window has been created, the procedure sets the global atom WinHwnd with the handle of the just created main window, and returns. The WinHwnd value can be used later as identifier of the main window with each EuWinGUI function or procedure which needs such parameter;

- the button1 = Control(Button,"Info",5,10,270,50) statement calls the EuWinGUI function Control(). This function creates a new control of the specified type (see later the available types), with the given caption, position (relative to the main window's client area) and dimensions, and returns the handle of the newly created control. The handle of the control can be used later as identifier of that control with each EuWinGUI function or procedure which needs such parameter. This function can only be used after the Window() procedure;

- the EuWinGUI SetIcon() procedure sets the icon appearing on the main window's titlebar and on the Windows traybar, with a new one. By default, EuWinGUI applications use the Euphoria icon or the one used with bound programs;

- the EventLoop() statement calls the above procedure which will start the event checking loop;

- the CloseApp(0) EuWinGUI procedure closes the application once the program exits from the EventLoop() procedure, freeing all the resources created by EuWinGUI during execution. If a EuWinGUI program closes without a call to this procedure (for instance for a call to the equivalent Euphoria statement "abort()") the memory used by the application's resources is not freed and it is no more available to the system, so it is important to pay attention to use it before exiting the program. If the application is closed using the default close ("X") button of the main window and the global atom CloseEventEnabled is set to False (default), EuWinGUI frees automatically the memory, but if the CloseEventEnabled variable is set to True and/or additional ways of closing the program are provided (for instance a "Close" button, see "TwoButtons.exw") the CloseApp() procedure must be used to terminate the program;

- the final WinMain() statement obviously starts the program.

Take a look to the other provided demos to see more advanced examples of EuWinGUI applications.


EuWinGUI applications with multiple windows


Creating applications with multiple windows in EuWinGUI is just as easy as creating single-window applications and there are no differences with the way the Events belonging to controls created over different windows other than the Main one are processed.

To create a new, empty child window after the Main one has been created is enough a call to the Control() function using Dialog as first (control type) argument. The handle returned by the function is the one of the newly created child window and can be used as usual with all the library's functions/procedures that need such a value.

The child windows are created with the style currently selected by the WindowType global variable, exactly as it is normally done with the Window() procedure, so it is possible to create child windows with different styles just changing the value of WindowType before the call to the Control() function which creates them.

The procedure SetParentWindow() is then used to set one of the existing windows (e.g. the Main one or one of the created Dialogs) as "parent" (e.g. owners) for all the controls created subsequently by the Control() function, of course until a new call to the same procedure changes it again.
Note that regardless of the window passed to the SetParentWindow() procedure, Dialogs are not "indipendent" window but are always created as children of the Main Window, meaning that if a Dialog overlaps the Main Window, the latter one will result always partially or totally covered. If there is the need of creating a multi-windows application whose windows are all always completely visible if active, there is a very simple techique to follow, described later in the FAQ section, which solves the problem with three additional lines of code.

The only thing to remember when using Dialogs is the fact that, unless the CloseEventEnabled global variable is set to True, if the User clicks on a Dialog's default close button ("X"), the entire application closes as if the default close button of the Main Window was clicked.
To avoid this, if an application uses Dialogs with the default close button active/visible, is enough to set to True the CloseEventEnabled global variable and to process the Close Event of the Dialog(s) so to make it/them invisible with a call to SetVisible() rather than closing the whole application.

See the available demos for some clarifying examples of applications which use multiple windows.


Performing lengthy background operations


I have received many enquiries asking if there was a way for a EuWinGUI application to perform lengthy operations while still being able of responding to the Events generated by the User's interaction with the program's interface. What normally happens when a (very) lengthy operation is started, in fact, is that the program is no more able of responding to any Events simply because it is busy doing another job (the lenghty operation), and the Event's handling code is no more executed until the long job is done and the program's flow revert to normal. This not only means that all the Events generated while the program was busy are lost, but even that the low-level event's handling performed internally by the library on behalf of the Operating System is suspended, causing the application to literally "freeze".

The easiest workaround for this problem is.... to avoid the lengthy operations!! Of course I am kidding, but there is definitely some truth in what I have said. In fact, the real solution consists in performing the lengthy job in many small "steps", temporarily but regularly suspending the operation just to check if there are Events waiting to be processed and handling them, if any, before continuing with it.

Doing that was not possible with previous versions of the library but is finally possible now, thanks to two new routines: IsEventWaiting() and ProcessEvent() .

IsEventWaiting() checks for the existence of any Event (either high or low-level, e.g. internally handled by the library) still waiting to be processed and returns True in positive case. ProcessEvent(), instead, is almost a clone of WaitEvent() with a single (but important) difference: WaitEvent() sets the Event/EventOwner/EventItem global variables and returns ONLY if it has recognized a valid EuWinGUI Event and DOES NOT return if no Events are detected; ProcessEvent(), instead, sets the global variables and returns not only after it has recognized a valid EuWinGUI Event, but ALSO if there are NO Events waiting to be processed (in the latter case Event/EventOwner/EventItem are simply set to zero). That basically means that it is now possible to use the latter procedure to handle the EuWinGUI Events as usual OR otherwise to perform a portion of a lengthy operation when Event is set to zero, meaning that no EuWinGUI Events are waiting.

Two programs, located into the "Demos" folder, "Bricks.exw" and "CDChecker.exw", show how to create applications which are able of responding to any Event while busy doing another long job (examine their fully commented code and read also the "Demos.txt" file for additional infos about them).

The first program is a game, and its main "long job" consists in drawing continuosly its window to update the positions of the "sprites" it uses. Since it is needed to hide the mouse cursor when it is moved over the game's window to avoid covering the moving ball or any of the bricks, it has been necessary to put at the end of each drawing loop a check to see if there are Events of any kind waiting to be processed. If IsEventWaiting() returns True, ProcessEvent() is called to set the main variables Event, EventOwner and EventItem as necessary and the handling code is executed (that is, if a Move Event is detected the mouse cursor is made invisible), then a new drawing loop is performed and so forth.
The second program is an utility application, and its "long job" consists in reading two or more files from disks and checking if they are identical or not. Since the files can be many and/or very big, checking them all could take several minutes of continued work. In this case is very important for any User to be able of aborting the operation or to open/close a report windows showing detailed results of the comparison in progress. To make the application able of responding to the necessary Events, the checking routine has been coded so that a little chunk of the source and backup file to check is read, a comparison is made on the chunk only, then IsEventWaiting() and ProcessEvent() are used to see if there are Events waiting and eventually handle them (in this case, by processing the eventually detected Clicks events for the "abort button" and the "report window") before reading another chunk of bytes and so forth until the files have been read completely.

At this point someone could ask why maintaining WaitEvent(), since it seems that ProcessEvent() does the same job, and maybe more. The answer is that WaitEvent() is MUCH more efficient to use for programs which do not need the special processing method above since this function, when no events are waiting, enters in a "efficent waiting loop" which only consumes a very minimum of system resources and CPU power. ProcessEvent(), on the contrary, is a "busy" function (because it immediately and always returns, even if no Events are waiting to be processed) and this causes a MUCH increased usage of CPU power and system resources (thus also downgrading the performances of the other applications running at the same time), even when it is not strictly necessary. For this reason, the demos above use both the procedures to optimize their performances: WaitEvent() is used with a normal event handling loop while the application is idle, ProcessEvent() is used instead once the program's main job has started.


What about graphics?


Although the original WinGUI for C++ Library implements an almost complete set of graphic functions and procedures, the Euphoria version intentionally features only a few of them to help keeping the library's size as little as possible, especially considering that those functions are not always used on smaller applications.

However, to give EuWinGUI a better modularity and also to allow using it without limitations or together with other 3rd party graphic libraries, the WinGUI SetDrawingProc() procedure has been ported to Euphoria code, together with a basic set of graphic routines which allow to perform all the most common drawing tasks.

First of all it is needed to point out that it is possible for an EuWinGUI application to use all the same graphic functions to draw using two slightly different methods: drawing directly on any Control's surface, in which case you first use SetDrawingControl() to set the control over which you want to draw, or drawing on a Memory Bitmap and then showing it on a Picture Control, in which case you first use SetDrawingMB() to decide which Memory Bitmap you are going to draw over.

The first method (the one originally implemented by EuWinGUI) is useful to add static graphic elements to existing Controls (for example see the "ListView.exw" demo, where it has been used to add a grid to all the List Controls) but is not very easy to handle due to the way the Operating System works. Everyone familiar with API programming in fact knows that it is possible to draw freely over the surface of a window or control using a number of different GDI functions. The problem is that since the Operating System automatically takes care of the visual aspect of all windows and controls, all the drawings added by the User are automatically removed each time that window or control is refreshed (e.g. erased and repainted), making it necessary to redraw them all after these repaintings occur to make them visible again (this is exactly the reason why Win32Lib Users put their graphic instructions inside one or more procedures called by the code when a onPaint event occurs).

EuWinGUI doesn't trap a "Paint" Event according to the usual method but uses the SetDrawingProc() procedure to set the address of a custom procedure (containing the needed drawing instructions to draw over a window or control) which is executed each time that window or control is repainted by the Operating System, making the drawings "persistent".

Obviously, this method is not adequate when the drawings are very complex, change with time, or must be animated. In all these cases, a much practical solution is to use the second drawing method implemented by EuWinGUI, that is, drawing over a bitmap in memory (hence the name Memory Bitmap) and then show that bitmap on a Picture control. Once the bitmap is set to a Picture control, there is no more need for a drawing routine which updates it constantly because that task is automatically performed by the Operating System. A Memory Bitmap can be an "empty" bitmap created directly in memory using the NewMB() function, or it can be a bitmap loaded from a file using the well known LoadPic() function; in either cases, the handle of the new bitmap, created or loaded, can be used with SetDrawingMB() to set it as the currently active bitmap over which all the drawing functions will draw, and can be assigned to a Picture-class control using the SetPic() procedure. Needless to say, if a bitmap as been loaded from an existing file on disk, drawing on that image in memory will NOT modify the file on disk, but ONLY the copy of that image created in memory by the LoadPic() function. It is possible to copy a portion of a bitmap to another using the CopyMB() procedure, and it is also possible to copy a part of it directly over a Control's surface by using CopyMBToControl(). This latter function is very useful since it allows to copy immediately a bitmap over a Control without waiting for the Operating System to erase and repaint it, hence avoiding any noisy flickering when developing games or other animations. This technique of using a Memory Bitmap to draw some graphics and then copy it immediately over a Control to update it is generally called "double buffering" and it is widely used on the Bricks.exw demo game and CDChecker.exw utility (for the simulated progressbar) enclosed with the package. You can think to a bitmap in memory (either created or loaded from file) like an invisible drawing board over which you can freely draw and where your drawings are always persistent, which only becomes visible when it is set to a Picture-class control with SetPic() or it is directly copied over any Control with CopyMBToControl().


Printing with EuWinGUI


EuWinGUI includes a basic set of printing instructions which can be used at runtime from within any programs to get hardcopies of text or graphics - provided that a physical or virtual printer is installed on the system where the program is run! Printing can be thought similar to drawing on a Memory Bitmap, with some notewhorty differences, explained in details below.

Before being able of using with any success the printing functions, it is FIRST necessary to select the physical or virtual printer which will be used to print. It is not possible to create a document for printing before a printer has been selected. The printer's selection is done by using the SelectPrinter() procedure. This procedure takes just one argument, a boolean flag, whose value can be either True or False. True instructs the library to use the default system's printer and settings, while False tells the library to show a standard Print Dialog from which the user will be able to select among the available printers the one which will be used, as well as its settings (like paper orientation, printing quality and everything the printer's driver allows to set).

Once a printer has been selected, it is possible to create a "printing document". This is done by using the NewDocument() function, which accepts a text string as document's name. The document name is only used as a reference and only serves to recognize your document on the printer's spool dialog while printing is in progress. If a empty string is specified, the library will use the "Untitled Document" default name.

A printing document can be made of any number of different pages. When a printing document is created it is made up by a single page, but more can be added by using the NewPage() procedure (which does not take any arguments). When the latter procedure is used, two things happen: the current page is "closed" and sent to the printer's memory buffer and a new blank one is added to the document, that one becoming the new current page over which all the following printing instructions will draw. Note that once "closed", the pages cannot be accessed anymore so you must organize your printing job so that a page at a time is prepared, and closed only when it's fully ready to be sent to the printer for hardcopy.

A document's page can be thought as a blank Memory Bitmap with a certain width and height in pixels (constant for all the pages of the same document) which only depends by the selected printer and it's settings. It is possible to retrieve the width and height of a page by using the GetPageSize() function and specifying either the X_DIM or Y_DIM flags as argument, depending if you need to retrieve width or height of the current page. This function can also be used to test if a printer has been selected or not, a return value of zero for either width or height meaning that no printer has been selected yet.

Once you know the dimension of the page(s), you can start "drawing" text on the current one by using the PrintString() procedure which works exactly like the DrawString() procedure used to draw text on a Memory Bitmap. It is possible to retrive the width and height of a printed string of text by using the GetPrinterStringSize() function - similar to the GetStringSize() one - so that it's possible to center a string on a page or to correctly vertically space two consecutive lines of text on the page with just some basic math.

It is possible to set the font and color which will be used to print any string by using the SetPrinterFont() and SetPrinterPenColor() functions exactly as it's done when drawing on bitmaps. Of course you have no restrictions on the mix of colors and fonts you can use, however unless you are going to use just the default system fonts which are available from start (FN_DEFAULT and FN_FIXED), you will first have to create all your needed fonts using the usual NewFont() function.

It is also possible to print Memory Bitmaps or BMP files loaded from disk to the current page at a given position by using the PrintMB() procedure, this also allows to prepare graphs on Memory Bitmaps and then printing them on paper since direct printing on pages of geometric shapes is not supported. NOTE however that very old printers and most plotters may not support printing of bitmaps. Note also that bitmaps will need longer times to be sent to the printer due to the amount of RAM they use.

When all the pages of a document have been created, the StartPrinting() procedure will actually close the document and send it to the printer starting drawing it on paper. Once a document has been closed and sent to the printer, nothing more can be done on it at run time (though the user can still manually stop/abort printing by using the spool's driver window).

NOTE that the size, in "logical points", of a same font varies depending on the device on which it is used. It can vary considerably when it is used to draw text on screen or to print it on paper since the final size of a font solely depends on the capabilities and settings of the device on which it's used: not only changes completely from the screen to a printer, but can also change from a printer to another or from a screen to another depending, for example, on the Windows theme used!

For instance if you create a MB, draw a string on it using the default font and then print it with PrintMB(), you will note that the dimensions of that string on paper will be much different than if you had directly printed that same string with the very same fonts using the PrintString() procedure. That happens because the Memory Bitmap uses the device capabilities and settings of your screen, which are quite different from the ones of your printer.

Consider that if the width in pixels of your screen is normally 1024 or 1280, the width of a normal printer's page easily exceeds 4000; it is the Operating System on behalf of the drivers of both your printer and your screen that work in the background so that the dimensions of a same characther using the same font appear similar to your eyes when you either see it on screen or printed on a sheet of paper. So, in case you need to mix up strings printed with PrintString() and MBs with strings drawn at run time on them, it's up to you to create MBs and to draw with fonts whose sizes, in pixels, are consistent with the sizes of the fonts used to print strings directly on a document's page.

See the "Printing.exw" demo for a practical example on how to use the printing functions.


The EWGUties.ew utility library


The EWGUties.ew utility library is a recent addition to the package and holds a number of utility fuctions, procedures and code snippets that will make faster and easier the creation of EuWinGUI applications. Each function or procedure is commented at the beginning of its declaration, explaining its intended use and can be freely modified to better fit your own needs. Since EWGUties.ew includes EuWinGUI.ew, it is enough to include EWGUties.ew at the beginning of your programs to be able of using all the EuWinGUI functions and procedures as well.


Binding and Compiling a EuWinGUI application


There are not particular procedures to follow to bind or compile a EuWinGUI program, just remember to leave routine names clear if you are using Euphoria versions older than 3.x.x since EuWinGUI uses routine_id().

EuWinGUI applications can be bound or compiled using either Euphoria V2.4, 2.5 or the latest Open V3.x.x versions.


Hints and FAQ


Q: Why only the most common event types are available to EuWinGUI Programmers?
A: Because I wanted to leave the library as small and simple as possible, so control's subclassing has been kept to a minimum; Euphoria programmers already have Win32Lib, if something more "heavy" and powerful is needed. For the same reasons keyboard shortcucts are not directly implemented in EuWinGUI (though they can be rather easily simulated). It is possible, however, to add a number of additional Events by using the provided low-level procedures and functions like TrapMessage(), Message() and GetTrappedMessage(), but a good knowledge of Windows programming is requested to be able of using them.

Q: Why there is only a limited set of control types available?
A: For the same reasons above only the most common used controls are implemented. However, remember that a number of additional controls can be easily simulated with EuWinGUI: Progressbars, ComboBoxes, StatusBars, simple ListViews but even Tabs or more complicated controls can be simulated using the other available EuWinGUI ones. See the demos to see how. Remember, Win32Lib is there if you need a wider coverage of ready-to-use common controls, EuWinGUI is designed for simpler applications.

Q: I have created a PictureButton control, but nothing appears on it, why?
A: Because no images (BMPs) have been loaded into it. Use the SetPicture() procedure to load an existing BMP into the PictureButton once it has been created.

Q: I have created a ClickPicture or a Picture control but nothing appears on the main window, why?
A: Picture/ClickPicture controls are created initially empty (like the Picture/PushButton), and since they have no visible parts they look initially "invisible". To let them appear use the SetPicture() procedure to load a BMP image into them after they have been created. Note that despite the dimensions you specified for it when creating the control (and differently from Picture/PushButtons), it is always resized to the dimensions of the image you loaded into it after the SetPicture() procedure is used. However, once an image has been loaded you can use the SetDim() procedure to resize it again to the desired dimensions and the loaded image is then stretched to fit it completely. Note also that a ClickPicture control can respond to the Click events only if it is visible, i.e. after an image has been loaded into it.

Q: I used a EuWinGUI function, the Euphoria interpreter doesn't encounter sintax errors, but the function doesn't work...
A: One of the arguments you used is not valid. Quite surely the handle of the control you are passing to the function is not valid (i.e. the control doesn't exist, or it is not valid for that function, for example you passed the handle of a Button control to one of the List() functions which work only on List controls) or another parameter is wrong (for instance the filepath you are passing as argument of a SetPicture() or SetIcon() function is not correct and the file can't be found). Always check that the parameters you are passing as function's arguments are valid.

Q: I intercepted the Click event for an Edit control, but after performing the needed actions, the control doesn't receive the input focus and I can't write inside it, why?
A: By intercepting the Click event of an Edit control you could "break" the normal Windows procedure and the control could lose the input focus. So, after executing your code, if it loses the keyboard input due to the code just executed but you still need to write into the Edit field, use the Activate() procedure to set again the input focus to that control (this doesn't cause a new Click event).

Q: I wanted to use an image as background of the main window, so I have created a ClickPicture which fits the window's client area and then I added the other controls (buttons and so on) "over it" but they do not respond to my clicks: why?
A: Because all the clicks events in case of overlapping (i.e more controls use the same phisycal space) are first catched by the ClickPicture control. Use always a Picture control (which do not respond to events) as background image, that way all the other controls (even other ClickPictures) will respond normally to click events. Always avoid overlappings between ClickPictures and other controls, if the other controls must respond to Clicks.

Q: I have made a program with EuWinGUI which starts an external application using the system()/system_exec() functions of Euphoria, but once the application is launched, the interface of my program appears erased and it is not restored until the external application finishes: what's happening?
A: system() and system_exec() break the normal repainting handling made automatically by EuWinGUI on your program. To start an external application from within a EuWinGUI program use the EuWinGUI function RunApp(), instead. It works almost like system()/system_exec() but has also some interesting advantages. For instance it can run directly not only EXE/COM/BAT files, but even every file whose extension is already associated to a given application, or can open existing directories. For instance, if you run a .TXT file, the Windows Notepad (or whatever application you have associated with .TXT files) is automatically run with it. "Runner.exw" uses this function to work, give it a look.

Q: I'm clicking on a List control, but it doesn't respond to the click event: where is the problem?
A: Probably you are not clicking over a List's item. If you click over an empty list or if you do not click over a List's item (string), the OS doesn't generate the Click event. The reason is that Click events for the List control generally serve only to know if and how the List index has changed, and this is also the reason why the Click event is generated also if you change the index of an active List by using the keyboard's arrows and not only by clicking over an item with the mouse.

Q: I have added two Radio groups to a same window, but they don't work as expected: if I click on a Radio control of one group, all the other Radio controls of both the groups are unchecked automatically, why?
A: Because each added (automatic) Radio control is actually created as a child of the same window, so Windows treat them as if they belonged to a same group. If you need more than a single radio group, use SimRadio controls instead; these are not automatically controlled by Windows and by processing the Click event for each one of them and using the SetCheck() procedure you can uncheck all the controls belonging to a same group and check only the control that was clicked. See RadioGroups.exw for an example on how to do that.

Q: My application uses very often the SetPicture() procedure to load images at run time. All seems working well but after a certain number of loadings, it is no more able of changing images and when I try to close the application I get an "out of memory error". What's happening?
A: The SetPicture() procedure loads a bitmap in memory, retrieves the handle of the image and stores it into the global variable PictureHandle, finally setting it to the specified control. The memory used by the loaded image is no more available to other applications until the program terminates or the memory is freed by a call to DeleteImage(), and this happens in any case, even if the SetPicture() procedure is used to load several times a same image, and even if it is replaced later on the control with another image. That means that if the program uses very often the SetPicture() procedure at run-time to load the same or different large bitmap images, it is very possible that your system goes phisycally out of memory. The solution to the problem is just to use the function LoadPic() to load just once the bitmaps which are needed several times or by several controls and use the SetPic() procedure to set them, then delete the unused images from memory using the DeleteImage() procedure as soon as they are no more needed by your program.

Q: I need to create a multi-windows application, and I need that all the windows are completely visible once they are active, but the Main Window, regardless of its active state, is always covered by any Dialog overlapping it. How can I make it fully visible?
A: There are no ways to make it fully visible as the Dialogs, though are normal windows, are always created as child controls of the Main one, so the Operating System gives them "visual precedence" over their parent. However there are several very simple techniques which allow to solve completely the problem, and consist in creating (and not using) the Main Window, but using only Dialogs which, having the same visual precedence, are always completely visible once active. The following code achieve this:
    WindowType = NoBorderWin
    Window("",0,0,0,0)
    WindowType = NoMaxWin
    window1 = Control(Dialog,"One Window",...)
    window2 = Control(Dialog,"Another Window",...)
    SetParentWindow(window1)
    control1 = Control(....)        -- controls belonging to window 1 go here
    SetParentWindow(window2)
    control10 = Control(....)       -- controls belonging to window 2 go here
You can see that the Main Window is created as a borderless window with zero height and width (e.g. "it is there but you can't see it"), and two Dialogs are then creatd with the needed style and populated with the needed controls. Having the same visual precedence they are always completely visible once active and the problem is solved. Note that since the Main Window is (and must be as in anyEuWinGUIapplication!) created, you will be able of handling the HotKey and Timer Events as usual.

Q: I want to create a Memory Bitmap to use it on a PictureButton. Is there a way to use the UseTransparentPics flag with it so that its background color is transparent?
A: The UseTransparentPics flag has no effect when setting a picture created using NewMB(), however to show a Memory Bitmap with a "transparent" background, you could set the pen color to the color of the button's surface (using GetPixelColor() once the button is visible) before creating the bitmap which will then be created using a background color equal to the one used by the Operating System for the button.

Q: I am trying to print the same document using two different printers, but I am getting completely different results in terms of font dimensions and lines per page... any help?
A: That depends on the fact that any printer has its own settings which may vary a lot from one to another. It is up to the programmer to create printing routines that will work the same on most printers. The EWGUties.ew utility library holds a custom routine, GetFontLines(), which creates and returns the handle of a font according to a family name and attributes specified so that if used as printer's font with SetPrinterFont(), each printed page will hold a number of lines as close as possible to a desired value, whatever printer is selected to print the document.

Q: I see the key code for the Function Key 1 (F1) but can't see the codes of the other ones. How can I check if key F3 is pressed, for example?
A: Simply add 1 or more to the value of KEY_FUNC01 to test for the other function keys other than F1. To test for key F2 use KEY_FUNC01+1, to test for F3 use KEY_FUNC01+2 and so on up to KEY_FUNC01+11 for key F12.

Hint: Remember that the graphical appearance of your application can change depending on the User system's setting. In particular, if you create your application on a system that uses Small Fonts (the majority by now) and then run it on a system which still uses Large Fonts (or vice-versa), the appearence of any control which uses captions (Buttons, Texts, Labels and so on) will be slightly different due to the different size of the fonts. For this reason it is always good to test the application on systesm using different fonts, or, if your system uses Small Fonts, to make at least the controls with a caption a little bigger than necessary to make room for the enlarged fonts, in case your application is used on systems using Large Font.


Appendix A: EuWinGUI Global Variables


The following Global Variables are defined and used by EuWinGUI:

atom Event
(stores the last Event type recorded after returning from the WaitEvent() procedure)

atom EventOwner
(stores the handle of the control to which the last Event recorded after returning from the WaitEvent() procedure belongs)

atom EventItem
(stores an additional value associated with certain Event types, after returning from the WaitEvent() procedure; for instance stores the char code of the key pressed, once a Key Event has occurred)

atom UserTrap
(is set to True each time one of the "trapped messages" passed to the TrapMessage() procedure is processed by the library and causes WaitEvent() to return in order to handle it)

atom WinHwnd
(stores the handle of the Main Window, after it has been created using the Window() procedure, for use with any EuWinGUI function which need a control's handle to work)

atom PictureHandle
(stores the handle of the last bitmap loaded after a call to the SetPicture() procedure (so it can be NULL if the latter function fails). The handle of a bitmap can be used with the SetLPicture() to load it multiple times into a same or different controls without using additional memory, or with the DeleteImage() procedure to free up the used memory if the bitmap is no more needed)

atom CloseEventEnabled
(initially set to False; if set to True before running the event loop allows the generation of a Close event if the user clicks on a window's default close button; process this Event to perform some actions before the application is finished (and remember to finish it with a call to the CloseApp() procedure to free the resources created by EuWinGUI) or to make a Dialog control invisible in a multiple-windows application)

atom UseTransparentPics
(initially set to False; if set to True before using the SetPic() procedure, tells Windows to use the color of the leftmost/topmost pixel of a bitmap loaded from a file as "transparent color": all the occurences of that color inside the image are automatically replaced with the color of the window's surface, so that is possible to load into Picture/ClickPicture/PictureButton controls images with a "transparent" background); Note that this flag has no effect if the bitmap has been created in memory using NewMB()

atom WinOnTop
(initially set to False; set this variable to True before using the Window() procedure if you need to create an always-on-top Main Window)

atom WindowType
(initially set to NoMaxWin; use this variable to set the appearance (style) of the Main Window or of a Dialog control before using the Window() procedure or the Control(Dialog,...) function. Five different styles are available:

NoMaxWin - default; window with titlebar, minimize+close buttons and solid frame
NoMaxMinWin - window with titlebar, close button only and solid frame
NoSysWin - window with titlebar, no active buttons and solid frame
NoTitleWin - window without titlebar and solid frame
NoBorderWin - flat window without titlebar and border

Note:
  1. windows created with either NoTitleWin or NoBorderWin styles, lacking the titlebar, cannot be moved on the screen by the program's User (but it is still possible to move them at run-time)
  2. program which uses a Main Window created with one the latter styles or the NoSysWin one, lacking the default close ("X") button, MUST provide an alternative way to close the program; the EWGUties.ew utility library provide the CloseAppOnEscape() procedure for this )

atom ShowFlag
(initially set to True; by default, the Main Window and all controls are shown immediately after their creation. By setting this variable to False BEFORE the creation of the main window or any control it is possible to create them initially hidden. To make them visible it will be necessary a call to the SetVisible() EuWinGUI procedure. For example if an application uses many controls the interface's creation could take some time and cause some noisy "flickerings". By setting this variable to False BEFORE using the Window() procedure and resetting it to True BEFORE the creation of the controls, the main window is not shown after its creation and remains hidden until a call to SetVisible(WinHwnd,True) make it visible. This way it is possible to add all the needed controls to the window while it is still hidden and then make it visible only after the interface is completely created and all the settings have been made (i.e. before entering the event loop); this way, no flickerings occur)

atom MouseX,MouseY
(store the pointer's coordinates, relative to the upper-left corner of the control's client area, after the occurrence of a recognized mouse event (i.e. Click, Release, RClick, RRelease, Move if the issuing control is the Main Window or a Dialog, or the Move event only if the control is another type)
Note: The Move events generated while one of the mouse buttons is pressed (as well as the Release and RRelease events) and recognized by the Main Window or by a Dialog can be issued when the mouse pointer is phisically out of the owner window's boundaries. Since the values stored into MouseX/Y can range from 0 to 65535 (e.g. no negative values are returned by Windows) and are relative to the upper-left corner of the window's client area, it is not directly possible to know if the mouse has generated the events inside or outside the window's boundaries.
However it is possible to know that with a simple check: if MouseX (MouseY) is bigger than the width (height) of the owner's window, it means that the event was surely generated while the mouse was outside the right (bottom) boundary of the window, BUT if MouseX (MouseY) is ALSO greater than the screen's width (height) it means that the event was generated while the mouse pointer was outside the left (top) boundary of the window's client area. Practically, if MouseX (MouseY) returns a value of 65535, it means that the event was generated when the pointer was located 1 pixel left (up) of the beginning of the window's client area, 65534 means it was 2 pixels left (top) and so on.)

atom Ticks
(counts and stores the Time Events generated and not processed while a message box or file dialog is shown; the use of a message box or file dialog (e.g. the use of the InfoMsg()/WarnMsg()/AskMsg()/FileDlg() procedures or functions) temporary freezes the application, suspending the generation of all Event types until the message box is closed. That means that, if using the Timer, all the Time Events generated while the message/dialog box was shown went lost. This global atom counts and stores the Time Events generated and not processed while a message box or file dialog is shown, allowing the application to update itself as necessary once the message/dialog box is closed)


Appendix B: EuWinGUI Control Types


The following Control Types are available for use with the EuWinGUI Control() function:

Dialog (new empty child window)
Button (simple button with a caption)
PushButton (button with a caption which can be toggled pushed or unpushed)
PictureButton (button showing a custom BMP picture instead of a caption)
PicturePushButton (button showing a custom BMP picture which can be toggled pushed or unpushed)
Edit (editable field with horizontal scrollable text)
MultiEdit (multiline editable field with horizontal scrollable text)
SimEdit (simple editable field with fixed width text)
SimMultiEdit (simple multiline editable field with fixed width text and word wrapping)
Check (automatic check box with a caption)
SimCheck (simple check box with a caption)
Radio (automatic radio box with a caption)
SimRadio (simple radio box with a caption)
Text (left-aligned static text)
FramedText (left-aligned framed static text)
Label (centered static text)
ClickText (left-aligned clickable static text)
ClickLabel (centered clickable static text)
Group (unclickable group box)
Picture (flat unclickable control showing a custom BMP picture)
ClickPicture (flat clickable control showing a custom BMP picture)
List (simple list box)
SortedList (sorted list box)
SimMultiList (flat multicolumn horizontal list box with no scrollbars)
SelecList (list box which allows to select multiple lines using the CTRL or SHIFT keys while clicking)
SortedSelecList (sorted version of a SelecList)


Appendix C: EuWinGUI Event Types


The following Event Types are defined as global constants:

Click
(recognized/generated by: ALL windows and controls BUT Group,Picture,Framed/Text,Label
when: one of the specified controls is clicked with the left mouse button; if the control is a window, the Event is generated when the mouse button is pressed, otherwise it is generated when the button is released)

Move
(recognized/generated by: ALL windows and controls BUT Group,Picture,Framed/Text,Label
when: the mouse pointer is moved over the client area of one of the specified controls not covered by others)

Release
(recognized/generated by: Main Window,Dialog
when: the left mouse button is released after it was pressed over a window)

RClick
(recognized/generated by: ALL windows and controls BUT Group,Picture,Framed/Text,Label
when: the right mouse button is pressed over a window. Note: by handling this Event it is possible to incidentally break the normal handling procedure of the same event (if any) made by Windows. For example, by intercepting the RClick Event of an Edit field it is possible to prevent the default Cut/Copy/Paste Windows popup menu to be shown. For this reason, particular care must be made if intercepting this Event while the owner control already has an associated default Windows action to perform)

RRelease
(recognized/generated by: ALL windows and controls BUT Group,Picture,Framed/Text,Label
when: the right mouse button is released after it was pressed over a window)

DClick
(recognized/generated by: List,SortedList,SimMultiList
when: a list control is rapidly double clicked with the left mouse button; note that this Event is generated after two Click Events have been issued for the same control)

Key
(recognized/generated by: ALL windows and controls BUT Group,Click/Picture,Framed/Click/Text,Click/Label
when: a control has the input focus and a keyboard's key is pressed; the char code of the key pressed is stored into the global variable EventItem; in addiction to all the printable keys, most not-printable keys generate this event (see the list in Appendix D); control/system keys (Ctrl, Shift, Alt and so on) DO NOT generate this Event)

HotKey
(recognized/generated by: ALL windows and controls BUT Group,Click/Picture,Framed/Click/Text,Click/Label
when: each time the "Tab" keyboard's key is pressed and one of the specified controls has the keyboard input)

Restore
(recognized/generated by: Main Window,Dialog
when: each time a window is restored from the Windows Taskbar)

Close
(recognized/generated by: Main Window,Dialog
when: CloseEventEnabled is set to True, and the user clicks on the window's default close ("X") button)

Time
(recognized/generated by: Main Window
when: every "interval" milliseconds, after the timer has been set with SetWinTimer(interval) procedure)


Appendix D: Other EuWinGUI Global Constants


True (=1)
False (=0)

Flags - to use as parameter of the FileDlg() function

Save
Open

Flags - to use as parameter of the GetStringSize()/GetPrinterStringSize() functions

X_DIM (get the string's width)
Y_DIM (get the string's height)

Window Styles - to use with global variable WindowType

NoMaxWin
NoMaxMinWin
NoSysWin
NoTitleWin
NoBorderWin

Deafult Font Handles - to use with the SetFont() and SetPrinterFont() procedures

FN_DEFAULT (default variable-width system font)
FN_FIXED (default fixed-width system font)

Deafult Cursor Handles - to use with the SetCurs() procedure

CR_WE (West-East double arrow)
CR_NS (North-South double arrow)
CR_SIZE (Four directions arrow)
CR_VARROW (Vertical arrow)
CR_WAIT (Hourglass)
CR_NULL (No cursor visible)

Colors - to use with the SetPenColor(), SetPrinterPenColor() and SetColor() procedures

CL_WHITE (White, #FFFFFF)
CL_GRAY (Gray, #C0C0C0)
CL_DKGRAY (Dark Gray, #808080)
CL_BLACK (Black, #000000)
CL_YELLOW (Yellow, #00FFFF)
CL_DKYELLOW (Dark Yellow, #008080)
CL_RED (Red, #0000FF)
CL_DKRED (Dark Red, #000080)
CL_GREEN (Green, #00FF00)
CL_DKGREEN (Dark Green, #008000)
CL_CYAN (Cyan, #FFFF00)
CL_DKCYAN (Dark Cyan, #808000)
CL_BLUE (Blue, #FF0000)
CL_DKBLUE (Dark Blue, #800000)
CL_PURPLE (Purple, #FF00FF)
CL_DKPURPLE (Dark Purple, #800080)

CL_DEFAULT (pseudocolor, to use as argument of the SetColor() procedure only: Default Control's color)

Not-printable Key Codes - to use with the IsKeyPressed() procedure and the Key Event

KEY_ENTER
KEY_BACKSPACE
KEY_ESCAPE
KEY_DOWN
KEY_UP
KEY_LEFT
KEY_RIGHT
KEY_CLEAR
KEY_PAUSE
KEY_CAPSLOCK
KEY_PGUP
KEY_PGDN
KEY_END
KEY_HOME
KEY_INS
KEY_DEL
KEY_FUNC01


Appendix E: EuWinGUI Functions and Procedures


Here follows a complete listings of all the EuWinGUI functions and procedures, in alphabetical order:

Activate(control)
ActivateText(control)
atom AskMsg(message, caption)
CloseApp(exitcode)
atom Control(controltype, caption, xpos, ypos, xsize, ysize)
CopyMB(sourcebitmap, xpos, ypos, xsize, ysize, destbitmap, destxpos, destypos )
CopyMBToControl(sourcebitmap, xpos, ypos, xsize, ysize, destcontrol, destxpos, destypos )
DeleteImage(imagehandle)
DrawLine(startx, starty, endx, endy)
DrawMultiLine(linestodraw)
DrawPoint(pointx, pointy)
DrawPolygon(points, fillflag)
DrawString(startx, starty, text)
sequence FileDlg(flag, defaultfile, filters)
atom GetCount(control)
sequence GetEditSel(editcontrol)
atom GetIndex(control)
sequence GetItem(control)
atom GetListItemHeight(control)
atom GetPageSize(dimensionflag)
atom GetPixelColor(xpos,ypos)
atom GetPrinterStringSize(string, font, dimensionflag)
sequence GetSelec(control)
atom GetStringSize(control,string, font, dimensionflag)
sequence GetText(control)
sequence GetTrappedMessage()
InfoMsg(message, caption)
atom IsChecked(control)
atom IsEventWaiting()
atom IsKeyPressed(key)
ListAdd(control, item)
ListClear(control)
ListDel(control)
ListIns(control, item)
ListPut(control, item)
ListSeek(control, position)
atom LoadCur(cursorpath)
atom LoadPic(imagepath)
atom Message(hwnd,msg,wParam,lParam,delayflag)
atom NewDocument(documentname)
atom NewFont(fontname, fontsize, bold, italic, underlined)
NewMB(width, heigth)
NewPage()
PlaySnd(wavfile)
PrintMB(sourcebitmap, xpos, ypos, mbwidth, mbheight )
PrintString(startx, starty, text)
ProcessEvent()
RunApp(program, parameters)
integer ScreenHeight()
integer ScreenWidth()
SelectPrinter(flag)
SetCheck(control, flag)
SetColor(control, textcolor, backcolor)
SetCur(cursorshape)
SetDim(control, newwidth, newheight)
SetDrawingControl(control)
SetDrawingMB(bitmap)
SetDrawingProc(control, procedureID)
SetEditSel(editcontrol, startpos, endpos)
SetEnable(control, flag)
SetDrawingFont(font)
SetFixedFont(control)
SetFont(control, font)
SetIcon(iconpath)
SetListCWidth(smlistcontrol, width)
SetParentWindow(parentwindow)
SetPic(control, controltype, imagehandle)
SetPicture(control, controltype, imagepath)
SetPenColor(color)
SetPenSize(width)
SetPos(control, newxpos, newypos)
SetPrinterFont(font)
SetPrinterPenColor(color)
SetRefresh(control)
SetRepaintOn(control, flag)
SetText(control, newcaption)
SetVisible(control, flag)
SetWinTimer(interval)
StartPrinting()
StopSnd()
TrapMessage(msg)
WaitEvent()
WarnMsg(message, caption)
Window(caption, xpos, ypos, xsize, ysize)


Activate(control)

Sets the input/keyboard focus to the specified control. This procedure is especially useful to reactivate a control after the handling code of an Event caused the control to lose focus (for example, because a message box was shown). If used to activate an editable field, any eventual text already typed/present into it IS NOT selected.

[atom control] is the control to activate


ActivateText(control)

This procedure works exactly as Activate() with most controls, but, differently from the latter procedure, if the activated control is an editable field, any eventual text already typed/present into it IS selected and the caret is placed to the end of it.

[atom control] is the control to activate


atom AskMsg(message, caption)

Shows a standard ask Dialog with custom message, Yes/No buttons, caption and the question icon. If the user clicks on Yes buttons the function returns True, otherwise it returns False. Note: the application freezes (e.g. do not process any Event) until the message box is closed.

[sequence message] is the message to show
[sequence caption] is the Dialog's window caption


CloseApp(exitcode)

Closes the application with the given exit code. Use always this procedure to terminate any EuWinGUI application, so that the memory allocated for fonts and other resources is correctly freed.

[atom exitcode] the code returned to the system when the application closes


atom Control(controltype, caption, xpos, ypos, xsize, ysize)

Creates one of the supported Control Types, and returns its handle. Can be used only after that the Window() function has been used. If the control can't be created, the function returns zero.

[atom controltype] is one of the supported Control Types
[sequence caption] is the text associated to the Control
[atom xpos,ypos] the Control's coordinates relative to the Window
[atom xsize,ysize] the Control's width and height


CopyMB(sourcebitmap, xpos, ypos, xsize, ysize, destbitmap, destxpos, destypos )

Copies part of, or an entire bitmap into another, at the specified position. It is possible to copy to the destination only a rectangular portion of the source bitmap by specifying the desired size and the top-left corner's coordinates of the rectangle to copy. Both the source and destination bitmaps can be either Memory Bitmaps or bitmaps loaded from files. See the "What about grahics?" chapter of this guide for more informations on the subject.

[atom sourcebitmap, destbitmap] are the handles of the source and destination bitmaps
[atom xpos,ypos] the coordinates on the source bitmap of the top-left corner of the rectangle which will be copied
[atom xsize,ysize] the width and height of the rectangle which will be copied from the source to the destination bitmap
[atom destxpos,destypos] the coordinates on the destination bitmap of the top-left corner of the rectangle which will be copied


CopyMBToControl(sourcebitmap, xpos, ypos, xsize, ysize, destcontrol, destxpos, destypos )

Copies part of, or an entire bitmap over a control's surface, at the specified position. It is also possible to copy only a rectangular portion of the source bitmap by specifying the desired size and the top-left corner's coordinates of the rectangle to copy. The source bitmap can be either a Memory Bitmap or a bitmap loaded from file and the destination control can be any visible control. The effect of this procedure is identical to the one you get when drawing with any of the drawing functions over a control, and so the copied bitmap is not persistent but will be erased by the operating system as soon as the control needs to be refreshed. The main purpose of this procedure is to provide an immediate and flicker-free method to update the appearance of a control (generally a Picture-class control), by drawing directly the bitmap over it. See the "What about graphics?" chapter of this guide for more informations on the subject.

[atom sourcebitmap] is the handle of the source bitmap
[atom destcontrol] is the handle of the destination control over which the bitmap, or portion of it, will be drawn
[atom xpos,ypos] the coordinates on the source bitmap of the top-left corner of the rectangle which will be copied
[atom xsize,ysize] the width and height of the rectangle which will be copied from the source to the destination control
[atom destxpos,destypos] the coordinates on the destination control of the top-left corner of the rectangle which will be copied


DeleteImage(imagehandle)

Deletes a previously loaded but no more needed bitmap or Memory Bitmap to free up unused memory. Every bitmap created with the NewMB() function, loaded with the LoadPic() function or the SetPicture() procedure uses a certain amount of RAM which is not released until the program terminates. If a program makes large use of bitmaps, it is a good rule to delete the unused ones by using this procedure to avoid the risk of running out of memory (of course if they have been loaded from a file, the images are only deletes from memory, not from disk!). The argument of the procedure is the handle of the bitmap to delete, e.g. the value stored into the PictureHandle global atom after the SetPicture() procedure was used to load the image, or the handle returned by a call to LoadPic(), or the one returned by NewMB().
Note that using LoadPic() or SetPicture() multiple times to load a same image has the effect of creating multiple copies of it in memory so the handle returned by LoadPic() or stored into PictureHandle after any call to these routines will be each time different, exactly as if different images were loaded.
So, to free up all the memory, create a custom sequence recording all the values stored into PictureHandle after any call to SetPicture() or returned by LoadPic(), and use the DeleteImage() procedure with all of them. Obviously, the handle of a deleted image is no more valid and cannot be used anymore.

[atom imagehandle] is the handle of the previously loaded bitmap to delete


DrawLine(startx, starty, endx, endy)

Draws a straight line over the client area of the window or control indicated by the last call to SetDrawingControl(), or over the memory bitmap indicated by the last call to SetDrawingMB() using the color indicated by the latest call to SetPenColor() and a line width indicated by the last call to SetPenSize(). Since any drawing made directly over a window or control's surface is automatically cleared by the operating system when the window or control is repainted, to make the drawings persistent (e.g. always visible at any one time) they must be placed inside a custom "paint procedure" which is executed each time this occurs. (See SetDrawingProc() below). Failing to do that will cause the drawing to be cleared as soon as the window or control is repainted by Windows, unless you are drawing on a memory bitmap.

[integer startx,starty] are the line's starting coordinates (point 0,0 is the top-left one)
[integer endx,endy] are the line's ending coordinates (point 0,0 is the top-left one)


DrawMultiLine(linestodraw)

A particular version of DrawLine() (see above) which draws several (consecutive or not) lines at one time. A single call to DrawMultiLine() to draw several lines is much faster than several consecutive calls to DrawLine(). "linestodraw" is a sequence of 4-element sequences storing the lines to draw. For example:

    DrawMultiLine({{10,10,20,20},{35,30,40,50},{100,20,100,50}})
is equivalent to:
    DrawLine(10,10,20,20)
    DrawLine(35,30,40,50)
    DrawLine(100,20,100,50)
but much faster to execute.

[sequence linestodraw] is a sequence of 4-element sequences storing the lines to draw


DrawPoint(pointx, pointy)

Draws a single pixel over the client area of the window or control indicated by the last call to SetDrawingControl(), or over the memory bitmap indicated by the last call to SetDrawingMB() using the color indicated by the latest call to SetPenColor(). Since any drawing made directly over a window or control's surface is automatically cleared by the operating system when the window or control is repainted, to make the drawings persistent (e.g. always visible at any one time) they must be placed inside a custom "paint procedure" which is executed each time this occurs. (See SetDrawingProc() below). Failing to do that will cause the drawing to be cleared as soon as the window or control is repainted by Windows, unless you are drawing on a memory bitmap.

[integer pointx,pointy] are the pixel's coordinates (pixel 0,0 is the top-left one)


DrawPolygon(points, fillflag)

Draws a polygon (e.g. a closed multi-segment line) linking all the points indicated by the sequence passed as first argument, over the client area of the window or control indicated by the last call to SetDrawingControl(), using the line width indicated by the last call to SetPenSize() and the color indicated by the last call to SetPenColor(). The polygon is also filled with the same color, if the fillflag argument is set to True. Since any drawing made directly over a window or control's surface is automatically cleared by the operating system when the window or control is repainted, to make the drawings persistent (e.g. always visible at any one time) they must be placed inside a custom "paint procedure" which is executed each time this occurs. (See SetDrawingProc() below). Failing to do that will cause the drawing to be cleared as soon as the window or control is repainted by Windows, unless you are drawing on a memory bitmap.

Note that:

1) the points' sequence must be a plain sequence of integers (e.g. can't contain other sequences) and the coordinates of the points must be entered this way: {x1,y1,x2,y2...,xn,yn} where 'x1' is the horizontal coordinate of point 1, 'y1' is the vertical coordinate of the same point and so on;

2) the first and last point are automatically linked by the procedure to "close" the polygon, so there's no need to repeat the coordinates of point 1 at the end of the sequence;

3) the polygon will be completely filled (if so indicated) only if the polygon's sides DO NOT intersecate each other. In the latter case only alternate parts of the whole polygon may be filled;

4) to draw a same polygon and apart the fill-in option, a single call to DrawPolygon() is much faster than several consecutive calls to DrawLine().

For example, the instruction

    DrawPolygon({10,10,50,10,50,90,10,90},True)
draws and fills a rectangle linking the points whose coordinates are (10,10),(50,10),(50,90) and (10,90).

[sequence points] is the plain sequence storing the point's coordinates
[atom fillflag] set to True to draw a filled polygon or False to draw an outlined polygons


DrawString(startx, starty, text)

Draws some text over the client area of the window or control indicated by the last call to SetDrawingControl(), or over the memory bitmap indicated by the last call to SetDrawingMB() using the color indicated by the last call to SetPenColor() and the font indicated by the last call to SetDrawingFont(). Since any drawing made directly over a window or control's surface is automatically cleared by the operating system when the window or control is repainted, to make the drawings persistent (e.g. always visible at any one time) they must be placed inside a custom "paint procedure" which is executed each time this occurs. (See SetDrawingProc() below). Failing to do that will cause the drawing to be cleared as soon as the window or control is repainted by Windows, unless you are drawing on a memory bitmap.

[atom startx,starty] are the text's starting coordinates (point 0,0 is the top-left one)
[sequence text] is the text to draw


sequence FileDlg(flag, defaultfile, filters)

Shows a standard "Open" or "Save As" file dialog (depending on the value of flag) and returns the full pathname of the file selected for opening or saving purposes. The starting folder is the current working directory (so it can be changed, if needed, with a previous call to the Euphoria statement chdir()). Argument defaultfile can hold name and extension (no path) of the file used by default when the file dialog appears. Argument filters holds the extension filter definition for the file dialog. Extension filters are given by couples of file descriptions and extensions separated by vertical lines, using this format:

"File Description 1|*.ex1|File Description 2|*.ex2" and so on; for instance the string:

"JPEG Images|*.JPG;*.JPEG|All Files|*.*"

sets two filter definitions: "JPEG Files" and "All Files"; if the User chooses the first filter from the drop-down list, only files with .JPEG and .JPG extension will be visible, while if he chooses the "All Files" filter, all files will be visible. Note the use of semicolon (";") to separate different extensions belonging to a same filter definition. If argument filter is an empty string (""), the default "All Files|*.*" filter only is used.

As a final note, be aware that, if using the Save flag, the function does NOT automatically append any extension to the returned filepath, regardless of the selected filter. The application freezes (e.g. do not process any Event) until the dialog box is closed.

[atom flag] set to Open or Save to display a standard "Open" or "Save As.." file dialog
[sequence defaultfile] is the default file name
[sequence filters] is the filter string definition


atom GetCount(control)

Returns the total number of items present into the specified List control.

[atom control] is the List control to check


sequence GetEditSel(editcontrol)

Returns a two-element sequence storing the starting and ending position of the current selection of the specified Edit-class control. If no text is actually selected on the control, the two elements will store a same value that is the caret position. Note that for MultiEdit controls, the carriage return+new line escape characters ("\r\n") separating each line ARE counted for the position values.

[atom editcontrol] is the Edit-class control to check


atom GetIndex(control)

Returns the position number of the currently selected item of the specified List control. -1 is returned if no items are currently selected. The first item of a list is the one with position 0 (zero).

[atom control] is the List control to check


sequence GetItem(control)

Returns the currently selected string item of the specified List control. It is the equivalent of the GetText() function used to retrieve text from other control's types.

[atom control] is the List control to check


atom GetListItemHeight(control)

Returns the height, in pixels, of each string item (e.g. line) of a list control. This can be useful when it is needed to know how many lines are visible at a time on a list control (you get the nuber of visible lines by dividing the list's height by the value returned by this function).

[atom control] is the handle of the list control


atom GetPageSize(dimensionflag)

Returns the width or height in pixels of the current printing document's pages, according to the selected printer and its settings.

[atom dimensionflag] set to X_DIM or Y_DIM to retrieve respectively the width or height of the page


atom GetPixelColor(xpos,ypos)

Returns the color of the pixel with the specified coordinates from the current drawing bitmap (or Memory Bitmap) or control, according to the last call to SetDrawingMB() or SetDrawingControl(). Note that it is possible to retrieve the color of a pixel of a control ONLY if it is visible on the screen. In case it was not possible to retrieve the color of the specified pixel, the function's result will be bigger than #FFFFFF.

[atom xpos,ypos] are the coordinates of the pixel to check


atom GetStringSize(string, font, dimensionflag)

Returns the width or height in pixels of the given string of text or caption, printed on the selected printer using the given font, much the same as GetStringSize(). Set "dimensionflag" to X_DIM or Y_DIM to retrieve respectively the widh or height of the string.

[sequence string] is the string or caption to "measure"
[atom font] is the handle of the font to use to retrieve the needed value
[atom dimensionflag] set to X_DIM or Y_DIM to retrieve respectively the width or height of the string


sequence GetSelec(control)

Returns a sequence of sequences containing the currently selected string items of the specified SelecList or SortedSelecList control (only). It is the equivalent of the GetItem() function used to retrieve the selected string item from the other single-selection List control's types.

[atom control] is the List control to check


atom GetStringSize(control,string, font, dimensionflag)

Returns the width or height in pixels of the given string of text or caption, drawn on the specified control using the given font. Set "dimensionflag" to X_DIM or Y_DIM to retrieve respectively the widh or height of the string. This function can be quite useful to resize a certain control according to the dimension of its caption (which in turn can vary depending on the font used to draw it) or just to check if a given string "fits" on it (for instance you can check if the width of a List's item exceeds the width of the control itself, to test if it is fully visible or not), or to precisely draw a string of text using the DrawString() procedure. For example, it is possible to horizontally center the string "Hello World!!" drawn with the default font over a Picture control which is 200 pixels wide with this instruction

    DrawString((floor(200-GetStringSize(Picture01,"Hello World!!",FN_DEFAULT,X_DIM))/2),10,"Hello World!!")
[atom control] is the handle of the control
[sequence string] is the string or caption to "measure"
[atom font] is the handle of the font to use to retrieve the needed value
[atom dimensionflag] set to X_DIM or Y_DIM to retrieve respectively the width or height of the string


sequence GetText(control)

Returns the caption or text of a control. To retrieve text from List controls, use the GetItem() function (see above).

[atom control] is the handle of the control


sequence GetTrappedMessage()

This low-level function is reserved to Programmers who already have a good knowledge of Windows low-level programming and can be safely ignored by casual Users of the library. It resets the UserTrap variable to False and returns a 4-element sequence containing the data (hwnd,message,wParam,lParam) stored and associated with the latest "trapped" Windows message (see the TrapMessage() procedure below) so that the message itself can be handled appropriately into the application's EventLoop() procedure and processed as needed as if it was one of the default EuWinGUI Events.


InfoMsg(message, caption)

Shows a standard information Dialog with custom message, caption and the information icon. Note: the application freezes (e.g. do not process any Event) until the message box is closed.

[sequence message] is the message to show
[sequence caption] is the Dialog's window caption


atom IsChecked(control)

Returns True if the specified checkbox or radio button is checked, or if the specified pushbutton is pushed.

[atom control] is the handle of the checkbox, radio or pushbutton control to verify


atom IsEventWaiting()

Returns True if there is any event waiting to be handled, or False otherwise. It can be used in conjunction with ProcessEvent() to allow a EuWinGUI application to perform other tasks while waiting for more Events to occurr. See Performing lengthy background operations for more information on the subject.


atom IsKeyPressed(key)

Returns True if the specified keyboard's key is actually pressed, or False otherwise. For instance IsKeyPressed('A') will return True if the keyboard's key 'A' is pressed at the time the function is called.

[atom key] identifies the keyboard's key to check (e.g. 'A' or 'B' ... or '9' and so on)


ListAdd(control, item)

Adds the specified string item to a List control. If the List control is actually a SortedList, the new item will be placed in alphabetical order among the existing items, otherwise it will be added at the end of the item's list.

[atom control] is the List control to which the string item must be added
[sequence item] is a string to add to the List item's list


ListClear(control)

Clears all of a list control's items.

[atom control] is the List control to clear


ListDel(control)

Deletes the currently selected item only from a List control.

[atom control] is the List control whose item must be deleted


ListIns(control, item)

Inserts the specified string item into a List control to the currently selected list position. Using this function with SortedList controls could cause to lose the sorting order.

[atom control] is the List control to which the string item must be added
[sequence item] is a string to add to the List item's list


ListPut(control, item)

Replaces the currently selected list item with the new string specified. Basically, this procedure deletes the currently selected list item and insert the new one into the same position. To avoid undesired list's flickerings caused by the deletion and re-insertion of the item, use the SetRepaintOn() procedure before and after this function. Using this function with SortedList controls could cause the lost of the sorting order.

[atom control] is the List control whose item must be replaced
[sequence item] is the new string item


ListSeek(control, position)

Sets the currently selected item of a List control to the specified position. If position is -1, no items will be selected, while if position exceeds the number of items present into the list, the last item will be selected. The first item of a list is the one with position 0 (zero).

[atom control] is the List control to set
[atom position] is the position number of the item to select


atom LoadCur(cursorpath)

Loads a cursor file from disk and returns its handle. Once a cursor is loaded its handle can be used to change the mouse pointer's shape using the SetCur() procedure (see below).

[sequence cursorpath] is the pathname of the cursor file to load


atom LoadPic(imagepath)

Loads a BMP image from disk, returns its handle and stores the same handle into the PictureHandle global atom too. Only standard BMP images can be loaded, but it is not necessary that the file has the .BMP extension. That means that you can rename your BMPs file with new extensions to hide them from the User of your application, but you can still load them with this procedure. Note that each time this function is called, an amount of RAM equal to the size of the just loaded image is used (even if loading the same image multiple times) and won't be available to other applications until the program terminates or until you use the DeleteImage() procedure (see above) to delete the loaded images and free up the used memory. Note that whatever the color resolution of the loaded bitmap is, once the bitmap is loaded it is converted to the color depth actually used by Windows.

[sequence imagepath] is the full pathname of the .BMP file to load


atom Message(hwnd,msg,wParam,lParam,delayflag)

This low-level function is reserved to Programmers who already have a good knowledge of Windows low-level programming and can be safely ignored by casual Users of the library. It serves to send (if delayflag is False) or post (if delayflag is True) a Windows message to an existing control or window.

[atom hwnd,msg,wParam,lParam] the data to send or post to the application's message queue
[atom delayflag] set to True to post the message or False to send it immediately


NewDocument(documentname)

Starts a new empty printing document, made up by a single blank page. The documentname string is used to identify the document once it has been sent to the printer. NOTE: once a printing document has been created with this procedure, it is not possible to create a new one before the current has been closed and sent to the printer using the StartPrinting() rpocedure.

[sequence documentname] is a name identifying the new printing document


atom NewFont(fontname, fontsize, bold, italic, underlined)

Creates and loads a new font type for use on EuWinGUI controls and drawing procedures, according to the given argument values and returning its handle. The SetFont() and SetDrawingFont() procedures can use the returned handle to set the newly created font on any control or to set it for use with the following calls to the DrawString() drawing procedure. "fontname" is the name of the font to use, fontsize is the dimension of the new font to create and bold, italic and underlined are self-descriptive style flags to set to True whenever the new font must be created with any of those styles "on".

Notes: the Operating System will create a font in any case, but IF the specified font, size, or styles are not ALL available at the same time on the system where the application is run, the font type will be created just according to the closest font, size, and styles available. For this reason, it is perfectly possible that a font is created using even a different fontname from the one you specified if, for instance, the fontname you specified is present into the system where your application is run but the size or style attributes you need are not available. Be sure that the font and attributes you want to use are available on the systems where your application is run! Note also that Windows could prevent to set some font types (generally the most "elaborated" ones) on certain control types if they were succesfully created.

Example:

    times1 = NewFont("Times New Roman", 16, True,False,False)
    SetFont(Button01,times1)
will create a new bold font type using "Times New Roman" as base font type and 16 point size and then will use it on "Button01" control. The font will be created exactly with the specified charachteristics, only if it is present on the system where the program is run.

[sequence fontname] is the name of the font to use
[integer fontsize] is the size of the font to create
[atom bold,italic,underlined] flags to set to True or False according to the style needed for the new font


atom NewMB(width, heigth)

Creates a new Memory Bitmap with the specified dimensions, filled with the color specified by the last call to the SetPenColor() procedure, and returns its handle. A Memory Bitmap can be used exactly as a bitmap loaded from a file. It can be loaded onto a Picture-class control using the SetPic() procedure. See the "What about graphics?" chapter of this guide for more informations on the subject.

[atom width, heigth] set the width and heigth of the new Memory Bitmap


NewPage()

Closes the current document's page and adds a new blank page to it. The new page becomes the current one and the closed one cannot be accessed anymore. All the following printing instructions will draw on the newly created page.


PlaySnd(wavfile)

Plays a wave (.WAV) sound. To stop a playing wave sound, use StopSnd() (see below). By starting play a new sound while another is still in execution will cause the old one to stop and be replaced by the newer one. Note that Windows allows playing wave sound only if they can fit into the system's physical memory, so it is not recommended to play extremely large files. Note also that if the wave file passed as argument doesn't exist, the default Windows "error" sound is played.

[sequence wavfile] is the complete pathname of the wave (.WAV) file to play


PrintMB(sourcebitmap, xpos, ypos, mbwidth, mbheight )

Prints part of, or the entire specified Memory Bitmap (depending on the values of mbwidth and mbheight) to the current page of a printing document at the position specified by xpos and ypos. Note that older printers and most plotters DO NOT support printing of bitmaps.

[atom sourcebitmap] the handlesof the bitmap to print
[atom xpos,ypos] the coordinates on the document's page of the top-left corner of the bitmap which will be copied
[atom mbwidth, mbheight] the width and height in pixels of the bitmap to print


PrintString(startx, starty, text)

Prints some text on the current page of a printing document using the color indicated by the last call to SetPrinterPenColor() and the font indicated by the last call to SetPrinterFont().

[atom startx,starty] are the text's starting coordinates (point 0,0 is the top-left one)
[sequence text] is the text to draw


ProcessEvent()

This procedure works almost like WaitEvent() (see below) with the difference that it returns immediately after having processed all the waiting events. By using this function, a EuWinGUI application can perform other tasks while waiting for more Events to occurr, at the cost of a much increased CPU usage. See the "Performing lengthy background operations" chapter on this guide for more information on the subject.


RunApp(program, parameters)

Starts or open the given program, file or directory, using the given parameters, if any. Not-executable files can be run directly, but only if their extension is already associated with an executable application. Note that this procedure DOES NOT change the working directory to the one of the started application; should it be necessary to change working directory, just use the Euphoria function chdir() before calling this procedure.

[sequence program] is the complete pathname of the program or file to run
[sequence parameters] are the parameters to use when running the specified program


integer ScreenHeight()

Returns the current DeskTop (screen) height, in pixels. This function is very useful to center the main window on the screen. If hei is the window's height, to center it vertically on the screen, set the y position of the window to "floor((ScreenHeight()-hei)/2)"


integer ScreenWidth()

Returns the current DeskTop (screen) width, in pixels. This function is very useful to center the main window on the screen. If wid is the window's width, to center it horizontally on the screen, set the x position of the window to "floor((ScreenWidth()-wid)/2)"


SelectPrinter(flag)

Selects a printer for printing. If the value of "flag" is True the default system's printer and its default settings are used without a Print Dialog is shown, otherwise a Print Dialog is shown allowing the manual selection of any installed printers and their settings. Note that the other printing instructions will not work until this procedure has been called to select the default or any other printer to use.

[atom flag] set to True or False to use or not the default printer


SetCheck(control, flag)

Checks or unchecks a checkbox, radio or pushbutton.

[atom control] is the handle of the checkbox, radio or pushbutton control
[atom flag] set to True or False to check or uncheck (push/unpush) the control


SetColor(control, flag)

Changes the text and background colors of the specified List-class, Text-class, Edit-class or Group control. You can specify the pseudo color CL_DEFAULT as either text or background colors to instructs the library to use the default system color for the text or background of that control. As regards the Group controls, note that it is only possible to change the text and background color of the label which is used as control's label, not the full background color of the control.

[atom control] is the handle of the control whose colors will be changed
[atom textcolor,backcolor] are the new text and background colors of the control


SetCur(cursorshape)

Sets temporarily the cursor's shape to one of five available standard window types (see Appendix D for a list of available default shapes) or to one loaded from disk using the LoadCur() function (see above), "temporarily" meaning that Windows automatically restores the original cursor's shape each time the mouse is moved. For this reason, this procedure is normally used when handling the mouse Events (e.g. Move,Click,Release,RClick,RRelease) of a control to change the shape of the pointer each time it lies, it is clicked or moved over it. For instance, it is possible to change the shape of the cursor to an hourglass to advise the program's User of a lengthy operation in progress by using SetCur(CR_WAIT) inside the handling procedure of the Move Event of all the program's controls and windows.

[atom cursorshape] is one of the default cursor shapes or the handle of a cursor loaded from disk


SetDim(control, newwidth, newheight)

Resizes the main window or a control to the given dimensions.

[atom control] is the handle of the control to move
[atom newwidth] is the new width of the control
[atom newheight] is the new height of the control


SetDrawingControl(control)

Set the indicated window or control as the one over which all the following drawing instructions will draw, until a new call to this procedure or to SetDrawingMB() will change it again. Initially, the default "drawing control" is the application's Main Window.

[atom control] is the handle of the control over which all the following drawing instructions will draw


SetDrawingMB(bitmap)

Set the indicated bitmap or Memory Bitmap as the one over which all the following drawing instructions will draw, until a new call to this procedure or to SetDrawingControl() will change it again.

[atom bitmap] is the handle of a Memory Bitmap or of a bitmap loaded from file over which all the following drawing instructions will draw


SetDrawingProc(control, procedureID)

This procedure has been introduced from later versions of the original WinGUI for C++ library to allow using the provided simple drawing functions or in conjunction with EuWinGUI additional 3rd party graphic libraries which use GDI functions to draw over the windows' surface. Since all the GDI drawings made by the User are removed by the OS each time a window is repainted, they need to be redrawn automatically each time this happens to make them visible again and keep them visible at any given time. By placing all the needed drawing functions inside a custom "paint procedure" with no arguments, and by passing the ID of that procedure (returned by a call to the Euphoria function "routine_id()") to SetDrawingProc(), EuWinGUI will take care of calling automatically that procedure each time a window or dialog is repainted by Windows, recreating the needed drawings. From within the custom procedure it is also possible to check the value of the global variable EventOwner to know the handle of the window which was repainted by the OS.

For example, the code:

    procedure paintproc()
        SetDrawingControl(Picture03)
        SetPenColor(CL_WHITE)
        DrawMultiLine({{10,10,50,50},{50,50,50,90},{50,90,10,90},{10,90,10,10}})
    end procedure

    SetDrawingProc(Picture03, routine_id("paintproc"))
creates and sets a procedure with no arguments named "paintproc" containing the instructions needed to draw a white outlined square over a Picture control's surface which will be executed automatically by EuWinGUI each time the control is repainted, making it persistent at any one time.

Note: it is extremely important to put inside the custom paint procedure ONLY calls to drawing procedures. Putting inside it instructions or code which could cause a window or control to be repainted will cause the application to enter in an infinite loop. For instance, if you show a message box from within the paint procedure, the message is shown a first time but when you close it Windows repaints automatically your application calling again your custom paint procedure which, in turn, shows again the message box which, once closed, force the paint procedure to be called again and again....
For the reason above, some of the EuWinGUI functions which always cause the application to be repainted are disabled and have no effects if accessed from within a custom paint procedure.

[atom control] is the handle of the control to which the painting procedure must be set
[integer procedureID] is the value returned by a call to the Euphoria function "routine_id()" using as argument the identifier of a custom procedure (with no arguments) containing all the needed drawing functions which must be executed by EuWinGUI each time a window or control is repainted by the Operating System.


SetEditSel(editcontrol, startpos, endpos)

Selects some text into an Edit-class control, according to the specified starting and ending positions. If the specified starting and ending selection values are the same no text is actually selected, however the caret is always moved to the specified ending position. The value -1 can also be used for the ending position to select all the text from the starting position to the end of the text stored into the control. Note that for MultiEdit controls, the carriage return+new line escape characters ("\r\n") separating each line DO count for the position values.

[atom editcontrol] is the Edit-class control to set
[atom startpos, endpos] are the starting and ending position of the text to select


SetEnable(control, flag)

Enables or disables the specified control, depending on the value of flag. Disabled controls cannot respond to events.

[atom control] is the handle of the control to enable or disable
[atom flag] set to True to re/enable a control, or False to disable it


SetDrawingFont(font)

This procedure allows to set the font type which will be used with all the following calls to the DrawString() procedure. The font type can be either one created with the NewFont() function or one of the default types (see Appendix D for a list of available default fonts).

[atom font] is the handle of the font to use


SetFixedFont(control)

This procedure is equivalent to the code SetFont(control, FN_FIXED). By default, EuWinGUI controls use the standard variable-width system Windows font. This procedure allows to replace the default variable-width font of the specified control's with the standard fixed-spacing Windows font and it is especially useful for Edit and List controls as it allows to display "formatted" text.

[atom control] is the handle of the control whose font must be set


SetFont(control, font)

This procedure allows to replace the default variable-width font of the specified control's with another, either created with the NewFont() function or one of the default ones (see Appendix D for a list of available default fonts).

[atom control] is the handle of the control whose font must be changed
[atom font] is the handle of the font to use


SetIcon(iconpath)

Sets the icon of the Main Window or of the last window used with a call to the SetParentWindow() procedure to the one specified. By default, the Main Window's or a Dialog's icon is the one bound with the compiled script, or the Euphoria one if the program was not bound.

[sequence iconpath] is the full pathname of the .ICO file to load


SetListCWidth(smlistcontrol, width)

Sets the width, in pixels, of all the columns of a SimMultiList control. It has no effects with the other list controls. Width must be comprised between 1 and 65535 pixels. Any value exceeding those limits will be rounded up or down as necessary by the library.

[atom smlistcontrol] is handle of the SimMultiList control to set
[atom width] is the desired width, in pixels, of all the columns of the control


SetParentWindow(parentwindow)

Sets the Main Window or an existing Dialog control as parent of all the controls created after this procedure has been used and until a new call to the same procedure changes again the "parent" window of all the newly created controls. It allows to populate the Dialog controls with other controls types as it is normally done with the Main Window. Note that Dialogs controls are always created as children of the Main Window, regardless of the window passed as argument of this function.

[atom parentwindow] is the handle of the Main Window (WinHwnd) or of a Dialog which will be used as parent of all the controls created following the call of this procedure


SetPic(control, controltype, imagehandle)

Sets a BMP image already loaded from a file or a Memory Bitmap created with NewMB() into a Picture, ClickPicture, PictureButton or PicturePushButton control. This procedure is especially useful when loading a BMP from file if your application use multiple times a same bitmap because, differently from the SetPicture() procedure below, it doesn't use addictional memory each time it is called as the third argument of the procedure is not a file path but the handle of a previously loaded bitmap image. The handle of a bitmap image is stored inside the PictureHandle global atom after the SetPicture() procedure has been used a first time to load it, or it is returned by a call to LoadPic() (see above). So, if you need to load a same bitmap inside multiple Picture controls, you can save a lot of memory by calling the LoadPic() function to load the bitmap from disk only once and then using SetPic() to set the same image into the other controls, using the handle returned by the function as third argument of the SetPic() procedure.

Example. Say you have four Picture controls and you need to load the same 100Kb image inside them, the code

    SetPicture(pic1,Picture,"image.bmp")
    SetPicture(pic2,Picture,"image.bmp")
    SetPicture(pic3,Picture,"image.bmp")
    SetPicture(pic4,Picture,"image.bmp")
and the code
    imghandle = LoadPic("image.bmp")
    SetPic(pic1,Picture,imghandle)
    SetPic(pic2,Picture,imghandle)
    SetPic(pic3,Picture,imghandle)
    SetPic(pic4,Picture,imghandle)
work the same, but by using the first method you will need 400Kb of RAM, while the second method only uses 100Kb because the image is loaded in memory only once.

[atom control] is the handle of the Picture, ClickPicture, PictureButton or PicturePushButton control
[atom controltype] is the type (Picture, ClickPicture, PictureButton or PicturePushButton) of the control
[atom imagehandle] is the handle of an already loaded bitmap image to use


SetPicture(control, controltype, imagepath)

A call to this procedure is absolutely equivalent to the code SetPic(control, controltype, LoadPic(imagepath)).
It loads and sets at a same time a BMP image into a Picture, ClickPicture, PictureButton or PicturePushButton control, and stores the handle of the loaded image into the PictureHandle global atom. Only standard BMP images are allowed, but it is not necessary that the file has the .BMP extension. That means that you can rename your BMPs file with new extensions to hide them from the User of your application, but you can still load them with this procedure. Note that each time this procedure is called, an amount of RAM equal to the size of the just loaded image is used (even if loading the same image multiple times) and won't be available to other applications until the program terminates. To avoid running out of memory when you need to use a same large bitmap multiple times on a same or different controls, use LoadPic() once to retrieve the handle of the image you need and use SetPic() instead to set it on every control or each time it is needed.

[atom control] is the handle of the Picture, ClickPicture, PictureButton or PicturePushButton control
[atom controltype] is the type (Picture, ClickPicture, PictureButton or PicturePushButton) of the control
[sequence imagepath] is the full pathname of the .BMP file to load


SetPenColor(color)

Sets the color which will be used by EuWinGUI with all the following drawing procedures until a new call to this procedure will change it. The default color is black, but it is possible to draw using any color. The basic 16 Windows colors are predefined by EuWinGUI and can be used as argument of this procedure (see Appendix D for the complete list of EuWinGUI predefined colors and their hexadecimal values), however, in case a specific color is needed, it is possible to pass it as a hexadecimal RGB value according to the format #bbggrr (where bb, gg, rr are values ranging from #00 to #FF (decimal 0 to 255) and defining the quantity and proportion of blue, green and red which will form the desired color). Note however that depending on the system's settings where your application is run (for example if you are using a screen color depth of 65536 colors, e.g. 16 bit), it is very possible that a given color is not available; in that case, the closest color among the available ones will be automatically used by the operating system. Note that it is possible to check which color was actually used by drawing a point or a line on a bitmap and retrieveing its true color using the GetPixelColor() function.

For example SetPenColor(CL_RED) will set the color of all the following drawings to the standard Windows red color, while SetPenColor(#E0E0E0) will set the pen color to a custom light gray.

[atom color] is the hexadecimal value defining the color which will be used by all the following drawing procedures


SetPenSize(width)

Sets the width, in pixels, of the lines that will be drawn by DrawLine(), DrawMultiLine() and DrawPolygon() procedures, until a new call to this procedure will change it. Width must be comprised between 1 and 50; the default value is 1.

[atom width] is the desired width of the lines drawn by the line-drawing procedures


SetPos(control, newxpos, newypos)

Moves a control to a new position over the Main Window's client area or the Main Windows to another screen's position.

[atom control] is the handle of the control to move
[atom newxpos] is the new x position of the control
[atom newypos] is the new y position of the control


SetPrinterPenColor(color)

Sets the color which will be used to print any text to the current page of a printing document. Much the same as SetPenColor() you can specify a custom color in #bbggrr format or use one of the default system's color. Of course, the final color used to print the text will much depend on the color capabilities of the selected printer.

[atom color] is the hexadecimal value defining the color which will be used by all the following drawing procedures


SetPrinterFont(font)

This procedure allows to set the font used to print on the current page of a printing document.

[atom font] is the handle of the font to use


SetRefresh(control)

Forces Windows to refresh (repaint) the specified control or window. Since this procedure forces the Operating System to repaint the specified control, it is intentionally ignored by EuWinGUI if used from within the custom drawing procedure passed as argument of SetDrawingProc() (executed every time a window is repainted), to avoid entering in a loop with no exit.

[atom control] is the control to refresh


SetRepaintOn(control, flag)

Every control is automatically repainted by Windows each time this is needed, for instance when changing a control's caption. Sometimes it can be useful to prevent Windows to repaint automatically a control, for example when adding string items to a list control since, each time an item is added, the list control is repainted by Windows and this causes some noisy "flickerings", especially if multiple items are added at a time. By preventing the control to be repainted before adding the items and re-allowing it to be repainted after having added them, the flickerings are avoided.

[atom control] is the target control
[atom flag] set to True to allow automatic repainting of the control or False to prevent it


SetText(control, newcaption)

Sets the text or caption of a control. To set the text of List controls, use the ListAdd() and ListIns() functions (see above). To span the text of a MultiEdit control through multiple lines, use a "\r\n" escape sequence between two lines. (i.e. SetText(medit1,"Line1\r\nLine2")).

[atom control] is the handle of the control
[sequence newcaption] is the new caption of the control


SetVisible(control, flag)

Makes the specified control visible or invisible, depending on the value of flag. Hidden controls cannot respond to events.

[atom control] is the handle of the control to show or hide
[atom flag] set to True to show a control, or False to hide it


SetWinTimer(interval)

Sets the main window timer. Once an interval is set, a Time event is generated for the main window every "interval" milliseconds. To stop the timer, set the value of interval to 0.

[integer interval] is the interval in milliseconds befor a new Time event is issued


StartPrinting()

Closes the printing document and send it to the selected printer for printing. Once this procedure is used no changes to the current page and document can be made anymore and the only way to stop printing is to manually do it by using the printer's spool dialog.


StopSnd()

Stop any wave sound currently playing.


TrapMessage(msg)

This low-level procedure is reserved to Programmers who already have a good knowledge of Windows low-level programming and can be safely ignored by casual Users of the library. It serves to "trap" specific Windows messages and forces the WaitEvent() procedure to return each time one of these "trapped" messages is processed by the library, exactly as it happens for the default Events. Each time one of the trapped messages is processed, the UserTrap global variable is set to True and the WaitEvent() procedure returns. It is then possible, by checking the value of UserTrap inside the application's EventLoop() procedure, to retrieve all the data associated with the trapped message (e.g. hwnd,message,wParam,lParam) using the GetTrappedMessage() function (see above), and process it as needed as it was one of the default EuWinGUI Events.

Important Notes:

[atom msg] is the Windows message to trap


WaitEvent()

Starts the event handling procedure and wait until the user interacts in some ways with the program's interface. Once one of the supported events is trapped, sets the global variable Event to the Event's Type and the global variable EventOwner to the handle of the Control which received the Event, then returns.


WarnMsg(message, caption)

Shows a standard warning Dialog with custom message, caption and the exclamation icon. Note: the application freezes (e.g. do not process any Event) until the message box is closed.

[sequence message] is the message to show
[sequence caption] is the Dialog's window caption


Window(caption, xpos, ypos, xsize, ysize)

Creates and shows the application's Main Window and assign the Window's handle to the global variable WinHwnd. It is the first WinGUI function to use to create the program's interface. If the Main Window can't be created, WinHwnd is set to zero. The appearance (style) of the Main Window can be choosen, before using this procedure, by setting the values of global variables WindowType and WinOnTop (see above).

[sequence caption] is the Window's title
[atom xpos,ypos] are the Window's screen coordinates
[atom xsize,ysize] are the Window's width and height


Appendix F: Operating System Limits


The limits given to EuWinGUI applications by the Operating System are very elastic and mostly depends on the Windows version, the resources and the available RAM on the system where the applications are run. However, some controls are limited by Windows in their capacities. Specifically:



Appendix G: Demo Applications


Note: To be able of running any of the demos presented into this archive, make sure you have both the EuWinGUI.ew and EWGUties.ew libraries copied into your Euphoria\Include subfolder, and the EuWinGUI.dll and icon copied into your Euphoria\Bin subfolder.

Button.exw
A simple window with a button which shows a message box once left-clicked with the mouse. This demo is fully commented at the beginning of this HTM file.

TwoButtons.exw
A window with two buttons, one showing an about box, the other asking confirmation before closing the program once clicked.

Controls.exw
A window showing all the available EuWinGUI controls. By left-clicking over each one of them, a message box is shown stating which control type has been clicked.
The Picture/Label/Text controls were not added since they look identical to the ClickPicture/ClickLabel/ClickText ones, but they don't respond to any event. The Picture controls are ideal for use as background images for your applications.
Similarly, the SimEdit/SimMultiEdit controls were not added as they look identical to the Edit/MultiEdit ones but the typed text can't scroll horizontally.
Note that the main window is centered on the screen using the ScreenWidth/Height() functions.

Runner.exw
This program shows a list of standard Windows applications which can be run just clicking on their name on the upper List control, and a button which starts other eventual applications or files, once typed on the Edit field immediately below it. An eventual list of parameters can also be typed inside the lower Edit field, for use with any of the started applications. The applications are started using the RunApp() EuWinGUI procedure which can start even not-executable file types, if their extension is already associated with an existing application. For instance if you type "EuWinGUI.txt" into the first edit field and you click on the button, the EuWinGUI instruction file is automatically opened with the Notepad (or with whatsoever program you have associated with .txt files on your system).

SimulatedControls.exw
This demo shows how additional controls, not directly implemented into the EuWinGUI library, can be easily simulated using some of the other available EuWinGUI controls.
- A ProgressBar is simulated using a Picture and a FramedText controls. The Picture control is used to show a little green Memory Bitmap used as central bar, while the ProgressBar's "frame" is given by an empty FramedText control. The progress of an operation is simulated by progressively "stretching" the central bar Picture's dimension, using the SetDim() EuWinGUI procedure each time is needed. The window Timer is used to simulated the progress of a lenghty operation. Of course, a simpler ProgressBar can be simulated with just one Picture control (representing the central bar) if no "frame" is actually needed, and by adding some drawings to the Memory Bitmap it is also possible to create professional-looking progressbars with ease (see the CDChecker.exw program for an advanced example).
- A ComboBox is even more easily simulated using an Edit and a List control (naturally it could be used a SortedList control, if it was needed to simulate a "SortedComboBox"). By clicking on either controls a same message box is shown. Note that the message box suspends the generation of all Events while it is displayed, so the program uses the Ticks global variable to update the simulated ProgressBar once the message box is close.
- A StatusBar is simulated with a single FramedText which looks identical. The initial caption "Simulation in progress..." is replaced by other captions while the simulated ProgressBar grows and until it has reached full extension and the Timer is stopped. Note that the simulated StatusBar has been dimensioned to be used on system using Small Fonts. If your system still uses Large Fonts it will not disply so well.

- A sophisticated ListView is also simulated here. Simpler ListViews can be realized with a lot less code, but I wanted to let you see that it is very possible to create a professional-looking advanced controls just using the right combination of standard controls types only.
The ListView features: The demo's code is fully commented, so it won't be very difficult to understand how things works.
The ListView is made up by a background FramedText which serves as visual containers for all the other controls, three Buttons used as column headers and three SimMultiList controls used as indipendent columns, four more Buttons used to scroll item's data up and down by line or page, an Edit field used to edit the list's items, and two FramedText used as statusbars, placed to the bottom of the windows and used respectively to show the current interval of visible lines over the total, and some short tips to explain what the main commands do when the pointer is moved over them. A paint procedure draws automatically a light-gray grid on all the List controls used.
Note that SimMultiList controls were used instead of normal Lists, because the former control type lacks the 3D border and the automatic vertical scrollbar of the latter one, so it fits better to our present needs.

MouseMove.exw
This demo demonstrates how, by processing the Move events generated by the main window, it is possible to know the position of the mouse pointer over uncovered portions of the window's client area, by checking the value of MouseX and MouseY.
It is important to note that Move events are generated by the main window only if the pointer is lying over a control which can't respond to other events.
To show this, a Picture (on the left) and a ClickPicture (on the right) have been added to the main window. Since the Picture (as well as the Group, Text and Label) controls do not respond to any event, they do not prevent the main window to receive Move events and the text control on the bottom is updated even if the mouse pointer is phisycally moved over their surfaces.
On the contrary, since ClickPictures (as well all the remaining controls) DO respond to events (i.e. mouse left clicks), the control of this type on the left prevent the Main Window to receive Move events (although the ClickPicture itself could respond to it own Move events) so the text control remains unchanged until the mouse pointer is moved again over an uncovered portion of the window's client area.

ClickableGroup.exw
Since Groups and Pictures do not prevent the main window to receive mouse events, it is possible to implement simple routines which, by checking the values of MouseX and MouseY when the mouse events occurred, are able to determine if those events happened "over" the phisycal surface of those controls or not.
The latest version of the Window Designer, for example, implements routines like these to know if a Picture, Group, Label or Text has been clicked by the User.
In this example, a Group control is made able of responding to Click and RClick events.

MiniNotepad.exw
This program demonstrates how it is possible to build a simple replacement of the Windows Notepad, using a MultiEdit control with few lines of executable code.
It is possible to write inside a MultiEdit control as it is normally done in Notepad, and by right clicking on the MultiEdit's surface, a popup menu allows to use the standard cut/copy/paste clipboard functions. When the "New" button is clicked the MultiEdit control is cleared; when the "Save" button is clicked, the entire content of the MultiEdit field is assigned to a sequence using the GetText() function, and the same sequence is then saved using the usual Euphoria statement puts().
The Main Window is made always visible (setting the WinOnTop global variable to True before actually creating it), so that the MiniNotepad can be used to write and save short notes at any time.
A simple starting "splash screen" is also implemented using a Dialog control which is displayed for 5 seconds before being hidden.
A couple of notes on MultiEdit controls:
For example, the instruction
    SetText(multi,"Line1\r\nLine2")
adds the MultiEdit control whose handle/ID is "multi", two consecutive lines (strings, "Line1" and "Line2") of text.

RadioGroups.exw
This demo shows how it is possible to create different working radio groups using the SimRadio controls, instead of the Radio ones.
Both these types of control can respond to Click events and look absolutely identical, but the difference between them is that a Radio is completely controlled by Windows, so each time a Radio control is left-clicked, Windows automatically makes it checked while at the same time unchecks ALL the other radio controls (BOTH Radio AND SimRadio) you have added to your program; a SimRadio control instead is NOT directly controlled by Windows and it is up to the Programmer to process its Click events to make it checked and uncheck the other SimRadio controls of a same group (using the SetCheck() EuWinGUI procedure), every time the control is clicked.
It should be clear that if your application needs just a single radio group the Radio controls are the best choice since you don't have to check/uncheck them all at run-time, but if you need more than a radio group, you have to use SimRadios, so that you can check the clicked one and uncheck individually all the other belonging to the same group only, so that the SimRadios belonging to the other groups remain unaffected.
By examining the RadioGroup.exw code, you will note that the click events for the Radio controls belonging to the first two groups are not even processed because Windows automatically checks the control clicked and unchecks ALL the others (even SimRadio ones). By using SimRadios, instead you can decide at run time which control to check (i.e. the one clicked) and which one to uncheck (i.e. all the other belonging to the same radio group ONLY), so if you click on any radio control on the right you'll see that only the radio belonging to a same group are unchecked when one of them is clicked.
Similarly, SimCheck controls are not automatically checked/unchecked by Windows once clicked (like the Check controls), but it is up to you to make them checked/unchecked at run-time using the SetCheck() procedure.

EuroConverter.exw
A simple converter of values from/to EUROs. Set the value to convert in the upper edit field, set the conversion type by clicking one of the radio boxes, click the button corresponding to the needed currency and you will see the converted value inside the lower edit field. Note that the lower edit field, used only as "display" of the Converter has been disabled to prevent the User from typing inside it.
Tabbing.exw
This demo demonstrates how to implement a simple routine which allows to use the HotKey Main Window's Event to switch between the added controls using the TAB keyboard's key. It also shows how it is possible to maintain the keyboard input to a given control even after the Main Window is restored from the Taskbar.
If you click the TAB key, you will see that the keyboard input recursively moves from a control to another, and if you minimize the Main Window the controls which last had the keyboard input still retains it once the window is restored.
Basically, to implement a routine which allows to switch among the added controls using the keyboard's TAB key, you have to:
  1. create a sequence containing the handles of all the controls you want to tab;
  2. use an atom as "current index" of this list of "tabbed" controls;
  3. process the HotKey Event to increment the index each time the Tab key is pressed and activate the corresponding control using the Activate() procedure, remembering also to update the value of the index each time one of the tabbed controls becomes active as a result of other User's actions (i.e. Clicks);
  4. finally, by processing the Restore Main Window's Event it is also possible to reactivate the last tabbed control after the Main Window is restored from the Windows Taskbar.

SimShortcuts.exw
This demo shows how to use the Key Main Window's Event to simulate the use of keyboard's shortcut to activate/start any of the added control.
The window shows three different buttons. You can either click on any buttons or use one of the suggested shortcut keys (i.e. SHIFT+'b', 'u', '3') and you will get the same result (i.e. a message is shown).
Note that shortcuts made by combinations of keyboard's charachters with CTRL, ALT or other special control keys are not supported.

Joke!.exw
This simple demo shows with a simple "joke" that the use of Labels (and Texts) instead of ClickLabels (and ClickTexts) doesn't prevent the Main Window to generate/recognize Move Events.
Note: this program will NOT harm in any way your system!

FormattedText.exw
This demo shows how it is possible to create a formatted list (i.e. a list which displays its text in ordered columns) with ease using the SetFixedFont() procedure for both a SortedList and a Label control (which is used, in this demo, as list's header). Outcomment the SetFixedFont() instructions to see the difference if the same controls would use the standard font instead...

TwoWindows.exw
This very simple demo shows how to create an application with two windows and different buttons on them. The Main Window is initially visible while a second window (a Dialog control) is hidden. By clicking on the "Show Dialog" button of the Main Window the second window is shown.
Since the generation of Close Events has been enabled, the Close Event generated by the default close button ("X") of the second window is used to hide the window again, while the one generated by the Main Window is used to close the application.
Note that the second window always cover the Main one when both overlap since Dialogs are (always) created as children of the Main Window. If you need to create an application having different windows which are never covered by others when active, see the FAQ section of the EuWinGUI documentation for a very simple technique which allows to do that with just three additional lines of code.

ManyPics.exw
This demo actually does nothing useful but its code shows how to use the SetPic() procedure to load a same image multiple times on different controls using only one instance of a same image (and so saving a lot of memory).
The program sets countinously, with an interval of two seconds, two different images into 12 different Picture controls. It uses SetPicture() only to load a first time both the image used and to store their handles, then it uses SetPic() to set them to the controls without reloading them in memory each time.
In a case like this, if you wouldn't use the SetPic() procedure, you'd run out of memory after some time, unless you'd free up each time the memory used by the images using the DeleteImage() procedure, but in this latter case the whole code would run much slower because each time the image would be loaded from a file on the hard-disk rather than being directly accessed in memory.

DirDlg.exw
This demo shows how to create a very simple "Directory Dialog" which allows to navigate through the system's folders, open them with a double-click and select the one needed. Using the same technique it is possible to create customized dialogs for almost any purpose.

Cursors.exw
This demo shows the default cursor shapes for EuWinGUI applications (more can be loaded from disk using the LoadCur() function). Just move the mouse pointer over each label to watch the relative cursor (between parenthesis is noted the EuWinGUI cursor type).
Note how, to maintain the cursor to a given shape while moving the pointer over a control, the SetCur() procedure must be used while handling the Move event of that control. Since the cursor is a shared resource, Windows automatically replaces the control's "default" cursor (which can vary depending on the control or window over which the pointer lies) each time a mouse event of any type occurs occurs. So, to change and maintain a given cursor shape, it is necessary to use the SetCur() procedure when handling any mouse event of the appropriate control or window.

Graphics.exw
EuWinGUI has a basic set of drawing functions which allows you to draw graphics of any complexity, and this demo shows you how.
The program draws some random graphics over a Memory Bitmap which is then set to a Picture control.

SoundPlayer.exw
This demo shows how to use the PlaySnd() and StopSnd() EuWinGUI procedures to start and stop playing a .WAV sound file. Use the "Play Sound" button (or double click one of the listed sounds) and "Stop Playing" button to start/stop playing the selected wave file and use the "Browse Sound" button to locate and select more files onto your system. Once a file is browsed, all the other wave sounds actually present into the same folder will be listed on the Player's list controls.

TrapMessage.exw
This little program shows how to use the "advanced" functions TrapMessage() and GetTrappedMessage() to process custom Windows messages with EuWinGUI applications. These functions, together with Message(), are reserved to programmers who already know how Windows works, and serve mainly to give the ability of processing additional "custom" events to EuWinGUI applications.
This demo traps the WM_NCMOUSEMOVE window messages sent to a Window when the pointer is moved over its non-client areas to replace the pointer's shape.
Using these functions, Colin Taylor has developed a nice add-on library (search for "ew-menu1.zip" into the RDS archive) which allows adding menus to EuWinGUI applications.

AboutBox.exw
This demo shows you how to implement a simple yet colorful "About" dialog, taking advantage of the EuWinGUI routines which allows to load and use custom font types with your applications.
The GetTextSize() function is also widely used to retrieve width and height of the strings drawn. By getting these dimensions it is possible to center horizontally and/or vertically a given string drawn over a control, and it is also possible to resize the controls over which the strings are drawn according to the string dimensions, so that the string itself is always completely visible whatever is the font used to draw it.
In this demo note how the blue background of the Main Window has been drawn only to cover the top portion of the window, the bottom part having been covered by a distinct Picture control. This was done to avoid flickerings to the ClickPicture control used as e-mail address.

TextSelection.exw
EuWinGUI allows to set and retrieve the current text selection of an Edit-class control using the procedure SetEditSel() and the function GetEditSel().
This demo uses the latter function to retrieve and show the starting and ending characther position of the current selection inside a MultiEdit control.
Left-click and drag a portion of text into the control to get the starting and ending position of the selection.
Note that in a MultiLine control the carriage return+new line escape sequences used to wrap each line, although not actually "visible", ARE counted when computing the starting and ending position of the selected text.

Bricks.exw
This is a simple clone of the classic arcade game of Atari era, created using the latest graphic functions added to EuWinGUI. The scope of the game is to destroy all the bricks of each level using the paddle (which can be moved left and right using the keyboard's arrw keys) to make the moving ball bouncing on them.
Each removed brick increments the score by a value of 10 multiplied for the game level. To make things increasingly difficult, the paddle's speed (which initially is twice as fast as the ball) is decremented by a fraction of the original value for each new level started. If the ball exits the lower edge of the gameboard, e.g. past the paddle's position, the game is over. It is possible to quit the game at any time by hitting the "ESC" key, while the Spacebar is used to start playing.
The .WAV sounds the game uses are intentionally left to a very minimum to avoid making the archive's size too big, however additional effects and even music could have been added without problems. The game was also intentionally implemented to use only a little window on the screen, to let you see that it is a real window application and also to let it plays fine even on slower/older systems.
The game takes advantage of all the most recent routines added to the library: IsKeyPressed(), IsEventWaiting(), ProcessEvent(), NewMB(), SetDrawingMB(), CopyMB() and CopyMBToControl(), so it is recommended to carefully examine the commented code to understand how the things exactly work.
Basically, a Memory Bitmap large as the main window is created and it is used as a gameboard over which all the "sprites" are drawn. The sprites themselves are other small memory bitmaps whose graphics were created with a paint program, saved on a bitmap file ("Bricks.bmp") and then copied onto the gamebaord when needed. Once the game is started, the programs enter in a busy drawing loop and the horizontal and vertical position of the moving sprites (the ball and eventually the paddle, if the arrw keys were pressed) are updated continuosly while the game is playing, to give the illusion of motion.
To create an arcade game the essential point is the speed, which allows drawing the graphics many times a second over the screen hence giving the player the illusion of a smooth animation of all the game's sprites. For this reason a game will always perform better on faster systems, and for this reason too it is generally not possible to use the Timer to create high-speed animations, due to its very low resolution.
Said that, the best way to create a EuWinGUI action game is to enter a busy loop which updates continuosly the screen the biggest number of times a second to take advantage of all the system's speed, as Bricks.exw does. But this method unfortunately introduces two new "problems" which must be solved.
The first is that the "busy" loop prevents the application to detect and handle all the Events generated for the application, in case they are needed; the second is that this way the speed of the animations is a direct consequence of the system's speed only, making a game possibly unplayable on system's much faster or much slower of the one where it was designed and tested.
The solution to the first problem is very easy, thanks to the new routines introduces by EuWinGUI, and consists in checking with the IsEventWaiting() function at the end of each drawing loop, if there are Events waiting to be processed and in affirmative case in processing them as usual after a call to the ProcessEvent() procedure which will set the values of the main EuWinGUI variables Event, EventOwner and EventItem. In the specific case of Bricks.exw, the only Event of interest which have been handled is the Move one, to allow hiding the mouse cursor when it is moved over the game's window.
The solution to the second problem is solved by coding a "benchmark" routine which the game must execute before the main game loop is started and which serves to measure the speed of the system where the application is run, compared to a default value measured on the system where the game was developed and tested, which serves as reference to adjust the sprites' speed to the correct values. The most accurate the benchmark routine is, the most accurate the result will be, anyway it is VERY important (and generally enough) that the benchmark routine uses all the drawing functions which the game uses in its drawing loop, since the graphic routines are the ones which mostly affect the game's performances and whose speed of execution highly depend on the power of the system (CPU's speed, video-card's speed, available RAM and so on).
In the specific case of Bricks.exw demo, the benchmark routine is executed at the very beginning of the program's code (invoked by the first call of the Initialize() procedure) and simply consists in counting how many times a memory bitmap of the dimensions of the game's window can be copied to the screen in 1/4th of a second. On my system, this measured average value is equal to 18800. Since the visual speed of the ball is simply given by the number of times its position is updated on the screen multiplied for the increment in its position's values, it is enough to change that increment to a bigger or smaller value to balance the count returned by the benchmark function, which will be most likely bigger or smaller than 18800 depending on the speed of the system where the game is run.

CDChecker.exw
This demo is rather a fully functional EuWinGUI application and I use it regularly for my own needs. It serves to check that the files saved on a CD-ROM are fully readable and exactly identical to the source ones present on the hard-disk. In a few words, the programs checks the integrity of the files that you have copied on a CD for storage or backup purposes, so to be sure that they were copied without errors before you want eventually delete them from the hard-disk.
The program can check single files or entire directories (and their subdirectories), and fills a List control of a secondary window (the "Report Window") with a detailed report of all the files checked/compared, the errors eventually found and the options choosen for the check in progress. If you choose to check entire directories and subdirectories, make sure that the backup files are saved on the destination CD using the same path of the source files, otherwise the program won't be able of finding them.
A nice-looking simulated progressbar is implemented using a Memory Bitmap and is used as a visual clue for the progress of the whole checking operation. The checking loop, which can take several minutes to be completed if many and/or big files need to be checked, can be aborted at will by the User clicking the same button used to start the operation.
To allow CDChecker to abort the checking loop, the program only reads and compare a small chunk of bytes at a time, then calls the new IsEventWaiting() and ProcessEvent() EuWinGUI routines to check if the "Abort" button has been clicked and eventually handles the button's Event as usual or resumes the checking loop.

Printing.exw
This demo show how to use a SelecList control to load a file at run time and print all of part of it with the printing instruction set provided by EuWinGUI. The demo's code is fully commented, and it also uses a utility procedure stored inside the EWGUties.ew library, GetFontLines(), to set a constant number of lines per page whatever printer is selected for printing.


Credits


Many thanks to:

Rob Craig and all at RDS for making available Euphoria, a really great and powerful language, now even Open and Free!

David Cuny for initial development of Win32Lib and to all the current developers of this great library (Derek Parnell in particular, for his kind comments on EuWinGUI). Win32Lib is definitely the best add-on available for Win32 programming in Euphoria. Hope EuWinGUI will get the second place :-))!

Rod Damon for his strong support and for his beta-testing work on the library and demos, Jiri Babor for his kind words about the library and for having given this new look and functionality to the documentation of the package, Colin Taylor & Michael Nelson for their useful suggestions, Ken Orr for his continued support and to all have sent in messages with comments on EuWinGUI or just to say hello or thanks....

.... and to all the Users of EuWinGUI! Comments or criticisms of any type on it will be always appreciated.