| Home page | HwGUI 2.23 reference manual | |
| Alexander S.Kresin, October 2023 | next |
HwGUI is an add-on library for Harbour and xHarbour, intended for creating GUI applications. There are two versions of HwGUI - Win32 version, which is based on direct calls of Win32 API, and GTK version, which uses GTK2 library and can be used under any platform where GTK is implemented ( Linux, Windows, probably MacOS ).
Most of GUI frameworks, not only for Harbour, but for other languages, too, which are based on third-party libraries, use these libraries on all supported operating systems. That is, if any framework is based, say, on the QT, it uses QT for both Windows and Linux. HwGUI key feature is that Windows version uses the native WinAPI - no need to additional mega-ton dlls for every, even the simplest application; it works faster as there are no additional layers between your code and WinAPI. At the same time, for other operating systems, ( Linux - first of all), GTK engine is used. But the Harbour code remains the same.
While developing HwGUI I tried to hide from the end user - Harbour programmer technical details of API calls and to build a set of commands and functions, which could allow easily create and manage GUI objects.
I began to work on HwGUI in August 2001 and the first version was released on August 21. Of course, one of sources of inspiration for me was Fivewin of Antonio Linares - the only at that time GUI library for Harbour.
My initial intention was to create a small and fast GUI lib mainly for my own needs. And already in October I had wrote the first small application with HwGUI for my firm, it reads the databases, created and managed with the accounting system, generates some documents and sends them by fax.
Firstly, from the initial release and til the 1.3 HwGUI didn't use the OOP paradigm - and I even had declared this as one of HwGUI features. My main motivations was speed and stability. Harbour's implementation of classes at that time had some bugs and I didn't want to add problems to myself. And, of course, access to object's variables is more slow than access to the array items. OOP is an additional level and using of it reduces application's performance.
But later I have arrived at a decision to make HwGUI OOP based - to simplify user interface and make it better structured and more convenient. So starting from the release 2.0 HwGUI is based on OOP paradigm.
Since the autumn'2003 HwGUI is hosted by SourceForge, and there is a group of developers working on it. Thanks to all of them for participation and contributions.
Yet another important milestone in HwGUI's timeline is a December,2005 - where a development of GTK version has been started, so HwGUI became a cross-platform tool.
First of all, of course, it is necessary to read this manual - at least the first 3 sections.
Meanwhile, you can skip subsections Inside HwGUI and Using the UNICODE.
For further study, I strongly recommend utility the Tutorial utility, located in hwgui/utils/tutorial/.
This utility contains an ordered set of code samples on HwGUI with comments, all of which can be
executed directly from the utility. Moreover, the code placed in a built-in editor with syntax highliting,
you can edit it and execute immediately, that is, it is the fastest way to check
the work of certain HwGUI constructions, styles, etc.
Compile samples from hwgui/samples/, utilities from hwgui/utils/,
review their code. And, of course, write yourself, write a little more - it is the best way to learn something.
Good luck!
Look into file "install.txt" for extra installation instructions (Prerequisite packages for LINUX, optional cross development environment for GTK on Windows).
HwGUI is distributed as an archive, zip for Windows and tar.gz, tar.bz2 - for Linux. Currently it doesn't use any setup utility, you need simply unpack it to any place you want. The archive package includes following files and directories:
Changelog
*.hbp,*.hbc - build files for Hbmk
make_b32.bat - command files to build HwGUI libraries, using Borland C
makefile.bc
make_vc.bat - command files to build HwGUI libraries, using MSVC
makefile.vc
make_pc.bat - command files to build HwGUI libraries, using Pelles C
makefile.pc
make_w32.bat - command files to build HwGUI libraries, using Open Watcom C
makefile.wc
makemngw.bat - command files to build HwGUI libraries, using Mingw
makefile.gcc
makedll.bat - command files to build HwGUI dll, using Borland C
makedll.bc
license.txt
install.txt - installation notes
whatsnew.txt
contrib\ - a directory with contribution modules, which for
various reasons were not included in the basic sources set
activex\ - sources of HActiveX И HHtml classes - implementation of ActiveX
technology
ext_controls\- few additional controls classes
hwmake\
misc\
qhtm\ - sources of HQhtm class
doc\ - directory with documentation
image\ - directory with sample image files
include\ - directory with HwGUI headers files
lib\ - directory with HwGUI libraries
samples\ - directory with HwGUI samples
gtk_samples\ - directory with samples for GTK version
source\ - Hwgui sources
common\ - common sources for both versions
debug\ - sources of hwgdebug library
editor\ - sources of Hilight и HcEdit classes - an editor with syntax
highliting
procmisc\- set of functions
xml\ - sources of HXMLDoc, HXMLNode classes - reading and writing of
xml files
gtk\ - GTK version sources
winapi\ - WinAPI version sources
utils\ - directory with utilities
bincnt\ - Binary container manages
dbc\ - Data Base Control
debugger\ - GUI debugger for Harbour
designer\ - The Designer, an utility to create screen forms and reports
editor\ - A text editor with extended formatting possibilities
tutorial\ - Interactive HwGUI tutorial.
devtools - Developer tools
In binary distributions, build files and sources are absent.
in the source distribution, the lib/ directory is absent - it will be created during the build process.
For a binary distribution this issue isn't actual, of course. So, we are talking here about the source distribution. Compiling HwGUI is quite simple - as compiling of any Harbour program.
Harbour programmers may use Hbmk2 (previous Hbmk) utility (it is absent in xHarbour). Just run it with hbp files:
hbmk2 hwgui.hbp hbxml.hbp hwgdebug.hbp procmisc.hbp
As a result, ypu will get hwgui, hbxml, hwgdebug and procmisc libraries in your hwgui/lib/ directory.
You may use also one of command files, included in distribution, depending of your C compiler. For xHarbour programmers it is the only way. I prefer it, too, simply because I like to keep control ob the building process.
Before building the libraries you need to set the HB_PATH environment variable, it should point to the directory where your copy of Harbour or xHarbour is. You may set it on your Windows environment or in the appropriate command ( .bat ) file, including there a line:
SET HB_PATH=c:\harbour
Then run one of command files depending of the C compiler you use
( make_b32.bat for Borland C, make_pc.bat for Pelles C, make_vc.bat for MSVC,
make_w32.bat for Open Watcom C, makemngw.bat for Mingw ) - this will build four libraries -
hwgui.lib, procmisc.lib, hwg_qhtm.lib and hbxml.lib. That's all !
The sources of GTK version are located in hwgui/source/gtk/ directory.
In the same place ypu will find a bash script for libraries building - build.sh.
Before to launch it, you need to check the Harbour installation. If it was installed
using binary deb or rpm package, Harbour files most likely are placed in
/usr/local/bin, /usr/local/include/harbour, /usr/local/lib/harbour.
In this case you don't need to do any additional work. But if your Harbour is placed
in separate directory, compiled from sources, you need to set the path to this directory
in HB_ROOT environment variable. You may insert appropriate line in build.sh, for example:
export HB_ROOT=../../..
Now you can run the build.sh and the ready libraries must appear in
hwgui/lib/ directory.
Now let talk about compiling and linking GUI programs with Harbour. HwGUI provides
few header files in include/ and four libraries:
Hwgdebug, hbxml and procmisc may be used without HwGUI, too.
Besides, there are 3 additional library from contrib/, which may be linked, if needed:
To build the GUI program, you need to link necessary libraries and add some options
for the C linker - these options are different for different C systems.
For to not write all these manually, HwGUI distribution includes scripts that solve this task.
For those, who use Hbmk, there is hwgui/hwgui.hbc. Following is a command line
to build some myprog.prg, if your hwgui\ directory is located in c:\harbour\:
hbmk2 c:\harbour\hwgui\hwgui.hbc myprog.prg
For WinAPI version I recommend always add a file samples\hwgui_xp.rc, for Windows themes was used:
hbmk2 c:\harbour\hwgui\hwgui.hbc hwgui_xp.rc myprog.prg
For those, who don't use Hbmk, there are command files in samples\ directory for different C compilers.
You may use them to build sample programs from samples\ or as a templates to build your programs.
For GTK version you may use Hbmk or samples/gtk_samples/build.sh bash script - probably,
you will need to set the HB_ROOT environment variable, as described in a subsection 2.3. How to build HwGUI library (GTK version).
#include "hwgui.ch"
Function Main
Local oMainWnd, oFont
Local aCombo := {"First","Second" }
PREPARE FONT oFont NAME "MS Sans Serif" WIDTH 0 HEIGHT -13
INIT WINDOW oMainWnd TITLE "Example" ;
FONT oFont ;
ON EXIT {||hwg_MsgYesNo("Really want to quit ?")}
@ 20,10 EDITBOX "Hello, World!" SIZE 200,30
@ 270,10 COMBOBOX aCombo SIZE 100, 150 TOOLTIP "Combobox"
@ 120,60 BUTTON "Close" SIZE 150,30 ;
ON CLICK {||oMainWnd:Close()}
MENU OF oMainWnd
MENUITEM "About" ACTION hwg_MsgInfo("First HwGUI Application")
ENDMENU
ACTIVATE WINDOW oMainWnd
hwg_writelog( "Program terminated " + Dtoc(Date()) + " at " + Time() )
Return
First thing you will want to do, I think, is to create the main window. The best way to do this is the command INIT WINDOW. In this command you can define initial position and the size of the window, it's style, icon, background color. You can set also event handlers - codeblocks, which are evaluated for different events ( INIT, EXIT, PAINT, SIZE changing, GETFOCUS, LOSTFOCUS and others ).
Then you need to define controls for that window and the main menu ( MENU ... ENDMENU commands), and, at least, activate the window, ( ACTIVATE WINDOW ) show it on the screen. Let analyse the above sample.
PREPARE FONT oFont NAME "MS Sans Serif" WIDTH 0 HEIGHT -13
At first, we create the font object for the main window. HwGUI works in such a way, that if a font isn't defined for a control, this control uses the font, defined for his parent window.
INIT WINDOW oMainWnd MAIN TITLE "Example" ;
FONT oFont ;
ON EXIT {||hwg_MsgYesNo("Really want to quit ?")}
This command creates main window with the title "Example" and with previously created font. ON EXIT clause will cause appearance of a message box, user will need to choose "Yes" to quit the application.
@ 20,10 EDITBOX "Hello, World!" ;
SIZE 200,30
@ 270,10 COMBOBOX aCombo ;
SIZE 100, 150 TOOLTIP "Combobox"
@ 120,60 BUTTON "Close" ;
SIZE 150,30 ;
ON CLICK {||hwg_EndWindow()}
The above commands creates appropriate controls - Edit, Combobox and Push Button. ComboBox is initialized with aCombo array, which was declared before. Button has an event handler defined - closing the application.
MENU OF oMainWnd
MENUITEM "About" ACTION hwg_MsgInfo("First HwGUI Application")
ENDMENU
These commands creates the main menu, which includes the only item "About".
ACTIVATE WINDOW oMainWnd
And, at least, this last command activates the main window. It appears on
the screen with menu and all controls defined. Pay attention to the important fact: the
main window is modal, i.e., when it appears on the screen the program stops.
This means, that the lines of the code, which are located after ACTIVATE WINDOW oMainWnd,
will be executed only after the window closes. In our sample this is a line, which
writes date and time to a log:
hwg_writelog( "Program terminated " + Dtoc(Date()) + " at " + Time() )
You can see that it is added to the file not immediately after the appearance of the window, but only after it is closed. These explanations may seem trivial for you, but many programmers just starting to write GUI applications, have some difficulties with this behaviour.
From the point of messages handling all HwGUI windows ( and controls, which, in fact, are windows, too ) may be divided in two groups:
1) The windows, which messages are handled by HwGUI.The first group includes main, mdi, child windows and dialogs and such controls as ( I will use the appropriate classes names ) HBrowse, HEdit, HStaticLink, HOwnButton, HPanel, HRichEdit, HSplitter, HTab, HTrackBar.
2) The windows, which messages are handled by Windows API only.
Handling of messages for the first group is implemented in the
following way:
Window ( control ) creation functions stores the pointer to the
appropriate HwGUI object in a window extra memory, granted by Windows
API - by calling the function SetWindowObject().
Besides, the window creation functions sets the pointer to the window
procedure ( an application-defined function that processes messages
sent to a window ). This is implemented by setting the pointer in
WNDCLASS structure ( see, for example, HWG_INITMAINWINDOW(),
HWG_REGBROWSE() ) or by redefinition the window procedure (
HWG_INITEDITPROC(), HWG_INITWINCTRL() ).
Thus, all windows of a first group has special messages processing
procedures ( MainWndProc(), WinCtrlProc(), ... ), while messages for
windows of a second groups are processed by Windows API internally.
The messages processing procedure extracts the pointer to appropriate
HwGUI object from a window extra memory and calls the :onEvent method
for this object.
The :onEvent method may process the message itself, or pass it to the
super method, or, returning -1, pass it to the default Windows API
procedure.
For example, the HStatic and HStatus are a second
group controls, i.e. messages to this control aren't processed by HwGUI -
that's why Windows doesn't process notifications, messages for it
child controls.
So, if you want to create ontop of them other controls, they are two ways:
1) create a new class, derived from HStatic and make it a control of a first group ( store a object pointer and redefine the window procedure )
2) use as a place holder for a button not HStatic or HStatus, but, for example, the HPanel. Hpanel is a general purpose control, which I use and recommend you to use for such purposes.
Resources in GUI applications means:
1.) Icons and imagesMost development tools for GUI programs (like Micosoft Visual C/C++) contain a tool for handling and designing resources.
2.) Forms
3.) Iconification
- Check the generated list of object variables of control elements in the LOCAL declaration section. Add missing variables.
- If a form contains a checkbox definition, the HWGUI designer crashes at storing of prg file.
The workaround is, to store the checkbox as a static text, starting with "X".
Modfiy the command , but the position and size can be copied.
- The designer runs at this time only correct on Windows. We will finish the port to
LINUX as soon as possible.
Iconification
On Windows:
If you will see the program icons in links on the deskop:

