Using AVS/Express |
|
This chapter describes AVS/Express projects and processes. It includes the following sections:
An AVS/Express project defines your development and execution environment. Whenever you work with AVS/Express, you are working in a project. A project, which serves as the framework for your working environment, includes three major components:
When you first use AVS/Express, you work in the install area's project, with its full complement of AVS/Express template objects (see Install Area Project on page 3-7). The install area project is read only and cannot be modified; you create your own projects as summarized in Creating a Runtime Project on page 10-3.
You create your own projects as children of your current project. You can create a new project from any existing project (install or other), as long as it is your current (parent) project. A new project can be either a distinct project (the default) or a derived project.
Both distance and derived projects are dependant on the original installed version of AVS/Express for V files and other files needed at runtime. If you wish to create a project that is not dependant on the original install of AVS/Express see "See Creating a Runtime Project on page 10-3."
As noted in the previous section, a project comes with the set of predefined processes, some of which are created as needed for objects. You can also create additional processes by inserting them into the root-level ProcTemplates object in which processes are defined.
For details, see Defining Processes for Objects on page 10-12, Creating New Processes on page 10-14, and The proc.v File on page 10-29.
When working with AVS/Express, you will often need to compile processes, for example to include new or revised definitions of objects. You can compile a process either from within AVS/Express or from the command line. When you do the former, AVS/Express uses information that you provide-for example, source filenames, library dependencies, and process name-to construct a makefile and, if possible, use it to build a new executable. During the compile process, AVS/Express can also generate template source files in cases where an object's source file does not exist.
For details, see Compiling Projects and Processes on page 10-14.
Only Developer Edition users can create a runtime project. As a Developer Edition user, once you understand project architecture, you can use AVS/Express to create more sophisticated projects. To do this, you will compile and save a selected set of objects into a separate project area. This mechanism allows you to build runtime versions of your AVS/Express applications that are smaller, start up faster, and depend upon fewer files, and are therefore ideal for distribution.
For details, see Saving Compiled Projects (Generating a Runtime Project) on page 10-30.
Processes contain definitions for the objects in an AVS/Express project, enable the objects' interactions, and perform operations required by the project. Any number of processes can attach to a single AVS/Express session. Each AVS/Express object in a project lives in exactly one process, but all processes see the same object hierarchy and any process can operate on any other object regardless of which process contains it. AVS/Express processes can either exist on the local host or run on a remote host.
A project comes with an express process and a base internal bootstrap process, and user processes are created as needed for objects (see Defining Processes for Objects on page 10-12). You can also create additional processes as needed (see Creating New Processes on page 10-14). The processes for a given project are defined in its root-level ProcTemplates object (see The proc.v File on page 10-29).
You must compile an AVS/Express process to use the objects it defines.
For details, see Compiling Projects and Processes on page 10-14.
The main process, named express, synchronizes all other processes. It must, therefore, start up before any other process attaches to AVS/Express and exit after all other processes detach from AVS/Express. The main process serves as a hub for the exchange of addresses among processes: when one process attempts to access an object in another process, it forms a direct socket connection to that process via the main process. If the processes are on different hosts and the hosts have different data formats, AVS/Express performs the required data conversions automatically.
The main process starts some processes automatically when you create objects that live in them. Other processes are started externally and attach to an existing session.
The following figure illustrates the process organization of the AVS/Express object hierarchy:
Any AVS/Express process can initiate an operation, but the main process controls the execution of operations through an AVS/Express object called the Scheduler. The Scheduler synchronizes operations by calling push_ctx and pop_ctx routines to push and pop contexts for them on a stack (see Contexts on page 8-11 for details). Only a single push_ctx call can be active at one time: if the Scheduler has an outstanding push_ctx call and receives another, it queues the additional push_ctx call. The process that initiated the queued push_ctx call waits on the current push_ctx call until it completes with a pop_ctx call.
AVS/Express provides a definition of a default C main in the library -lmnc and a definition of a default C++ main in the library -lmncxx. By default, these libraries are included on the link line of any process that is constructed through an AVS/Express compilation. Whether AVS/Express uses the C or C++ version depends on which compiler it uses to compile a process; this is system dependent. You can also define your own main; for details, see Defining Your Own Main Process on page 10-9.
You use the following three environment variables to specify whether a process is the main process or an external process; that is, a process that attaches to the main process:
You can define these environment variables in several ways:
Each AVS/Express process has the following components:
When AVS/Express compiles a process, it generates code for two functions, PREinit and BASEinit, that AVS/Express' initialization routine calls (see Initializing AVS/Express on page 10-8 for details). At initialization, PREinit and BASEinit do the following:
The PREinit function is called before object definitions in the Templates hierarchy are defined and the BASEinit function after the Templates objects are defined but before any template objects are instanced.
You can add your own code to the PREinit and BASEinit functions by setting the properties pre_init_code (for PREinit) and init_code (for BASEinit). Each of these properties specifies C code that is added directly to PREinit or BASEinit functions (the string value for each must define a complete C statement). These functions are generated in the order in which objects appear in the Templates library, thus a particular library is defined after all of the libraries upon which it depends are defined.
Although PREinit and BASEinit are defined with C-scoped names, AVS/Express may compile them with a C++ compiler. Therefore, you must be sure that any functions called in the init_code and pre_init_code property values are declared before they are used. You can do this as follows:
For example, using V code, if the library MYLIB is included in the current process, you can call the function MYLIB_init in the BASEinit function as follows:
Each process has a name, so that AVS/Express can determine which processes are running and create the right objects in the right process. The name should correspond to the name of the object defined in the root-level ProcTemplates object (see The proc.v File on page 10-29). When AVS/Express generates a process, it sets the process name automatically by code inserted into the PREinit function; for example:
You need to set the name of a process explicitly only if you are generating your own PREinit and BASEinit functions for a process that will define local objects. In this case, you must set the name of the process to the process property value set for the objects that you will define locally.
You call the OMmain_init routine (or equivalent) to initialize AVS/Express. You must make this call before you attempt to access any AVS/Express objects. Once it returns, you can create and destroy AVS/Express objects.
How OMmain_init is called varies depending on your platform. For UNIX platforms, it is called as follows:
For Windows platforms, it is called as follows:
These routines parse the command-line arguments that AVS/Express parses (you can disable them by passing in empty command line strings). If you have command-line arguments that your program recognizes, you should remove them from arguments that you pass to OMmain_init since the routine displays error messages about arguments that it does not recognize.
This routine returns a flag that indicates whether the -vcp or -novcp options were specified in the command-line arguments. The flag should be passed to the OMmain_loop routine to enable the functionality of these command-line arguments.
The following call processes events for AVS/Express processes:
The vcp_flag argument can have one of the following three values:
As noted previously, AVS/Express provides definitions of default C and C++ main processes in the libraries -lmnc and -lmncxx, respectively, and includes these libraries on the link line of any process that it compiles. If you define your own main for a particular process, you must disable the use of the default main processes as follows:
See Providing Code Management Information on page 8-28.
Be sure to supply your definition in the correct language for your process. On UNIX systems, AVS/Express links your process with the C++ compiler if any objects in the process need C++, otherwise it links with the C compiler. If you are not certain which compiler your system uses, supply your definition of the main process in a C++ source file to force the use of C++ for the link.
The rest of this section discusses topics relevant to defining your own main process.
On UNIX systems, you can configure your main process to use the standard Xt event dispatch facilities (for example, XtAppMainLoop, XtAppNextEvent, or XtAppProcessEvent) instead of the routine OMmain_loop. Doing this makes it easer to integrate AVS/Express objects into existing Motif/Xt based applications. See your platform documentation for information on the XT event dispatch facilities.
In order to take advantage of this facility, you must do the following:
If you intend to use UI Kit objects in your application, you must ensure that your code and the UI Kit code share only a single XtAppContext. Currently, the only way to do this is to obtain the Widget pointer from the handle.widget subobject of a UI object used in your application. From this Widget pointer, you can use the XtWidgetToApplicationContext and XtDisplay functions to access the XtAppContext and the Display:
This example illustrates how to create a dummy shell object outside of the express project mechanism, obtain a Widget pointer from that object, and perform an EVXinit_display_xt call. It uses the example source code that follows the set of instructions.
The resulting express process uses the xtmain.cxx file as its main program.
When defining your own main process, you can define functions that AVS/Express will call in response to system events such as a time-out interval, an idle event, or an event on a file descriptor. You do this using the Object Manager API routine EVadd_select.
For details, see the reference description of EVadd_select in the AVS/Express online help.
There are two ways to make a process exit.
For details, see C and C++ API Routines on page 9-5 and the reference descriptions of these routines in the AVS/Express online help.
Each template object in AVS/Express belongs to exactly one process. The process for an object is set using the process property, which specifies the string name of an object defined in the root-level ProcTemplates object (see The proc.v File on page 10-29). This property is inherited as you move down the object hierarchy: if it is set on a library, each module in the library is placed in the specified process unless you override this value by setting the process property on the module itself to another process). If process property is unset for both an object and its parent, the object is placed in the default process, which is the first process in the ProcTemplates list (by default, the express process).
The following rules specify in more detail how the process for a particular object is set. Note that the order of these rules is significant: the first rule that applies to the object is used to set its process.
The following diagrams illustrate these rules. In each figure, the circles represent objects in the Templates hierarchy, belonging to processes as noted in the key.
If the library that contains C and D is given an explicit process setting, C no longer inherits the process from its superclass B and is instead assigned to the process of its parent.
Note that when you change the process on an object, you must recompile the affected processes:
See the next section, Compiling Projects and Processes, for details.
As noted previously, a project comes with an express process and a base internal bootstrap process, and user processes are created as needed for objects (see Defining Processes for Objects on page 10-12). Using the VCP, you can also create additional processes as needed while running AVS/Express, by inserting them into the root-level ProcTemplates object in which processes are defined (see The proc.v File on page 10-29).
To create a new process, enter the VCP window and navigate to the ProcTemplates object, then define your new process as in the following example:
When you save the project that contains this new process, your new proc.v file looks like the following:
When you compile this process, AVS/Express generates filenames with your process name as the identifier. Advanced Visual Systems recommends that you assign process names that have fewer than seven characters, in order to avoid problems on machines that limit filenames to eight or fewer characters.
You must compile an AVS/Express process to use the objects it defines. The simplest way to compile a single, specific process other than the express process is from within AVS/Express. Using information that you supply-source filenames, library dependencies, process name-AVS/Express compiles the process by constructing a makefile and, if possible, executes it. (If necessary, AVS/Express also generates source files that contain prototype source code for methods.) On most platforms, AVS/Express compiles a process dynamically, to make use of shared AVS/Express libraries. The next subsections describe compiling with shared libraries and compiling a single, nonexpress process.
Note that you cannot compile either of the following from within AVS/Express:
You must perform these compilations from outside AVS/Express, as described later in this section; however, both use AVS/Express-supplied compile functionality to simplify the task.
You can choose to compile a process manually without using AVS/Express compile functionality of any kind; however, this is a complicated task because you must perform independently each of the tasks that an AVS/Express compilation performs for you.
Shared libraries offers several notable benefits, including smaller executable size and drastically reduced link times when relinking your processes. AVS/Express uses shared libraries on all platforms except AIX, Windows NT, and Windows 95. You use shared libraries by dynamically linking to them (the default) at compile time.
Advanced Visual Systems recommends that if your platform supports shared libraries, you use dynamic linking. However, you can use static linking (as described later in this section), in which case your application is no longer dependent on AVS/Express external libraries.
Dynamic linking is the default behavior. If a dynamically linked application references the libmods.so or libmods.sl shared library, AVS/Express dynamically loads the image file reader and writer libraries, contained in the libmods.a library archive.
Static linking, which you must set explicitly, enables you to avoid using shared libraries at compile and/or link time. To do this, you set the NO_DLLIBS environment variable to a nonzero value for the make process (the recommended values are t or l). When you do this, the AVS/Express shared libraries are neither generated when compiling nor included on the link line when linking, and your process is linked with static libraries instead.
You can set NO_DLLIBS in any of the following ways:
Compiling a single process other than express from within AVS/Express is a straightforward procedure that consists of the following steps:
AVS/Express executes the compilation by performing the following tasks:
For a description of error messages that may appear during this procedure, see Common Error Messages on page 10-20.
Because you cannot compile a process while it is executing, you cannot compile the express process from within AVS/Express. Instead, you compile it as follows:
Run make on the express makefile by entering the following (On Windows):
With one exception, you can compile at one time all processes in your project (as defined in the root-level ProcTemplates object; see The proc.v File on page 10-29). The exception is that you cannot include the base internal bootstrap process, because you use it to perform the multiprocess compilation, as follows:
Note that you can also use the base process to build a specific process from outside of AVS/Express as follows:
Your XP_PATH environment variable must be set properly (for example, through the avsenv file) for this to work.
For details see The avsenv File on page 10-26.
You can gain further control over the compilation process by separating the code generation steps and the actual compilation.
This can save time when you are working on C/C++/FORTRAN code of a project, but not changing the V code. You can recompile the project without repeating the code generation process.
If you are working on Windows, you will probably use the debugger integrated into Microsoft Developer Studio to debug your project.
You can start Microsoft Developer Studio by clicking on the .dsw file that AVS/Express generates.
![]() |
You can also start Microsoft Developer Studio from the command line. First change directory so that the the current working directory is the same as the root of the project directory.
Alternatively you can bypass the autogenerated project files and start up Microsoft Developer Studio directory on the express executable
No matter how you start up Microsoft Developer Studio you will see to set the Working directory. Go to the Debug tab of the
Project->Setting control panel, and set the Working directory to the root of the project directory.
![]() |
This section describes common error messages that AVS/Express may return when you use it to compile a process.
The following error message may appear in the startup window when you compile a process:
The following types of error messages may appear in a popup window while the makefile is being processed. (The actual message text depends on the operating system.)
This section provides detailed information about certain aspects of AVS/Express process compilation. You do not need this information for relatively straightforward compilations, but it may be helpful when you implement and debug more complex projects.
The AVS/Express compilation process contains two main stages: code generation and process build.
This section provides detailed information about the code generation process. For information about the process build, see the make command documentation available with your system.
In Pass 1, AVS/Express determines what objects belong in what processes, using the rules discussed in Defining Processes for Objects on page 10-12, and marks the objects needed by the process to be compiled. When AVS/Express marks an object as needed, it also marks the containing library. For example, if the process needs the UIbutton object, AVS/Express marks both this object and the UI library that contains it. Note that other objects in a marked library (for example, UIshell in the UI library) are marked only if the project specifically needs them. To continue the previous example, AVS/Express marks UIshell, another object in the UI library, only if it is needed.
Note that if you compile using Project->Save Compiled Project instead of Project->Compile, this pass is modified so that only the objects that select are marked as needed. As a result, the process contains only a subset of the objects defined for this process in templ.v, and templ.v is not explicitly modified.
Two properties affect the way in which objects are marked as needed:
The libdeps property takes a list of names of AVS/Express template objects. In its object-marking pass, AVS/Express marks these objects but not their subobjects as needed by the process. This property is useful for guaranteeing that AVS/Express marks the link files specified by one library whenever another library is needed by a process. This is necessary only when those AVS/Express objects do not express this dependency directly.
For example, if you define a library that calls the FLD library but does not contain any FLD objects, AVS/Express may report that the FLD routines are undefined when you link. To fix this problem, set the libdeps property as follows to indicate this dependency:
The need_objs property also takes a list of AVS/Express objects. In its object-marking pass, AVS/Express marks these objects and their subobjects as needed by the process. You set this property on a module that creates objects dynamically to ensure that AVS/Express places them in any compiled project that contains the module.
For example, if you write a module that dynamically creates a UIbutton object and include the module in a compiled project, AVS/Express may report that the UIbutton object was not included in your project. To fix this problem, set the need_objs property as follows to indicate this dependency:
During the code generation stage, AVS/Express generates initialization code, header definitions, source definitions, and the process makefile.
In Pass 2, AVS/Express generates code for objects marked as needed during Pass 1; specifically:
The build_dir property specifies the build directory for an object and its subobjects. If this property is specified with a relative pathname, it is taken to be relative to the project directory. If the build_dir property is unset for an object or its ancestor, AVS/Express uses the project directory as the build directory.
All build files processed for an object and its subobjects are taken to be relative to the current build directory. T his includes values taken from the c_hdr_files, cxx_hdr_files, c_src_files, cxx_src_files, src_files, and link_files properties.
The c_src_files and cxx_src_files properties specify one or more source files required for processes that need this object. AVS/Express addes rules for constructing object files from the source files to the process makefile and adds the resulting object files to the link line for the process. (Recall that these files are specified relative to the current build directory.) If a process needs an object for which the cxx_src_files property is set, AVS/Express uses the C++ linker to link that process.
The src_file property also specifies one or more source files. It implements similar logic on its arguments except that it determines the language of the files from the filename suffixes. The omethod and cxxmethod base types also use current value of the src_file property to determine whether to generate target-function prototypes (see Target Functions on page 8-15 for details). You can turn off prototype generation by setting the use_src_file property to 0 on an object for which the src_file property is set.
The c_hdr_files and cxx_hdr_files properties specify one or more header files that contain the definitions needed to compile this object or its subobjects. Setting these properties puts an #include statement in the file that contains generated header definitions for this object, either the file specified by the out_hdr_file property, or the default file process_name.h if out_hdr_file is unset.
If AVS/Express can find an absolute path to each header file (recall that it looks relative to the current build directory), it adds the files to a list used to generate makefile dependencies for object files in this process. If it cannot find the header files, it includes them using a pathname specified specified from the property definition. AVS/Express does not treat this behavior as an error, nonetheless this does not generate proper dependencies.
On Windows, AVS/Express creates .dsp and .dws files for use by Microsoft Developer Studio. You can use these to recompile or debug the project.
AVS/Express project architecture is accessible to all users, and all users will find the discussion of project architecture in this section useful. Only Developer Edition users can generate runtime projects. An AVS/Express user who thoroughly understands project architecture can use AVS/Express to create more sophisticated projects; for example:
This section describes AVS/Express project architecture, then (for Developer Edition users) explains how to use Save Compiled Project to save a runtime project.
A project is based in a project directory. The project directory hierarchy contains all of the files and directories required by the project. At absolute minimum, it contains a directory called v, which contains the v files needed for the project. However, it typically contains much more than a v directory, including files and directories such as the following:
AVS/Express may generate some of these files and directories as needed, and you may supply others. The following sections do not describe all of a project's possible files and directories, but do discuss typical components.
The avsenv file contains environment-variable definitions. AVS/Express generates an avsenv file in your project directory whenever you create or save a project; for example:
You can modify an avsenv file by adding environment variable definitions as required; they take effect for AVS/Express only. If you do modify this file, be sure to remove the first two lines so that AVS/Express does not regenerate the file, thus removing your modifications, the next time you save the project.
Whenever AVS/Express starts up, it looks for an avsenv file in the following places in the order listed, and uses the first file it finds:
A particularly important environment variable-one required by AVS/Express whenever it starts up-is XP_PATH. The value of this environment variable is a list of project directories, specified as absolute pathnames; for example (from the previous avsenv file):
Your project's directory (if any) should be specified first, followed by the install area project's directory.
Whenever AVS/Express starts up, it looks for an definition of XP_PATH in the following places in the order listed, and uses the first definition it finds:
If AVS/Express does not find a definition, it sets XP_PATH to the directory two levels above the executable's directory. For example, if the executable is in the directory /home/express/bin/hp, AVS/Express sets XP_PATH to /home/express.
Note that when you refer to the XP_PATH environment variable in V code, you can supply an index value to indicate a particular project directory in its list. This usage has the following format:
Indexes for project directories in the XP_PATH list begin with 0 for the rightmost directory and increase by 1 as you move to the left. Recall the previous example:
In this definition, $XP_PATH<0> refers to /home/express and $XP_PATH<1> refers to /home/users/me/proj1.
The templ.v file, a V file located in the v directory, defines the contents of the Templates library which, in turn, defines all of the templates from which you can create new objects. For example:
The first line in this file (following) creates your project's Templates library:
Observe that the type of Templates is a filename. The $XP_PATH<0> component of the name refers to the rightmost path in XP_PATH, typically the install directory. Therefore, the entire name, $XP_PATH<0>/v/templ.v, refers to the install area project's templ.v file. As a result, the Templates library for your project begins with all of the objects in the install area project.
The subsequent lines define additions and modifications for your project. In this example, the project contains an additional library named MYLIB and and a simple module named named my_module that is defined in that library.
The proc.v file, a V file located in the v directory, creates a root-level object called ProcTemplates that defines a project's processes. The relevant (noncomment) portion of the install area project's proc.v file is as follows :
The project consists of three processes named as express, user, and base. The executable is given the same name as the name of the process object.
Here is a version of proc.v as it might appear in your project directory:
Observe that the type of ProcTemplates is a filename. The $XP_PATH<0> component of the name refers to the rightmost path in XP_PATH, typically the install directory. Therefore, the entire name, $XP_PATH<0>/v/proc.v, refers to the install area project's proc.v file. As a result, the ProcTemplates object for your project starts off with all of the processes of the install area project. You can manually insert additional lines to create additional processes; for example:
Two V files in the V directory contain information that defines the Network Editor libraries.
For more information on libraries, see Understanding Libraries on page 5-11
The default AVS/Express environment provides access to a large number of objects in the application development process. The Developer Edition of AVS/Express provides a feature, implemented as the Save Compiled Project command, that you can use to generate a project containing a subset of the objects used in the base project. There are two main advantages to using this feature:
You should consider streamlining a project with Save Compiled Project in the following circumstances:
Whenever you use the compiled project capability of this command, AVS/Express creates a separate project directory that contains local versions of the make files and configuration files that it generates for the project. This project directory also contains a local version of each AVS/Express executable needed by the objects contained in the compiled project.
The Save Compiled Project command is available on the Network Editor's Project menu. Selecting Project->Save Compiled opens the following dialog box:
As illustrated in this figure, there are three sets of controls in the Save Compiled Project dialog box:
You use the project directory controls to specify the directory for the compiled project. You can specify either a new directory or an existing directory. In the latter case, if the directory already contains a project, the new project replaces the previous project. You specify the directory either by typing its name into the text box or selecting the Browser button and navigating to it in the file-browser dialog box that opens.
There is directory, called runtime, under the "compiled project directory". The dictionary files for different languages are copied into this directory. Any files necessary for executing the runtime will be copied automatically into this sub-directory.
This used to be a manual process in Release 3.0; it is now automated in Release 4.0
You use the object selection controls to specify the core set of objects that the compiled project will contain. You can choose either of two objection-selection modes:
In addition to the core set of objects specified by your choice of mode, AVS/Express automatically includes any objects that the core set of objects need. For example:
The operation selection controls specify a number of operations that the command can perform when it executes. These operations are as follows:
Diagnostics are available when you select Project->Compile.
You may see a warning message if you copied methods from the "Standard Objects" page but did not provide a new function value to replace the default method value (OMomethod_unset, OMmethod_unset, OMcmethod_unset).
This warning message can be ignored, but it provides the name of the methods that are not functional in your system.
You can eliminate the extra warning message by setting the method value to a valid function name or deleting the method from your Templates library. If you want to "deactivate" the object that this method belongs to, you can set the "compile_subs" property to 0.
When AVS/Express compiles a project, it chains it off the project directories of the original project; that is, the project that was active at compilation time. You can determine which project directories were used to create the new project by reviewing the avsenv file in the new project directory. The compiled project uses libraries and object files from these other project directories when its executable is being linked; therefore, you must also compile these other projects if they define any new code that the compiled project uses.
The following figure illustrates the files generated when you execute Save Compiled Project command with the Generate source option checked.
These directories and files are as follows:
There is a subdirectory of the Compiled Project Directory called runtime. The dictionary files for different languages are copied into this directory , and any files necessary for executing the runtime will be copied automatically into this subdirectory.
The examples in this section illustrate uses of the Save Compiled Project command.
In this example, imagine that you have produced an application that is entirely represented using an AVS/Express network, and it is running as the current application. You now want to produce a version of this application that runs more efficiently and is easier to hand over to another user. To do this:
In this example, imagine that you have constructed an application that dynamically creates and modifies AVS/Express networks: specifically, it dynamically creates objects from the Data Visualization and the Graphics Display kits. You now want to deploy a more efficient version of this application to a set of users. To do this:
The following procedure explains how use AVS/Express and Microsoft Visual C++ to create a simple multiple-document interface (MDI) application that allows you to read AVS/Express geometry files and display them. The application that you will be creating is called Geomview. The file that you will access while creating this application is:
where <install_dir> is the directory in which AVS/Express is installed.
All of the steps that you perform in this procedure are specific to building the Geomview application, however, the steps can be adjusted and the concepts can be applied to developing similar types of applications.
The application is created as follows:
![]() |
The following steps are performed using Microsoft Developer Studio.
You are now finished with the Project Settings dialog box.
You can rotate, scale, or XY-translate the geometry using the left mouse button. To scale, hold the Shift key down while dragging. To translate, press the Control key while dragging.
If you select Window->New Window, a new view window appears, and it displays the currently selected geometry using the default transform.
If you select File->Close, the geometry for the currently selected view is deleted, and all of the geometry's view windows are closed.
The following procedure explains how to use AVS/Express 6.0 and Microsoft Visual C++ 6.0 to create an ActiveX Control (the technology formally known as OCX's). This is as an alternative to using AVS/Express to generate the OCX directly using the Save_Compiled_Project options. The advantages of this methodology are that you have none of the limitations regarding control naming or number of properties. It is also more robust, works in a wider variety of MS applications and is transportable.
The application that you will be creating is called Geomview. It is a simple OCX that allows you to display AVS/Express geometry files. This is the same Express application that the MFC example uses with the exception of shortcuts made in regard to access of the readers. The separate class for the reader is kept for future expansion purposes.
1. Start AVS/Express 6.0. Choose "None" when asked for the initial application type.
2. The v code we have supplied is a library. Use the following procedure to load the library. Select the "Templates" library from the Libraries combo box near the top of the Network Editor. Then, highlight the Templates library by clicking on its border.
3. Select the Object_Load_Objects... pulldown menu entry, and load the following V code: (note hard coded path name for teapot.geo. As this example develops, we will add additional controls to read other filenames) If you load the geomview.v that comes with express then you must modify it to contain the file name if you are not going to add code to choose the file to be loaded because it is not coded in the .v file as shown below.
4. Now we want to do a "Save_Compiled_Project". We don't need to create a project for this library. We do want to strip off any unnecessary kits. To do that, select the Project-Configure... pulldown menu entry, and use the dialog box to disable the Annotation and Graphing Kit, the Print Renderer, the VPS Renderer, and the VRML Renderer.
5. The highlight the Libraries.Templates.GEOMVIEW object by clicking on it. This is what we will save.
6. Select the Project-Save_Compiled_Project... pulldown menu entry. Specify a new project directory, and turn off the toggles labeled "Instance objects automatically on restore" and "Build project's executable". Then select the dialog's OK button. We only want to create the source code files (.cxx, .c and .h) and the binary v file (.vo).
7. After the compiled project has been generated, exit from AVS/Express and start Microsoft Developer Studio.
1. Select File-New-Project. The New Project Workspace dialog box appears. Select MFC ActiveXControlWizard, and enter a name for your project, e.g. geomview. Select the Create_new_workspace button. Click OK. The AppWizard now appears. Click Next on pages 1. On page 2 (step 2) of AppWizard, also check "Available in 'Insert Object' dialog" in addition to the defaults. Click Finish at the bottom. After you are done with the AppWizard, the project directory will be created.
The discussion below assumes that the project is called "geomview".
2. Copy the following files to your MSVC++ project directory from the compiled project directory that you generated using AVS/Express:
Note that the appl.vo file should be placed directly into your MSVC++ project directory; there is no need to create a "v" subdirectory.
3. In your MSVC++ project directory, create a file called avsenv, that sets the XP_PATH variable to the name of your project directory. For example, if your project directory is c:\projects\geomview, your avsenv file should contain the following line:
4. Using Project-Add_to_Project-Files, insert the following files into your project:
5. Select Project-Settings... to display the Project Settings dialog box.
Go to the Link tab, and specify the following files as Object/library modules: (note inclusion of mfc libraries to force link before the other run-time libraries). Cut and paste these - it's a lot to type. This is a rather long line which will be cut off from the view in most browsers.
For Express 5.1 use the following libraries
lib_vers.obj uci_pal.obj Xfld.obj xp_init.obj UIcursor.obj UIcursoP.obj ui_gen.obj libacvt.a libgeom.a libutil.a libgdogl.a libgdsw.a libgd.a libmutil.a libvxbx.a libui.a libcxxut.a libpal.a libdmap.a libdbxx.a libgmod.a libwtobj.a libwtool.a express.lib wsock32.lib mfc42.lib mfcs42.lib
For Express 6.0 use the following libraries
express.lib Xfld.obj lib_vers.obj UIcursor.obj UIcursoP.obj ui_gen.obj libgdogl.a libgdsw.a libgd.a libvxbx.a libusers.a libacmod.a libac.a libacvt.a libgeom.a libutil.a librf.a libui.a libcxxut.a libmods.a libavsx.a libbmp.a libgif.a libjpeg.a libpbm.a libsunrs.a libsgiim.a libtif.a libip.a libpal.a libdmap.a libdbxx.a libgmod.a libmutil.a libwtobj.a libwtool.a liblic.lib wsock32.lib xp_init.obj libagx.lib libag.a ag_omx.obj mfc42.lib mfcs42.lib
In the "Settings for:" list box on the left side of the dialog box, change the selection so that only the Win32 Debug version of the project is selected.
Go back to the C/C++ tab. In the "Preprocessor" category, remove the _DEBUG preprocessor directive and add MSDOS to the list. Go to Project_Options, change the /MDd flag in the Project Options area to /MD.
1. If you choose to use the debug version, you will need to make the changes to the link line. Go to Link->General, change mfc42.lib and mfcs42.lib to mfc42d.lib and mfcs42d.lib and add mfco42d.lib.You may have to specifically exclude mfc42.lib and mfc42s.lib in the Setting/Link/Input dialog.
Add the following in the ignore libraries typein in the Link->Input panel:
2. If you are using non debug then you will need to add the following in the ignore libraries typein in the Link->Input panel:
Go to the Link->Input->Additional Library Path and typin:
You are now finished with the Project Settings dialog box.
1. Add the following line to geomview.h:
2. In the code for CGeomviewApp::InitInstance, add the following line, just before the final return statement. Note full path name. Change this path if you use the Release build in VC++.
OMmain_init(m_hInstance, m_hPrevInstance, "c:\\geomview\\Debug\\geomview -novcp",SW_SHOWNORMAL);
3. In the code for CGeomviewApp::ExitInstance, add the following line.
4. Add the following public class method to CGeomviewCtrl:
5. Add the following protected class members to CGeomviewCtrl:
6. Using ClassWizard, add functions for the following messages
7. Add the following code to CGeomviewCtrl's constructor:
8. Add the following code to CGeomviewCtrl::OnDraw:
9. Add the following code to CGeomviewCtrl::OnCreate:
10. Add the following code to CGeomviewCtrl::OnDestroy:
11. Add the following code to CGeomviewCtrl::OnLButtonDown:
12. Add the following code to CGeomviewCtrl::OnLButtonUp:
13. Add the following code to CGeomviewCtrl::OnMouseMove:
* Add the following code to CGeomviewCtrl::OnSize:
14. Build and execute the project.
The ActiveX Control (OCX) is registered as part of the build process.
You can test the OCX in the MSDEV ActiveX test container located in the Tools menu. The most likely place of error is at CGeomviewApp::InitInstance where OMmainInit is called. If the test container seems to hang, comment out the call to OMmainInit and rebuild and reregister. You should then get an empty control with the appropriate error messages. Make sure the avsenv file has correct pathways and the OMmainInit function has a valid path.
You are now finished with VC++ and MSDEV.
To use it in Visual Basic, startup Visual Basic, select the OLE icon from the toolbar and use the mouse to create the container framework in the default "Form1" and then choose Geomview Control from the list box of available controls.
To use it in MS Internet Explorer, download the MS ActiveX Control Pad from Microsoft (if you don't already have it) and follow directions for inserting an ActiveX control into an html document.
You can rotate, scale, or XY-translate the geometry using the left mouse button. To scale, hold the Shift key down while dragging. To translate, hold the Ctrl key down while dragging.
The following section will describe how you can go about adding properties to your control. These will be visible when you use the control in VC++ or VB (or any other programming environment that will accept ActiveX controls.
Example : Color of DataObject (Scalar property)
Properties are added to controls using ClassWizard. Start it up from View->ClassWizard and then click on the Automation tab, making sure that CGeomviewCtrl is showing in the Class name box. Press the Add Property .. button to bring up the property dialog, and fill it in as described.
The External name of the property will be RedLight, and containers such as Visual Basic and Internet Explorer will use this when they want to manipulate it. The property will be of type BOOL, which we have chosen from the Type drop-down list that contains all the permissible types. A protected member variable called m_redLight will represent the property in the CGeomViewCtrl class. Choose the property implemented in your C++ code as a Member variable of the class.
Press OK to dismiss the ClassWizard, and go to the control class to look at the code. If you look in the header file, CGeomviewCtl.h, you'll find that Class Wizard has added declarations for the property variable and notification function.
To ensure that the property is initialized correctly (redLight will be FALSE by default). So add line m_redLight = FALSE to the constructor :
We can now use the property page object that we were given by the ClassWizard to allow users to modify the values of the properties at design time. The property page is already associated with the control, but at present it does nothing. You can see the property page by placing the Geomview Control in the Test Container, and then selecting the Edit | Properties... menu.
At the moment, the property page only contains the test string "TODO: Place controls to manipulate properties of Geomview control on this dialog". To fix this, open up the project's resources and find the property page dialog resource, which will be called IDD_PROPPAGE_GEOMVIEW. When you open it, you'll see that it is blank apart from the test string, which you can delete.
Add the checkbox to represent the property, as follows:
Drag and drop a check box. Go to checkbox properties and specify the id as IDC_RED_LIGHT
Give the checkbox suitable labels, and place it on the dialog.
Use ClassWizard to associate variables with the controls on the page. Select the CgeomviewPropPage class, and click on the Member Variables tab. Highlight the IDC_RED_LIGHT ID, and press Add Variable ... to open the following dialog. Type in the values as below.
The member variable in the property page class will be called m_bRedLight, of type Bool.
If you go and look at the code in the property page class, you'll see that the DoDataExchange () function now contains code to transfer data.
Add the below handler code to OnRedLightChanged method.
The above code adds red light to the teapot. Build the control and test it in the Test Container. If you select the red light check box , the Apply button will become enabled. Pressing this will add the red light property to the control.
![]() |
![]() |
![]() |
![]() |