HMG 3.0.46 Released

File Name: HMG.3.0.46.exe
File Size: 38.91 MB
Date: 06. November 2012

Update to latest Harbour Nightly Build (18443 2012-11-05)


– Print Barcode sample. See samples/printean13 folder for details. (Contributed by Marek Olszewski)
– Desktop Make Shortcut for file/dir and URLs in HFCL. See sample at hfcl/samples/makeshortcut folder. (Contributed by B.P Dave and Esgici)
– buildalllib.bat in the base directory to build all the libraries including hmg, hfcl, hmgsqlbridges, crypt, edit, editex, ini, graph, report etc with a single call.
– Included hbvpdf library in HMG library folder. This library is required to compile all the samples in samples/report.advanced folders.

– Update

– Bos Taurus Graphics library 1.01. Author Claudio Soto had modified the source files to make it compatible for HFCL. (Thanks to Claudio Soto)
– Updated BT_BitmapLoadFile() fuction, now load images in the formats: BMP, GIF, JPG, TIF and PNG.
– Added Functions:
– BT_BitmapInvert
– BT_BitmapContrast
– BT_BitmapModifyColor
– BT_BitmapGammaCorrect
– BT_BitmapConvolutionFilter3x3
– Updated BosTaurus-FunctionsReferenceGuide.PDF with changes made.
– Added Demo10
– HMG_HPDF Library in HFCL. Now the image command accepts both jpg and png file formats from either file or resource location. (Contributed by Claudio Soto)

– Fix

– Number of warnings while compiling the HMG library is now reduced to only six. Great thanks to Claudio Soto.
– Hardcoded Path name references in batch files. Now HMG can be installed any path (having no spaces).






Contributed articles

Contributed articles on Harbour &   HMG

(  In order  of  publishing  date  )

Roberto Lopez  (Builder of HMG and HMG-IDE; Buenos Aires, Argentina )

What is HMG ?

Sri Rathinagiri (Builder and  Administrator of HMG Forum;  Sivakasi, India)

How I have joined HMG Family – A Story
An explanation about Harbour, HMG and HMG-IDE

Raumi  ( Senior member of HMG-Forum; Lünen, Germany )

From CA-Clipper to Windows in 5 Minutes
Postgresql as a backend for HMG

Danny Del Pilar ( Senior member of HMG-Forum; Manila, Philippines )

My HMG Learning Experience

Agil Abdullah Batati  (Programmer Never Surrender; Jakarta / Indonesia  )

The Easy Way To Study Programming In Harbour And HMG —  Part I

PutFile() with 5th parameter

Beware : This article posted on  February 2, 2013 and than with HMG 3.1.3 release on 23 May 2013 added 5th and 6th parameters to that function by our genius Dr. Soto …

Look at changelog of HMG.


PutFile() is a HMG function that :

Opens ‘Save As’ System Dialog And Returns The Saved File name


PutFile ( acFilter , cTitle , cIniFolder , lNoChangeDir ) –> cSavedFileName

Although its name is “Put”, this function doesn’t “put” anything to anywhere; that is don’t write anything to disk. It only return a file name ( or empty string if user not selected / typed anything). File that name returned by PutFile() may exist or not. This is only difference between PutFile() and GetFile(); the second return only name of an existing file.

Therefore PutFile() function doesn’t check overwrite status. This is totally responsibility of programmer and if not care, PutFile() become a dangerous tool. The “Default File Name” and network environments will increase the risk. Of course no problem for intentionally overwrite.

As a result, PutFile() open a “Save As…” dialog box and returns a file name to save, selected / typed by user.

As above syntax indicated, this function has four parameters.

Whereas sometime required a bit more info : default file name.

When program suggest a default file name, in addition to select / type a new file name, user may feel more comfortable by only confirm (verbatim or after typing something) suggested file name.

This is a bit modified version of PutFile() (with a small test program); since accept default file name as 5th parameter, name is PutFile5P()

Note : This work is superseded by adding two parameters to official PutFile() function at HMG 3.1.4 2013/06/16.

Happy HMG’ing 😀




  HMG Common Dialog Functions 
  PutFile5P() Test prg.

#include ""
  LOCAL nTask
     AT 0,0 ;
     WIDTH 400 ;
     HEIGHT 400 ;
     TITLE 'PutFile with Default File Name' ;
        POPUP 'Common &Dialog Functions'
           ITEM 'PutFile5P()'ACTION MsgInfo( Putfile5P( ;                       
                { {'Text Files','*.txt'} },; // 1° acFilter ;
                   'Save Text',;             // 2° cTitle 
                   'C:\',;                   // 3° cIniFolder 
                   ,;                        // 4° lNoChangeDir 
                  "New_Text.TXT" ) )         // 5° cDefaultFileName
       END POPUP
