GRAphical Programming for Eiffel index contents

Chapter XII. How to Use Resources

When you write a GUI program you can divide the interface into two parts: how it appears and how it interacts with the program's "internals". In your code, for example, you may not think about the buttons order in any dialog box. GRAPE can place your dialogs, menus, buttons and cursors into separate modules which are written on GRAPE's original "script language", called ERC (the Eiffel Resource Code).


Why ERC?

You can ask why we must learn another language? Please do not worry again, this language is very similar to our favorite Eiffel. If you know the Resource script language for Microsoft Windows you can easily understand ERC. If you have no experience in the Resource languages you can simply understand it if you know the Eiffel language. And more, if you are using our Interface Builder (IB) you can ignore ERC at all, simply draw your fantasies with it.


First steps

Now let's compare the code using the embedded menu creation calls and the code using the ERC resources.

This only a piece of code from the TEMPLATE directory. It builds the menu structure "manually".

make_menu : MENU is
   local 
     menus : MENU;
     popup : SUB_MENU_ITEM;
     entry : MENU_ENTRY;
     item : MENU_ITEM;
   do
     !!Result.make_root;
     !!menus.make;

     !!item.make("&New child window", 0, IDM_NEW );
     menus.add(item);
     !!entry.make_separator menus.add(entry);
     !!item.make("&Close", 0, IDM_CLOSE );
     menus.add(item);
     !!item.make("Close Al&l childs", 0, IDM_CLOSE_ALL);
     menus.add(item); !!item.make("E&xit", 0, IDM_QUIT );
     menus.add(item);

     !!popup.make("&File", 0, menus );
     Result.add(popup);

     !!menus.make;
     !!item.make("&Cascade", 0, IDM_CASCADE );
     menus.add(item);
     !!item.make("&Tile", 0, IDM_TILE );
     menus.add(item);
     !!item.make("Arrange &Icons", 0, IDM_ARRANGE );
     menus.add(item);

     !!popup.make("&Window", 0, menus );
     Result.add(popup);
   end; 

What a terrible code it is? And only imagine that you have to insert it in each your application. Fortunately it's not necessary if you use our ERC resources.

Start Interface Builder and create file RESOURCE.ERC into the TEMPLATE directory. Create a menu resource called MAIN_MENU and save it. You will got a "very pretty" ERC file:

menu MAIN_MENU is
   sub_menu is
     text := "&File";
     menu_item is
       text := "&New child window";
       command := IDM_NEW;
       checked := false;
       disabled := false;
       end;
     separator;
       menu_item is
       text := "&Close";
       command := IDM_CLOSE;
       checked := false;
       disabled := false;
       end;
     menu_item is
       text := "Close A&ll childs";
       command := IDM_CLOSE_ALL;
       checked := false;
       disabled := false;
       end;
     menu_item is
       text := "E&xit";
       command := IDM_QUIT;
       checked := false;
       disabled := false;
       end;
     end;
   sub_menu is
     text := "&Window";
     menu_item is
       text := "&Cascade";
       command := IDM_CASCADE;
       checked := false;
       disabled := false;
       end;
     menu_item is
       text := "&Tile";
       command := IDM_TILE;
       checked := false;
       disabled := false;
       end;
     menu_item is
       text := "Arrange &Items";
       command := IDM_ARRANGE;
       checked := false;
       disabled := false;
       end;
     end;
   end;

Are you surprised? You see a typical Eiffel text? Of course, the idea of ERC is to simplify the resource definitions for GRAPE programmers. Another reason to make ERC is to unify the resource definitions for different platforms. You can simply port your programs from MS Windows to Mac and you will have no problems with the resources.

Next step is to compile the script into a separate module. For Windows we must create a Dynamic-Linked Library (DLL). Examine MAKEFILE for the commands you need to create it. DLL is created from the C-source stub and RC script. You can produce a Microsoft compatible resource file with Interface Builder if you use the "Save as RC" menu item.

The piece of code that builds the menu structure "manually" (see above) can be replaced by the following code if ERC is used:

make_menu () : MENU is
   local
     rc : RESOURCE_CONTAINER
   do
     !!rc.make
     rc.open("generic.dll")
     if rc.is_valid then
       !!Result.load(rc, MAIN_MENU);
       rc.close();
     end
   end 

And that's all!

The next problem is connected with menu item identifiers. When you save resources as the GENERIC.RC file Interface Builder automatically generates file GENERIC.E with class RESCONST in it. Use it instead of SYS_CMD.E (according to the tradition all constants used in GRAPE's applications such as menu item commands are placed into class SYSTEM_COMMAND), make the appropriate changes into file GENERIC.PDL and in the inheritance clause of the GEN_APPLICATION class. Now you can compile a new version of the GENERIC application.


RESOURCE_CONTAINER class

This is the short form of the RESOURCE_CONTAINER class.

class RESOURCE_CONTAINER
   creation
     make
   feature
     -- System identifier of loaded binary resource
     sys_id : INTEGER;
     filename : STRING;

   make
     -- creation feature

   open ( file : STRING )
     -- Tries to load platforms binary resource file
     -- (DLL for windows)

   close
     -- Frees previously loaded binary resource file
 
   is_valid : BOOLEAN
     -- Checks wether the load is successful

   load_string ( string_num : INTEGER ) : STRING
     -- Loads string by number from RC file
   end 

You should work with this class in the following sequence:

make...
open...
if is_valid...
   load...
   load...
   close


Resource loading

If you want to load a resource (for example an icon) from the file you should call the load feature instead of make:

load (rc : RESOURCE_CONTAINER, code : INTEGER)

This feature is an alternative creation feature for classes RECT, TILE, BRUSH, COLOR, GRAPHICS_CURSOR, FONT, ICON, PEN, PICTURE. For more information about the resourceable objects, please look at the ERC On-Line Reference.


Close Resource library

close

Use this feature with a special care. After the resource container has been closed all the resources loaded from it become unavailable. For example:

!!rc.make...
rc.open...
if rc.is_valid then
   !!ico.load (rc, MY_ICON)
   application.set_icon (ico) -- This is invalid!!!
   rc.close
end

After you have closed the rc container the application will lose its icon.


© Object Tools -- info@object-tools.com -- December 1999