DFRM tutorial

Example 1 : simple alert box.

by Dominique Béréziat

The purpose of this example is to create an alert box : a box containing a text object and two buttons "Ok" and "Cancel".

#include <stdlib.h>
#include <windom/dfrm.h>

void ApTerm( void);
void WinTerm( WINDOW *win, void *data);

void main( void) {
  WINDOW *win;
  void* dial;
	
  ApplInit();
	
  dial = dfrm_create( 10, TYPE_NORMAL);
  dfrm_setw( dial, ROOT, 100);
  dfrm_seth( dial, ROOT, 50);

	
  win = dfrm_open( dial,WAT_FORM,"Alert Box",
                   TRUE);

  EvntAttach( NULL, AP_TERM, ApTerm);
  for( ;;) EvntWindom( MU_MESAG);
}

void ApTerm(void) {
  while( wglb.first) {
    ApplWrite( app.id, WM_DESTROY, 
               wglb.first->handle, 0, 0, 0, 0);
    EvntWindom( MU_MESAG);
  }
  ApplExit();
  exit( 0);
}

First Step

First of all, you have to initialize WinDom. Next, we declare a local variable to build our dialog box: a dialog pointer.

The second thing to do is to create a master dialog structure. The function dfrm_create() creates :

  • A dynamic structure which will contain objects.
  • Using TYPE_NORMAL mode, we create a root object which is box with relief borders. The second parameter stands for the maximal number of objects in the form.

The third thing is to place the dialog form into a window using dfrm_open(). This function is a custom call of the WinDom function FormCreate().

The continuation of the code addresses some WinDom aspects to handle GEM events : the callback function ApTerm() catches the AP_TERM message (application terminaison), and we handle GEM events in an infinite loop.

#include <stdlib.h>
#include <windom.h>
#include <dfrm.h>

void ApTerm( void);
void WinTerm( WINDOW *win, void *data);

void main( void) {
  WINDOW *win;
  void* dial;
  int child;
	
  ApplInit();
	
  dial = dfrm_create( 10, TYPE_NORMAL);
/* Useless code
  dfrm_setw( dial, ROOT, 100);
  dfrm_seth( dial, ROOT, 50);
 */
  
  child = dfrm_new_label( dial, TYPE_LABEL, 
                          "This alert box");
  dfrm_add( dial, ROOT, child, -4, -1, DIR_VERT);
  
  child = dfrm_new_label( dial, TYPE_LABEL, 
                      "is designed using DFRM");
  dfrm_add( dial, ROOT, child, -4, 0, DIR_VERT);

  win = dfrm_open( dial,WAT_FORM,"Alert Box",
                   TRUE);
  EvntAttach( NULL, AP_TERM, ApTerm);
  for( ;;) EvntWindom( MU_MESAG);
}

void ApTerm(void) {
  while( wglb.first) {
    ApplWrite( app.id, WM_DESTROY, 
               wglb.first->handle, 0, 0, 0, 0);
    EvntWindom( MU_MESAG);
  }
  ApplExit();
  exit( 0);
}

Second Step

In the next step, we add two labeled objects. For that purpose we have to declare a local variable, child, which hold the index of created object.

Directive of size on the root object (dfrm_setw() and dfrm_seth()) are now useless because when we add children objects to a object, its size is recomputed in order to contain its children objects.

DFRM functions with prefix dfrm_new_ create new objects. Here we create two label objects with dfrm_new_label().

After object creation, we can add them in the dialog structure using dfrm_add(). So they are added as children of the ROOT object, they are vertically aligned, each object are spaced using a demi-height character (-1). Objects are placed from 2 width character (-4) from the left border because objects are left-aligned by default.

#include <stdlib.h>
#include <windom.h>
#include <dfrm.h>

void ApTerm( void);
void WinTerm( WINDOW *win, void *data);

void main( void) {
  WINDOW *win;
  void* dial;
  int child, parent;
	
  ApplInit();
	
  dial = dfrm_create( 10, TYPE_NORMAL);

  child = dfrm_new_label( dial, TYPE_LABEL, 
                          "This alert box");
  dfrm_add( dial, ROOT, child, -4, -1, DIR_VERT);
  
  child = dfrm_new_label( dial, TYPE_LABEL, 
                      "is designed using DFRM");
  dfrm_add( dial, ROOT, child, -4, 0, DIR_VERT);

  /* 1. Create an Invisible BOX */
  parent = dfrm_new_box( dial, 0, 0, 0, 0);
    /* 2. create a button */
    child = dfrm_new_button( dial, TYPE_XDBUT, 
                             "Exit");
    /* 3. horizontaly aligned in inv. box */
    dfrm_add( dial, parent, child, 0, -1, 
              DIR_HORI);
    /* another button */
    child = dfrm_new_button( dial, TYPE_XEBUT, 
                             "[Info");
    dfrm_add( dial, parent, child, -4, -1, 
              DIR_HORI);
  /* 4. adding invisible box in ROOT object */
  dfrm_add( dial, ROOT, parent, -4, 0, DIR_VERT);

  win = dfrm_open( dial,WAT_FORM,"Alert Box",
                   TRUE);
  EvntAttach( NULL, AP_TERM, ApTerm);
  for( ;;) EvntWindom( MU_MESAG);
}