FUNCTION Putfile5P ( aFilter, title, cIniFolder, nochangedir, cDeFilName )
   LOCAL c:='' , n

   IF aFilter == Nil
      aFilter := {}

   IF HB_ISNIL( cDeFilName )
      cDeFilName := ''

   FOR n := 1 TO Len ( aFilter )
       c += aFilter [n] [1] + chr(0) + aFilter [n] [2] + chr(0)

RETURN C_PutFile5P ( c, title, cIniFolder, nochangedir, cDeFilName )
#define HB_OS_WIN_USED
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include "hbapi.h"
#include "hbapiitm.h"



 char buffer[512];


 if ( hb_parl(4) )
 flags = flags | OFN_NOCHANGEDIR ;

 if( strlen( hb_parc( 5 ) ) != 0 )
 strcpy( buffer, hb_parc( 5 ) );
 strcpy( buffer, "" );

 memset( (void*) &ofn, 0, sizeof( OPENFILENAME ) );
 ofn.lStructSize = sizeof(ofn);
 ofn.hwndOwner = GetActiveWindow() ;
 ofn.lpstrFilter = hb_parc(1) ;
 ofn.lpstrFile = buffer;
 ofn.nMaxFile = 512;
 ofn.lpstrInitialDir = hb_parc(3);
 ofn.lpstrTitle = hb_parc(2) ;
 ofn.Flags = flags;

 if( GetSaveFileName( &ofn ) )
 hb_retc( ofn.lpstrFile );
 hb_retc( "" );
#pragma ENDDUMP

Basic Controls – 3

( Status Bar, Check Box )

We are continuing with Viva_HMG.hbp, Main.prg and Main.fmg.

While using a table and while navigating between its records, we need some extra info to show to user: Name of table, current record and record count in the table. So user always feels comfortable by knowing where is he / she; which table, which record?

The status bar control is convenient for this purpose and though this is a quite simple control, IDE has a builder for it: Status bar builder.

When you choose this builder ( after open the .fmg file by IDE of course ), a dialog box will open:

By using this dialog box we can define a status bar. We can prefer define status bar manually too:

        STATUSITEM "" WIDTH 300
        STATUSITEM "" WIDTH 40
        DATE         WIDTH 90
        CLOCK             WIDTH 90

After define status bar, we need assign values to its items. We don’t need assign values to DATE and CLOCK items, because these items will be updated by system (HMG) automatically.

First a little procedure :


EditReco.StatusBar.Item( 1 ) := cTableFNam


RETURN // InitEdit()

Change ON INIT event of  EditReco form from ReadData() to InitEdit(.

And add this line at end of ReadData() procedure.

 EditReco.StatusBar.Item( 2 ) := LTRIM( STR( RECN() ) ) + "\" + ;
                                 LTRIM( STR( LASTREC() ) )

Let’s look at the result :

Whenever active record change, Item( 2 ) of Status Bar will be updated ( 5/25 ) in above picture.

In this step, user must use “Save” button every time current record edited.  Whereas “Read” process is different; whenever current record changed, values of text boxes automatically updated. What about automatic save? May be, we can do this; but user may don’t want such automation. Asking a question like “Do you want save?” every change doesn’t a good way.

The better way may be: put a control to form such “Auto save” with On / Off option.

Yes, fortunately we have such control: Check Box.

We can replace a Check Box control to EditReco form with chbAutoSave name and Auto Save caption:

Now, how we will implement Auto Save process?.

By adding a little IF clause to ACTION events of navigation buttons:

Top : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBGOTOP(), ReadData() )

Next : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBSKIP(), ReadData() )

Previous : ( IF(EditReco. chbAutoSave.Value , SaveData(), ), DBSKIP( -1 ), ReadData() )

Last : (IF(EditReco. chbAutoSave.Value , SaveData(), ), DBGOBOTTOM(), ReadData() )

To be continued …

Download source files

Basic Controls – 1

( Image, Label and Button )

We are continuing with Viva_HMG.hbp, Main.prg and Main.fmg. First, let’s enlarge our form: width: 650, height: 550; and then place an image: First click “image” button the toolbar of HMG-IDE, and then click anywhere in the form. This clicked point in the form, will be left upper corner of control; in this case : image. IDE always first places controls with its default values. Our image is 405 x 340 pixel size:

We need assign a size to image control so it can hold properly our image. We can manually set these values and assign name of image file:

Background color of our form didn’t well-matched with this image. Let’s change it to white:

In this step, if we run the program we will see like this :

The STRETCH option of IMAGE control allows assigning size values to the control other than original image sizes. In this case quality of image may decrease. We need also avoiding distortion too; that is keeping fixed aspect ratio of image.

