
              NOVELL TECHNICAL INFORMATION DOCUMENT

TITLE:              AppWare Bullets Article (3/94) Source Code
DOCUMENT ID:        TID100120
DOCUMENT REVISION:  A
DATE:               05APR94
ALERT STATUS:       Yellow
INFORMATION TYPE:   Symptom Solution
README FOR:         APINST.EXE

NOVELL PRODUCT and VERSION:
AppWare Foundation for Windows 1.70

ABSTRACT:

APINST.EXE contains the source code and the executable for the PDS Bullets
article that was published in March 1994.


DISCLAIMER
THE ORIGIN OF THIS INFORMATION MAY BE INTERNAL OR EXTERNAL TO NOVELL.  NOVELL
MAKES EVERY EFFORT WITHIN ITS MEANS TO VERIFY THIS INFORMATION.  HOWEVER, THE
INFORMATION PROVIDED IN THIS DOCUMENT IS FOR YOUR INFORMATION ONLY.  NOVELL
MAKES NO EXPLICIT OR IMPLIED CLAIMS TO THE VALIDITY OF THIS INFORMATION.


SYMPTOM

     Users wanted the source code and the executable for the PDS Bullets
     article that was published in March 1994.

SOLUTION

     APINST.EXE contains the source code and the executable for the PDS
     Bullets article that was published in March 1994.

     Self-Extracting File Name:  APINST.EXE     Revision:  A

     Files Included     Size     Date      Time

     \
       APINST.TXT         (This File)
           APPF.R       4244   03-17-94   11:49a
           MAIN.C       9353   03-17-94   12:49p
           MAIN.H       2023   03-16-94    9:30a
           MAIN.I      73668   03-17-94   11:57a
           MAIN.R        579   02-16-94    3:02p
           MAIN.Z       2465   03-17-94   12:49p
          APP.EXE      25128   03-17-94   12:50p
          APP.ICO        766   09-17-93   12:00a
          MAIN.RC       2095   02-16-94    9:40a
          MAINR.H       2943   03-16-94    9:30a
         MAIN.BMK       2611   03-17-94   12:55p
         MAIN.DEF        414   02-11-94    5:41p
         MAIN.RES       1304   03-17-94   12:50p
     DISCLAIM.TXT        977   07-15-91   12:30p

     Installation Instructions:

     No installation instructions are included with this file.

     Solution Specifics:

     The following the text of the Bullets article: "Loading the Application
     Instance as a Resource"

     AppWare Foundation:
     Loading the Application Instance as a Resource

     The Novell AppWare Foundation (NAWF) is the base component of the Novell
     AppWare development architecture and is designed for developers who want
     to code directly to the core component of the AppWare development
     environment. NAWF is composed of programming libraries and a
     cross-platform API for accessing operating system, user interface, and
     connectivity services with traditional 3GL programming tools. NAWF is
     divided into different components and the components are grouped into
     series. Currently there are three series:

     *    Operating System
     *    User Interface
     *    Network Connectivity.

     The components are a collection of utility routines that are reusable
     within and among applications. Components encapsulate their routines with
     associated data elements, and some components rely on and inherit
     capabilities from other components. These components are implemented as
     modules using C.

     This article introduces the experienced C programmer to NAWF by detailing
     a method for creating a generic NAWF application that loads the
     Application instance as a resource. This resource can be used as a seed
     for other NAWF applications.

     Instances

     Instances are complex entities with many characteristics and behaviors.
     Instances are designed as general purpose entities, however all
     instance-using NAWF components are from the User Interface Series and are
     used to implement graphical user interfaces. They usually have a visible
     representation on the screen and interact with the end-user. The
     characteristics of instances include their types, attributes, and
     relationships to one another.

     Instances can be created in two ways:

     *    By loading instance data into a structure invoking the NAWF
          UInstCreate() function
     *    By describing it in a NAWF superset resource file, compiling it
          using the NAWFresource and compiler, and calling the UInstLoad()
          function. This article demonstrateshow to load the Application
          instance as a resource.

     As instances are created, they are organized into a hierarchy. At the top
     of every instance hierarchy there is an Application instance.

     Having a generic NAWF application you can later use as a starting point
     for other applications eases the process of adding functionality. If you
     can load a simple NAWF application as a resource, it will be easy to port
     that application to all other target operating system platforms.  Since
     the Application instance is just another NAWF instance, you can edit it
     using a resource editor.

     For example, you could set the Application instance style to "iconized"
     by changing the attribute in the resource definition. To do this, you do
     not have to recompile the C source modules. The change can be effected by
     recompiling only the resources and then relinking the program.


     Elements of a Generic NAWF Application

     Four types of files comprise a generic NAWF application:

     *    C Sources (.C)
     *    Header (.H)
     *    Intermediate include file (.Z)
     *    Superset resource file (.R)

     Intermediate include files have a .Z extension and may include any number
     of .h header files. All headers to be pre-compiled are gathered into the
     .Z file. Intermediate include files are used only for source files that
     are intended to be machine independent.

     Superset resource files have a .R file extension. Superset resources are
     resources defined by a platform-independent resource definition language.
     This language allows you to specify instance information that is a
     superset of the resource information for all platforms. Superset instance
     resources are described in text form in a resource data file.  The
     instance resource contains a standard header followed by fields specific
     to the instance type.

     Loading the Application instance as a resource requires four steps:

     *    Defining the application instance in the superset resource file
     *    Making the NAWF component initializations in the C source file
     *    Defining the appropriate vectors in the C source file
     *    Loading the Application instance


     Defining the Application Instance

     The Application instance is just another NAWF instance. Like all
     instances, the application instance has common instance information and
     specialized instance information. The code segment in Figure 1 defines
     the Application instance in the superset resource file.

