DFRM tutorial

Example 1: a simple alert box.

by Dominique Béréziat

The purpose of this example is to create a 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_form( 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 initialise 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 in the which is box with relief borders. Second parameter stand for the maximal number of object 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().

Rest of the code address some WinDom aspect to handle GEM event : the callback function ApTerm() catches AP_TERM message (application terminaison), and we handle GEM event in an infinite loop.

#include <stdlib.h>
#include <windom/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_form( 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 useness 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 it in the dialog structure using dfrm_add(). So They are added as children of 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/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_form( 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 button as children of invisible box.
  4. add invisible as children of ROOT object with an vertical alignment.
#include <stdlib.h>
#include <windom/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_form( 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 adding some alignement/justification directive. For example, we want to center texts and buttons inside the form : we specified a centered directive for each concerned object using dfrm_align() function.

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

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

  1. wclose to the button "Exit". The function simply close the window.
  2. winfo to the button "Info". This function open an alert box displaying WinDom and DFRM number version.


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