By assigning same width / height values of form and image; we can use an image as back-ground image of form. But in this case we can’t place other control onto image: because controls must not be overlap to each other. Under certain circumstances system not obstructs this. But the beneath control can’t seen.

The LABEL control is an exception of this rule by TRANSPARENT option. If a label is transparent, the beneath control may be seen partially.

Let’s add a label to our form:

The big “A” symbol in the toolbar of IDE represent LABEL. First click this button and then top of our form:

The placeholder of LABEL is primitive situation for now. We have added a new and adjusted  both to our needs:

If we built and run our project after set these values, appearance will be like this:

Since two controls (labels) have been overlapped, constructing this “shadow” effect will be a few painful. You can edit .fmg file out of HMG, via any text editor when necessary.

Labels probably are most used controls in GUI programming. This control simply displays any text onto form. For xBase programmers we can say this is GUI counterpart of @ …,… SAY command. As all other GUI controls, we use coordinate system to indicate placement of control. In addition we can set size ( width, height ), back and fore color values, font properties and others as well as we need.

Labels also have ALIGNEMENT property with LEFT, RIGHT and CENTER option. In this sample used LEFT.

In addition, LABEL control supports ACTION event too. This means you can instruct a LABEL control to do an action when user clicked it; same as BUTTON.

Last control to use in this sample is button.

Beside menus, buttons are handy controls for doing an action when user clicked. Let’s see how :

The button for BUTTON in the IDE Tool Bar is this:

As precedents, one click to this button and another one to form, under image:

And two more :

Now we can tailor these buttons to our needs:

First let’s change names and captions given by IDE:

btnOpenFile, btnEditRec and btnExit to names and Open File, Edit Record and Exit to captions, consecutively:

It’s time to assign ACTIONs to this buttons.

MsgInfo( “Open File”) to ACTION of btnOpenFile

MsgInfo( “Edit Record”) to ACTION of , btnEditRec,

ThisWindow.Release to ACTION of btnExit.

And, RUN of course …

Test ACTIONs of buttons by clicking: first two will repeat the sentences in their captions via MsgInfo() function  and the last will terminate program. Yes, we are using RELEASE method to the main window for terminate running program, instead of QUIT or CANCEL commands.

That’s all for now !

Downloads source files

DBA : Data Base Assistant

DBA is an imitiative work to the © dBASE III’s Assistant.

It may be an easy tool for people who are familiar to this base architecture of the whole x-Base family.

Many thanks to :

Antonio Linares ( Initiator and first developer of © Harbour ) and

“Le Roy” Roberto Lopez ( Initiator, Builder and Developer of © HMG  ).

Without this two big men and their volonteer coworkers, DBA ( and many others of course) couldn’t be exist.

Download ( setup executable ) here.

How I can migrate ?

How I can migrate DOS  to Windows ?

By principle, Harbour  can compile every Clipper Language program; and Harbour applications can run under Windows ( besides many other platforms ) with no problem. This is one of main goals of Harbour project.

Furthermore, Harbour compiled executables will be 32 bit, not 16 😉

Maybe your application include many ( or too many ) .prg file; no problem; (almost) no modification required on your source code; nor extra scripts for compile. ( Thanks to Viktor Szakáts for really wonderful MAKE utility : HBMK2. )

Only  care is :  if “main” prg of your application doesn’t have a “main” module , add one PROCEDURE or  FUNCTION statement to most top of your “main” .prg.


That’s all 🙂

You can build your application via HMG by a .bat file (or direct command in the DOS box) such as :

CALL C:\hmg\build.bat /c <mainPrgName>

or via Harbour:

SET PATH=C:\harbour\bin;C:\hmg\mingw\bin;%PATH%
hbmk2 <mainPrgName> -RUN

or the simplest way :

    C:\harbour\bin hbmk2 <mainPrgName> -RUN

( hbmk2 will find all necessary  paths / files 🙂 )

Of course, you need supply name of your main .prg file in place of <mainPrgName>. You may also want to  change  “C:\hmg” and “C:\hmg\harbour” according to your install configuration.

Please be careful about PATH command : If you call the the .bat file from Windows explorer, no problem. If you are working on command (DOS) box, calling repetitively .bat file may cause problem by grown of PATH . In this case you may build a separate .bat for only PATH command and call it only once at beginning of DOS session.

If you want convert a text (console) based application to GUI ( Graphical User Interface ) based Windows application, this is another thing and there isn’t any automatic way for this.  You have need first a GUI library can be used into Harbour. After selecting which library is convenient to your needs and learning  this library, you may begin planing steps of converting process. Writing your application from scratch may be longest but most secure way.

There are links to some articles  about migration in the Links page; looking at this will be useful.