*****************************************************************
Figure 1: Defining the Application instance in superset resource file

resource URES_TYPE_INSTANCE(APP_ID_KEY)
{

   /* options, native ref, default font, device type, extra */

   UR_UNITS_CHARS | UR_RECT_FRAME, DataNone{}, DataNone {}, N_NULL, {},
   {
      InstApplication
      {

         /* native key, resource options, childcount */

         0, UR_RECT_CONTENT, 0,

         /* action code, action params, user data, buf size, buf data */

         N_NULL, DataNone {}, N_NULL, 0, DataNone {},

         /* Filter */

         Filt {UINST_FOPT_VECTOR | UINST_FOPT_ALL,
              { N_NULL, N_NULL,  N_NULL },
              { N_NULL, N_NULL,  N_NULL },
          "AppVector" },

         /* item type, data, attrs */

         TypeID{UITEM_ID_BASEFONT}, DataStr{ "App Instance" },
                AttrsNone{},

         /* Virtual Data */

         VirtNone{},

         /* style, style2, options, options2, alignment */

         UINST_STYLE_SHOW|UINST_STYLE_CLOSEABLE|
            UINST_STYLE_ICONIZEABLE|UINST_STYLE_SIZEABLE,
         N_NULL, N_NULL, N_NULL, N_NULL,

         /* frame, selection, mnemonic, cursor */

         RectNone , SelNone {}, MnNone {}, DataStd
            {URES_STD_ARROW_CURS},

         /* help desc, help topic, extra */

         HelpNone{}, HelpNone{}, {},

         /* icon, menu bar, window menu position, size information */

         DataNone {},
         DataRef {"",URES_TYPE_INSTANCE, APP_MENU, N_NULL},
                  N_NULL, SizeNone {},

         /* foreground timer intervals, background timer intervals,
            help config structure, extra */

         0, 0, HelpConfigNone {}, {}
      },
   }
};

END of FIGURE 1
*****************************************************************

     Initializing NAWF Components

     An important part of the application setup process is initializing each
     NAWF component that will be used in the application. NAWF components must
     be initialized in a strict order to be properly utilized by an
     application. Failure to observe this requirement can cause erratic
     application behavior such as a General Protection Fault in the NAWF.DLL
     under MS Windows.

     The components listed in Figure 2 are shown in the proper sequence. 
     Although only three components are listed, other components must be
     initialized in proper order, depending on which ones you use in your
     application.


*****************************************************************
Figure 2: NAWF component initialization

/* Essential foundation components */

if (! UModInit ( &Access, UMOD_VERSION, 0L ))
    UModExit( UErrGetVal( &Access ) );
if (! UMemInit ( &Access, UMEM_VERSION, 0L ))
    UModExit( UErrGetVal( &Access ) );
if (! UErrInit ( &Access, UERR_VERSION, 0L ))
    UModExit( UErrGetVal( &Access ) );

/* Other component initializations */