or compiled in the exe file:
(properties of the exe file, right mouse click ==> Properties)

you must use the resource compiler
(is delivered with the most compilers for Windows like Borland C and MinGW).
Otherwise a default icon is showed:

(Verknüpfung ==> link)
You need a resource file only with 2 lines (for example):
cllog.rc:
1 24 "./images/WindowsXP.Manifest"
CLLOG ICON resource\cllog.ico
Attention !
A file name and path like "..\image\cllog.ico"
causes a syntax error at resource compiling.
You find the file WindowsXP.Manifest in directory "\image".
The icon was compiled into the exe file, that the operating can find the icon:
hbmk2 %PRGNAME%.prg cllog.rc ...
In your main program, add the icon following this example:
#ifndef __GTK__
oIcon1 := HIcon():AddResource( "CLLOG" )
#else
oIcon1 := HIcon():AddString( "cllog" , cResourceCLICO ) && loaded from hex values
#endif
...
INIT WINDOW oWndMain TITLE "Title" ;
AT nx,ny SIZE nheight,nwidth ;
ICON oIcon1
...
In the INIT WINDOW command the icon was only showed at run time !
On LINUX:
The Icon was displayed at runtime in the tray bar and the header Window:
![]()
Special troubleshooting:
As reported with support ticket #55 some trouble
with program crashes caused by recource configuration
on MingW64 with GGC version >= 11, Windows 10.
We suggest to add extra .rc files and compile scripts for
newer GCC versions.
If the following message appears:

