![]() |
![]() |
![]() |
![]() |
10 Projects and Processes
This chapter describes AVS/Express projects and processes. It includes the following sections:
- Overview
- Projects and Processes
- AVS/Express Code Generation
- Projects
- Integrating with a Microsoft Foundation Class (MFC) Application
- Creating ActiveX Controls using AVS/Express C++ Classes using VC ++
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:
- Libraries are collections of template objects that are available to you for building applications.
- User code includes any user written C/C++ or Fortran code needed by objects (modules) in the process.
- Processes include the main (express) executable process, any external processes (notably the user process), and an internal bootstrap process called base. You can create additional processes as necessary (see the next section, Creating and Compiling Projects, for details).
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.
- A distinct project is a copy of the parent project that defines itself as being like the parent project at the time of its (the new project's) creation. A distinct project inherits from any projects from which the parent project inherits, but inherits from the parent project only at the time of creation.
- A derived project is a copy of the parent project and therefore inherits from the parent project. A derived project is like the parent project in its current state, but changes in the new project override files inherited from the parent.
By creating derived projects, you can build a project hierarchy that is a chain of projects; for example, Project A is a derivative of Project B, which in turn is a derivative of Project C, and so forth.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:
- To specify that the process attaches to a main process, define these environment variables before the process is initialized (see Initializing AVS/Express on page 10-8) with the appropriate values.
- To specify that the process is the main process, leave them unset. On initialization, the process becomes the main process and then defines the environment variables for itself.
You can define these environment variables in several ways:
- For the main process, use the following command-line option, which writes the environment variable definitions to the specified file:
- For a client process, use the following option, which loads the definitions from the specified file:
- This option loads the definitions.
- Use the getenv function from anywhere within the main process to retrieve the values of these variables, then set the definitions manually in the environment of the client process.
Each AVS/Express process has the following components:
- Definitions of the modules that it contains, if any
- Its process name
- An initialization call
- An event handler
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:
- Perform any process-specific initialization required by the objects in this process; for example, initializing the widget toolkit for the UI objects
- Set the name of the process
- Build a table that maps method names to the method pointers using the OMadd_named_func routine
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:
- Set the the c_hdr_files or cxx_hdr_files property to specify a header file that declares these functions.
- Set the hdr_code property to declare the functions. This property specifies a C statement that is inserted into the value of the current out_hdr_file property (by default, process_name.h).
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:
- Instruct AVS/Express to omit these libraries from the link line by setting no_main=1 on an object in your process.
- Specify the file that defines your main process using the c_src_files, cxx_src_files, or link_files properties.
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:
1. Place a call to the function EVXinit_display_xt() for each Display used in your program. This function is declared as follows:
- To include a definition of this function in your main, include the header file avs/event_x.h in your program as follows:
- You must place this call after you open the display but before you enter the event dispatch loop of your program; that is, before you call XtAppMainLoop, XtAppNextEvent or XtAppProcessEvent.
2. Define your own main loop, bypassing the AVS/Express main loop. Doing this prevents you from using the V Command Processor (VCP) from within this process. However, you can start up the VCP in another process that manipulates objects in the current process as follows:
- The VCP available in the shell started by the base command can manipulate objects in your express process.
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.
1. Save the example source code at the end of this section (see Example Source Code) into your project directory in a file called xtmain.cxx.
3. Select the Workspace_1 object (or any library that defines objects for the express process) for dummy.v.
The resulting express process uses the xtmain.cxx file as its main program.
---- xtmain.cxx:
#include <stdlib.h>
#include <avs/om.h>
#include <avs/event_x.h>
#include <X11/Intrinsic.h>
void
main (int argc, char **argv)
{
int vcp;
OMobj_id shell_id, widget_id, macro;
Widget widget;
vcp = OMmain_init(argc, argv);
OMpush_ctx(OMroot_obj,0,0,0);
macro = OMcreate_obj_from_path("macro", "my_macro", OMinst_obj);
shell_id = OMcreate_obj_from_path("UIshell", "xt_shell", macro);
OMset_name_int_val(shell_id, OMstr_to_name("visible"), 0);
OMpop_ctx(OMroot_obj);
widget_id= OMfind_str_subobj(shell_id,"handle.widget",OM_OBJ_RD);
if (OMget_ptr_val(widget_id, (void **)&widget, 0) != 1)
widget = NULL;
if (widget == NULL) {
fprintf(stderr,"can't get widget\n");
exit(-1);
}
EVXinit_display_xt(XtDisplay(widget));
XtAppMainLoop(XtWidgetToApplicationContext(widget));
OMexit(0);
}
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.
- The process that issues this call exits using the exit system call with the status code provided as the first argument.
- To make a specific process exit, call the C API routine OMprocess_exit (or C++ equivalent), as follows:
- The process specified by the proc_id argument exits with the status specified by the status argument. This call is most useful when you want an external process to make the main process exit. Note that the process ID of the main process is always 0.
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.
1. If the process property is set on the object itself or the template object from which it was created, the object is placed in the specified process.
2. If the process property is set on an ancestor of the object, the object is placed in the specified process.
3. If the process is set on an ancestor of a template object from which the object was created, the object is placed in the specified 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:
- The process that previously contained the object has a stale copy of the code for that object, which should be removed.
- More importantly, the process that now contains the object needs its definition.
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:
- In your project's templ.v file in the build_cmd property
- In the environment of the shell under which AVS/Express is running
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:
- AVS/Express creates the makefile by navigating all branches of the object hierarchy under Templates, except where it finds the compile_subs=0 property, looking for objects that are part of the process being compiled. The makefile is called process_name.mk. If a file by this name already exists in your project directory, AVS/Express removes it and creates a new one.
- While creating the makefile, AVS/Express sends informational and error messages, if any, to the startup window (in which the V Command Processor appears).
2. Generate the files process_name.c, xprocessname.cxx and process_name.h and place them in your project directory.
3. If a method's source file does not exist and the method specifies the src_file property, generate template source files.
- See Writing Target Functions on page 8-15 for details.
- See Introduction on page 9-2 for details.
- When AVS/Express runs make on the makefile, it pops up a window in which to display any compile-time messages.
6. If the make is successful, place the resulting executable in a machine-specific subdirectory of your project's bin directory.
7. On Windows platforms, AVS/Express creates .dsp and .dsw files for use by Microsoft Developer Studio. These files can be used to recompile or debug the project.
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:
1. Run Project->Compile. As for a single nonexpress process, AVS/Express prepares a makefile named express.mk for the express process and places it in your project directory. However, because the express process is running, it does not run a make on the makefile. On Windows, AVS/Express also creates Microsoft Developer Studio project files express.dsp and express.dsw.
Run make on the express makefile by entering the following (On Windows):
6. On Windows you can also compile (and debug) by using the Microsoft Developer Studio project files.
- Note: Once the express process compiles, be sure to run the express process that you just compiled rather than the express process in the AVS/Express install directory.
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:
- This message means that AVS/Express has created the makefile for this process, but cannot run a make on it because the specified process is currently executing. AVS/Express typically returns this message in the following circumstances:
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 message, from the linker, indicates that a required function is missing.
- If the undefined function belongs to an object that you added, this message may mean that you did not set a c_src_files (or similar) property.
- If the undefined function belongs to an object in one of AVS/Express' kits, your objects may have a dependency that you did not account for by setting the libdeps property.
- See Providing Code Management Information on page 8-28.
- You are compiling a function that receives pointers to a C structure that you have defined and to a bitmask structure generated by AVS/Express. The generated file includes the header file where your C structure is defined, so you do not have to include it again in the function's source file.
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.
- During the code generation stage, AVS/Express generates the code and makefile needed to build the process. To do this, AVS/Express makes two passes through the Templates hierarchy:
- During the process build state, AVS/Express simply invokes your system's make command for the generated makefile.
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 affects how AVS/Express handles library dependencies.
- The need_objs property affects how AVS/Express handles dynamic object dependencies.
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.
- AVS/Express inserts initialization code, which is executed when the process is started, into the function BASEinit. This function is put into the file process_name.c if the file contains only C definitions, or the file process_name.cxx if it contains any C++ definitions.
- By default, AVS/Express also places all source definitions into the file process_name.c or process_name.cxx, as appropriate. You can modify this default by setting the out_src_file property.
- By default, AVS/Express puts all header definitions into the file process_name.h. You can modify this default by setting the out_hdr_file property.
- AVS/Express puts generated code for the process makefile into the file process_name.mk.
- On Windows, AVS/Express generates the Microsoft Developer Studio files process_name.dsw and process_name.dsp.
In Pass 2, AVS/Express generates code for objects marked as needed during Pass 1; specifically:
- Methods marked as needed. This code includes:
- Code Management Properties set on any objects that are marked as needed. The following properties affect what code is generated:
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:
- A project that completely replaces the install area project
- A project that includes only a small subset of the install area project's libraries
- A project with a completely different appearance in the Network Editor
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:
- an avsenv file
- makefiles
- project-level source files
- project-level header files
- data directories
- source-code directories
- object-file directories
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:
# WARNING: this file is program generated.
# Remove these two lines to protect the file from overwrites.
XP_PATH=/home/users/me/proj1 /home/express
- The first two lines identify the file as an AVS/Express-generated avsenv file rather than a user-supplied file. Whenever the associated project is saved, AVS/Express regenerates this file if it finds these two lines.
- The next line assigns a value to the XP_PATH environment variable.
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:
- The directory specified by the -project command-line option, if any.
- The current directory.
- (UNIX systems only) Your home directory.
- The directory two levels above the directory that contains the AVS/Express executable. For example, if the executable is in the directory /home/express/bin/hp, AVS/Express looks in the directory /home/express.
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:
"$XP_PATH<0>/v/templ.v" Templates {
flibrary MYLIB {
module my_module {
int p1;
omethod+notify+read update = "my_module_update";
};
};
};
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.
- The libs.v file includes files that define the libraries as they appear in the Network Editor.
- The lib_xp.v file describes the AVS/Express Network Editor layout. It is simply a set of NElink objects and libraries of NElink objects, one for each major library collection.
For more information on libraries, see Understanding Libraries on page 5-11
- Note: The information in this section is relevant only to Developer Edition users. Visualization Edition users cannot use the Save Compiled Project command.
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:
- The compiled project is streamlined by the elimination of code associated with objects that it does not use.
- All of the V state information for the compiled project is stored in a single binary V file, reducing application startup time and the number of files required to support the project.
You should consider streamlining a project with Save Compiled Project in the following circumstances:
- When you deploy an application built entirely from AVS/Express components
- When you deploy an application built from code that creates AVS/Express components dynamically
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:
- Project directory selection controls: a text box and Browse button combination
- Object selection controls: a set of radio buttons
- Option controls: a set of check boxes
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:
- Save selected objects. In this mode, the core set of objects to be included in the compiled project consists of all currently selected objects.
- Save current application. In this mode, the core set of objects includes only the current application object.
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:
- If you include a macro object, AVS/Express also includes all objects that the macro uses.
- If you include a library object, AVS/Express also includes all objects in that library.
The operation selection controls specify a number of operations that the command can perform when it executes. These operations are as follows:
- This option controls whether or not AVS/Express automatically instances the objects selected for the compiled project operation when it starts up the main (express) process.
- Check it if you are using AVS/Express to generate a compiled project from a single object that contains the entire definition of the object.
- Uncheck it if your program dynamically creates the AVS/Express objects itself, or the objects you selected are libraries (it does not make sense to instance a library of objects).
- This option controls whether the Network Editor is a part of the compiled project.
- If you include the Network Editor, it is instanced when the main (express) process of your project is executed, just as in a normal AVS/Express session. As usual, the default creation of the Network Editor can be disabled with the -none command line option.
- Since your project will contain only a compilation of system objects, the organization of the Libraries object in the Network Editor must also display a subset of the objects in the system. The current version of AVS/Express does not perform a subset operation on the existing Libraries organization for you. Instead, it creates a default v/libs.v file that displays the contents of the Templates object only. This display lists all of the libraries that are included in AVS/Express but in a very raw form. In order to get a better libraries organization, you must create your own customized v/libs.v file.
- As noted previously, the Save Compiled Project command generates a single binary V file that contains the definitions of all objects needed to implement the selected set of objects. This option controls whether the V definitions are stored in a separate binary V file that is loaded when the main (express) process is started or the binary V file is directly linked into the executable of the main process.
- Check it to link the binary V file linked into the executable of the main process.
- Uncheck it to store the V definitions in a separate binary V file that is loaded when the main process is started.
- If you select this option (that is, link the binary V file into the executable), you can produce a single standalone executable file with which to deploy the application. Note, however, that any runtime files needed by any objects that the compiled project uses are still required; for example, the runtime files that are required to use the Network Editor in an application.
- There are some drawbacks to selecting this option:
- Linking the binary V file into the executable takes longer than storing it in a separate file.
- You must always relink the executable if you change the project. With a separate binary V file, you can make changes to the project that require only updating the binary V file rather than relinking and rebuilding the project.
- This option controls the building of the project's exexcutable. This is on as a default.
- This option automaticaly generates wrapper code for the project. This is on as a default.
- If you attempt to overwrite an existing project, you are informed of this fact and given the option to cancel.
- If you attempt to overwrite a project that is currently in use by this session, you are prevented from doing so (since the compiled project references these projects and thus will not work).
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:
- A machine-specific subdirectory of this directory contains the object files compiled for this project. None of the files in this subdirectory tree are necessary to run an application built with this project. On UNIX machines, you can obtain the value of the $MACHINE variable for a particular platform by running the xp_mach shell script. On Windows machines, this value is always pc.
- This file, generated if you compiled the project with the Build V into executable option turned off, contains the V definitions for the compiled project. It is required for running applications built from the project, and must be located in the v subdirectory of XP_PATH when you run the project.
- See Build V definition into executable on page 10-33.
- This file is generated if you compiled the project with the Include network editor in project option turned on. The file is a simple prototype that you can replace by a custom version.
- See Include network editor in project on page 10-32.
- A machine-specific subdirectory of this directory contains contains all of the process executables necessary to run this project. On UNIX machines, you can obtain the value of the $MACHINE variable for a particular platform by running the xp_mach shell script. On Windows machines, this value is always pc.
- These files are generated for each process used by the compiled project. They are necessary only for compiling the project, not for running applications built with it.
- This file stores the value of the XP_PATH variable used to construct the project. It is necessary for compiling the project and is necessary to run the project if any of the components it uses rely on any files stored relative to XP_PATH.
- This source file, generated if you compiled the project with the Build V into executable option turned on, contains a hexadecimal description of the binary V description for the objects used by the project. It is necessary for compiling the project but not for running it.
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:
3. Select the Save current application option: the current application is the only object you need in the compiled project.
4. Deselect the Include network editor in project option: the user of this application will not be editing it.
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:
6. Select the Save selected objects option: you want to save the objects you have selected in the compiled project.
7. Deselect the Include network editor in project option: the user of this application will not be editing it.
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:
- Notice that the border around the various sublibraries is highlighted.
a. When the dialog box is displayed, disable the Annotation and Graphing Kit, the Print Renderer, the VRML Renderer, and the VPS Renderer.
6. Drag the scrollbar at the bottom of the Libraries.Templates object all the way to the right, so the GEOMVIEW object becomes visible.
![]()
- Instance objects automatically on restore
Build project's executable9. After the compiled project has been generated, exit from AVS/Express and start Microsoft Developer Studio.
The following steps are performed using Microsoft Developer Studio.
2. The New Project Workspace dialog box appears. Select the Projects tab if it is not already selected.
- Note: This tutorial assumes that the project is called "geomview". If you choose a different name, you will need to make the necessary adjustments as you complete the steps.
- The MFC AppWizard appears.
6. Click Next on pages 1, 2, and 3 of the MFC AppWizard, since you will be using the default settings for these steps.
- After you are done with the MFC AppWizard, the project directory will be created.
11. Copy the following files to the MFC AppWizard-created geomview 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 geomview project directory; there is no need to create a v subdirectory.
12. Optionally, use a text editor to examine the file express.dsp from the compiled project directory.
- Examine the file looking for lines that start with:
- #ADD LINK32_OBJS
- The libraries and files listed on these lines should match the list of files you will be specifying later when you change your project settings.
13. In your geomview project directory, create a file called avsenv, and enter the information for setting the XP_PATH variable so that it indicates the name of your project directory.
- For example, if your project directory is c:\projects\geomview, your avsenv file should contain the following line:
- Note: The instructions below assume that AVS/Express is installed in C:\express. Be sure to substitute the appropriate installation directory when assigning your project settings.
1. Select Project->Settings to display the Project Settings dialog box. In the "Settings for:" list box on the left side of the dialog, make sure "All Configurations" is selected.
a. In the "General" category, add the preprocessor definition MSDOS to the end of the list of existing definitions.
c. In the "Preprocessor" category, add the following entries to the "Additional include directories:" text field:
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 express.lib wsock32.lib
- Note: This needs to be entered as one long line in the typein window.
a. In the "Settings for:" list box on the left side of the dialog box, change the selection so that only the Debug version of the project is selected.
You are now finished with the Project Settings dialog box.
2. Add the following line immediately before the final return statement in the code for CGeomviewApp::InitInstance in geomview.cpp:
5. Using the ClassWizard (View->ClassWizard), add the OnOpenDocument and OnCloseDocument messages to the CGeomviewDoc class.
m_reader = new CGeomFileReader;
m_reader->push_ctx();
m_reader->filename = lpszPathName;
m_reader->pop_ctx();
10. Using ClassWizard, add the OnInitialUpdate, PostNcDestroy, WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP, and WM_SIZE messages to the CGeomviewView class.
CGeomviewDoc *pDoc = GetDocument();
CGeomFileReader *reader = pDoc->GetReader();
if (!reader) return;
m_viewer = new C3DViewer;
if (OMadd_obj_ref((OMobj_id) m_viewer->objs,
(OMobj_id) reader->obj, 0) != OM_STAT_SUCCESS) {
return;
}
m_viewer->push_ctx();
m_viewer->window = (int) GetSafeHwnd();
m_viewer->widget = (int) GetSafeHwnd();
m_viewer->hdc = 0;
m_viewer->event = 1;
m_viewer->pop_ctx();
- The program starts up with an initial empty view window.
2. To display some data, select File->Open and input an AVS geometry file (e.g. c:\express\data\geom\teapot.geo).
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.
- 1. In the "General" category, add the preprocessor definition MSDOS to the end of the list of existing definitions.
- 2. In the "Precompiled Headers" category, select the "Not using precompiled headers" toggle.
- 3. In the "Preprocessor" category, add the following entries to the "Additional include directories:" text field:
- $(XP_ROOT)\include,$(XP_ROOT)
- (This, of course, assumes that you have the environment variable XP_ROOT set. Be sure to set this.)
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:
..,.,$(XP_ROOT)\lib\pc,$(XP_ROOT)\lib\pc\pal,$(XP_ROOT)\lib\pc\fld,$(XP_ROOT)\lib\pc\nt_ui,$(XP_ROOT)\lib\pc\gmod,$(XP_ROOT)\lib\pc\ip_lib\inter,$(XP_ROOT)\lib\pc\ne,$(XP_ROOT)\lib\pc\om,$(XP_ROOT)\lib\pc\ag,$(XP_ROOT)\lib\pc\animator
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
- 1. WM_DESTROY,
- 2. WM_CREATE,
- 3. WM_LBUTTONDOWN,
- 4. WM_MOUSEMOVE,
- 5. WM_LBUTTONUP, and
- 6. WM_SIZE.
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.
![]() |
![]() |
![]() |
![]() |