END of FIGURE 2
*****************************************************************

     Defining Message Vectors

     Before loading the Application instance, you must make sure that the
     appropriate vectors are defined for the messages that you want to filter.

     Using vectors for message filtering is somewhat different than using
     callback filters and explicit filter masks. Rather than writing a single
     message filter procedure that handles all message types utilizing a
     switch statement, you can write a set of individual message handlers. 
     Each handler can be written to handle a specific message before or after
     notification (pre- or post-notification). These handlers are then
     associated with message types by a vector definition, shown in Figure 3.

     Note: UInstVectorBegin, UInstVectorMsg, and UInstVectorEnd are macros
     with parameters which generate code. These macros must never be
     terminated with semicolons.

*****************************************************************
Figure 3: Associating message types  with a vector definition

/* Begin the vector definition */

UInstVectorBegin( AppVector, N_NULL )

/* Associate OnAppAfterCREATE filter procedure with the post-filtered
   UMSG_CREATE message */

UInstVectorMsg( UMSG_CREATE, UMSG_MODE_AFTER, OnAppAfterCREATE)

/* Associate OnAppAfterACTION filter procedure with the post-filtered
   UMSG_ACTION message */

UInstVectorMsg( UMSG_ACTION, UMSG_MODE_AFTER, OnAppAfterACTION)

/* End the AppVector definition */

UInstVectorEnd( AppVector )

END of FIGURE 3
*****************************************************************


     The code in Figure 3 associates two filter procedures with the
     UMSG_CREATE and the UMSG_ACTION messages. The code segment in Figure 4
     defines the OnAppAfterCREATE filter procedure that would automatically be
     called when a post-filtered UMSG_CREATE message is generated.

*****************************************************************
Figure 4: Defining the OnAppAfterCREATE filter procedure

N_GLOBAL_FUNC( nbool8 )
OnAppAfterCREATE ( pUMsgStruct pMsg )
{
     /* You can put in the code that you want executed */

      return N_TRUE;
}

END of FIGURE 4
*****************************************************************

     Loading the Application Instance

     NAWF instances can either be created by calling UInstCreate(), or by
     loading it as a resource by a call to the function UInstLoad(), as shown
     below.

     nid UInstLoad (pAccess,
                    idInstParent,
                    idResPack,
                    pInstFilter,
                    userLoadData);

     UInstLoad() is used to load an instance or an instance hierarchy from a
     resource definition. The example program discussed in this article uses
     the UInstLoad() function to load the Application instance as a resource. 
     The code segment below demonstrates how the Application instance must be
     defined in the superset resource (.R) file.

     Assuming that you have performed the appropriate NAWF component
     intializations, and have created the UModMain() function with the message
     loop, you can add the function shown in Figure 5 to load the Application
     instance as a resource.


*****************************************************************
Figure 5: Loading the Application instance

N_INTERN_FUNC( nid )     
LoadApp( void )
{
   nid         idResPack, appID;

   /* Open resource file */
   /* Access and idResFile are global variables */
   idResFile = UResOpenModule( &Access, UModGetModule( &Access ),
                               URES_OPEN_READ );
   /* Initialize Application instance */
   idResPack = UResCreatePack (&Access, idResFile, URES_TYPE_INSTANCE,
                               APP_ID_KEY, URES_PACK_NO_KEEP);
   DEBUG_ASSERT( UErrGetVal( &Access ) == N_SUCCESS &&
                 UResValidatePack( &Access, idResPack ),
                 "Can't reference App resource" );
   /* Load the App instance from the resources */
   appID = UInstLoad (&Access, N_NULL, idResPack, N_NULL, N_NULL);
   return (appID);
}

END of FIGURE 5
*****************************************************************


     Using a graphical resource editor, you can easily add additional NAWF
     instances as "children" of the Application instance. These instances are
     defined wholly in the resource file and only processing code need be
     added to your program.

     If you would like to obtain the complete source code for the example
     discussed in this article, it is available for downloading from Novell's
     NOVLIB forum on CompuServe (Library 7, APINST.EXE).

     If you have additional questions about any of the concepts discussed in
     this article or about the Novell AppWare Foundation, please contact
     Novell at 1-800-NETWARE (1-800-638-9273) or 1-801-429-5588.


*****************************************************************
*****************************************************************
(c) Copyright 1994 Novell, Inc. This article originally appeared in
Novell Professional Developer Bullets, Volume 6, Number 3.
*****************************************************************
*****************************************************************