void ApTerm(void) {
  while( wglb.first) {
    ApplWrite( app.id, WM_DESTROY, 
               wglb.first->handle, 0, 0, 0, 0);
    EvntWindom( MU_MESAG);
  }
  ApplExit();
  exit( 0);
}

Third Step

Now, we want to add horizontaly aligned buttons above label objects. We need a second local variable containing a parent object index. To align horizontal buttons we have to :
  1. create an invisible box,
  2. create and align buttons,
  3. add buttons as children of invisible box,
  4. add the invisible box as children of the ROOT object with an vertical alignment.
#include <stdlib.h>
#include <windom.h>
#include <dfrm.h>

void ApTerm( void);
void WinTerm( WINDOW *win, void *data);
void winfo( WINDOW *win, int index);
void wclose( WINDOW *win, int index);

void main( void) {
  WINDOW *win;
  void* dial;
  int child, parent;
	
  ApplInit();
	
  dial = dfrm_create( 10, TYPE_NORMAL);

  child = dfrm_new_label( dial, TYPE_LABEL, 
                          "This alert box");
  dfrm_add( dial, ROOT, child, -4, -1, DIR_VERT);
  dfrm_align( dial, child, DIR_HORI, 
              ALIGN_CENTER);
  child = dfrm_new_label( dial, TYPE_LABEL, 
                      "is designed using DFRM");
  dfrm_add( dial, ROOT, child, -4, 0, DIR_VERT);
  dfrm_align( dial, child, DIR_HORI, 
              ALIGN_CENTER);

  /* 1. Create an Invisible BOX */
  parent = dfrm_new_box( dial, 0, 0, 0, 0);
    /* 2. create a button */
    child = dfrm_new_button( dial, TYPE_XDBUT, 
                             "Exit");
    dfrm_attach( dial, child, BIND_FUNC, wclose);
    /* 3. horizontaly aligned in inv. box */
    dfrm_add( dial, parent, child, 0, -1, 
              DIR_HORI);
    /* another button */
    child = dfrm_new_button( dial, TYPE_XEBUT, 
                             "[Info");
    dfrm_add( dial, parent, child, -4, -1, 
              DIR_HORI);
    dfrm_attach( dial, child, BIND_FUNC, winfo);
  /* 4. adding invisible box in ROOT object */
  dfrm_add( dial, ROOT, parent, -4, 0, DIR_VERT);
  dfrm_align( dial, parent, DIR_HORI, 
              ALIGN_CENTER);

  dfrm_repack( dial);
  win = dfrm_open( dial, WAT_FORM,"Alert Box",
                   TRUE);
  EvntAttach( NULL, AP_TERM, ApTerm);
  for( ;;) EvntWindom( MU_MESAG);
}

void ApTerm(void) {
  while( wglb.first) {
    ApplWrite( app.id, WM_DESTROY, 
               wglb.first->handle, 0, 0, 0, 0);
    EvntWindom( MU_MESAG);
  }
  ApplExit();
  exit( 0);
}

void wclose( WINDOW *win, int index) {
  ObjcChange( OC_FORM, win, index, NORMAL, TRUE);
  ApplWrite( app.id, AP_TERM, 0, 0, 0, 0, 0);
}

void winfo( WINDOW *win, int index) {
  FormAlert( 1, 
     "[1][Compiling using|WinDom v%x.%02x"
     "|DFRM v%x.%02x][OK]", 
     WinDom.patchlevel >> 8 ,
     WinDom.patchlevel & 0x00FF,
     __DFRM_MAJOR__,__DFRM_MINOR__);				
  ObjcChange( OC_FORM, win, index, NORMAL, TRUE);
}

Last Step

In this last step, we can add some alignement/justification directives. For example, we want to center texts and buttons inside the form : we specify a centered directive for each concerned object by calling the dfrm_align() function.

Directives of alignment are effective only after the function dfrm_repack() is invoked.

We finish by adding callback functions to selectable objects. We bind the functions :

  1. wclose to the button "Exit". This function closes the window.
  2. winfo to the button "Info". This function opens an alert box displaying WinDom and DFRM number versions.


Comment ? suggestion ? Send a mail to Dominique Béréziat.