Die Anwendung konnte nicht korrekt gestartet werden.
(0xc000007b).
==> The german text means:
The application could not be startet correctly.
To fix:
- Remove the line from all *.rc
1 24 "../image/WindowsXP.Manifest"
and change concerning the following sample:
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "../image/Windows64.Manifest"
CLLOG ICON resource/cllog.ico
Change in the manifest file the entry
processorArchitecture="x86" to "ia64"
- Load icons from file in the *.rc file, for example:
HWGUI ICON image\hwgui_32x32.ico
All other resources can be loaded from hex hex values or
the binary container.
In this chapter you find some description and tips for multi platform applications,
at this time especially for Windows and GTK/LINUX.
Design rules
The designs of forms differs between Windows and GTK, in most cases
the GUI elements needs more space.
It is recommended to check the design for multi platform applications also on LINUX !
The sample program "samples/hello.prg" demonstrates the design differences.
Full infomation in the inline comments of this sample.
The compiler switch "#ifdef __GTK__" is used to select the commands for correct design.
Here some sceen shots for this example:
Windows:

On LINUX with old design for Windows:

On LINUX with new design:

Some other instructions:
- Height 32 (default value in designer) for buttons is OK for Windows and GTK
- GTK: Main menu items need submenus.
For details look into "hwgdoc_commands.html", chapter "4.2. Menu commands",
item "Additional instructions for menus".
| table of contents | next | |
| commands |