**************************
DEVELOPERS README.TXT FILE
**************************
This ReadMe file lists the locations of the developer-related files installed with Visio Technical. It also contains programming notes related to working with Visio Technical.

Tip: If necessary, choose Word Wrap from the Notepad Edit menu to wrap the text within the document window.

-----------------------------------
LOCATING PROGRAMMING-RELATED FILES
-----------------------------------
The following directories contain programming-related information and sample files:

*   C and C++ samples are stored in the C-CPP directory in the Visio Add-ons directory.  For more information, see "Programming with C or C++" later in this file.

*  Attribute example code is stored in the Sample directory of the Visio Add-ons directory.

*  A header file for programming the Attributes and Extended Entity Data through C and C++ is stored in the Utils directory of the Visio Add-ons directory.


------------------------------------------------
PROGRAMMING VISIO AND THE PROGRAMMING VISIO DISK
-------------------------------------------------
In Programming Visio, references to menu names and commands and the illustrations of the user interface are for Visio 2.0.

Visio 3.0 (Visio Technical) includes several new OLE Automation terms, including the Characters object, which you can use in a program to control and format the text in a shape or to insert a field in a shape. For a list of the properties and methods related to the Characters object, see the programming language reference online help.

New properties and methods in Visio 3.0 include:

Export
Import
Help
Parent
InPlace
Language
OnDataChangeDelay
Units

For complete information about the Characters object and other new methods and properties, see the programming language reference online help.

The Programming Visio disk, which contains sample code and Visual Basic applications, also includes an older copy of the programming language reference online help. For the most recent information about the objects, methods, and properties you can use to control Visio, use the version of progref.hlp that comes on the Visio Technical disks.


--------------------------------------------------------------
USING VISUAL BASIC'S OLE AUTOMATION FEATURES TO CONTROL VISIO
--------------------------------------------------------------
The following information describes workarounds for problems we have found using the OLE Automation features of Visual Basic.

1. Don't use complex expressions as parameters to methods. If you chain several methods together in an expression and then pass that expression as the parameter to another method call, Visual Basic allocates temporary storage for the expression and never releases it. If you do this enough times, Visual Basic eventually crashes. For example, the following code causes an Application Error in Visual Basic:

	Dim visio As Object	' Visio application object
	Dim wins As Object	' Window collection

	Set visio = GetObject( , "visio.application")
	Set wins = visio.Windows
	For i = 1 To 1000
		k = wins.Item(wins.Count).Index
	Next

To work around the problem, replace the body of the loop with:

	For i = 1 To 1000
		cnt = wins.Count
		k = wins.Item(cnt).Index
	Next

2. You must use square brackets around the method names that conflict with Visual Basic keywords:

	Arrange
	Close
	Delete
	Print

For example,

	visio.Windows.[Arrange]

If you don't use square brackets, Visual Basic displays the following message:

	"Method not applicable for this object"

3. Visio generates unique run-time error codes for different types of OLE Automation errors. Visual Basic, however, ignores these error codes and converts them all to a generic OLE Automation error--Error 440. This is a Visual Basic 3.0 issue that should be resolved in the next release.

4. Be careful when using default properties. Visual Basic calls the default property for an object even after an exception has occurred. This generally results in an Application Error in OLEDISP.DLL. For example, in some circumstances the following statement generates an Application Error:

	Set page = doc.Pages(1)

In this example, Item is the default property for collections. If calling the Pages method generates an exception for whatever reason, the previous statement will cause an Application Error.

To work around the problem, replace the previous statement with:

	Set page = doc.Pages.Item(1)


--------------------------
PROGRAMMING WITH C AND C++
---------------------------
Before attempting to program Visio through OLE Automation using either C or C++ you must have a C or C++ compiler, the Windows 3.1 or greater SDK as well as the OLE 2.0 libraries and header files.  Furthermore, it is assumed that the reader is familiar with both of these programming languages as well as the Windows 3.1/OLE 2 APIs.  We have included MAK/IDE files for the Microsoft Visual C++ and Borland compilers.

For information on Visio's different interfaces and their properties and methods please refer to the Programming Language Reference help file (PROGREF.HLP) included with Visio.  It should be located in the same directory as Visio if you chose to install it during setup.


Table of contents
-----------------
  I.  Example Code/Basics
 II.  Includes
III.  Support Interface
 IV.  IVISREG
  V.  VSLs - Visio Libraries


I. Example Code/Basics
----------------------
This directory contains example code written in C AND C++ for driving Visio through OLE Automation as either an EXE or a VSL.  VSLs are a special type of DLL and are discussed in detail below.  4 MAK files and 4 IDE files are provided for building each sample.  To compile using Microsoft's NMAKE do the following:

1 ) Make sure you are in the directory containing the example code.
2 ) To produce a C EXE   : nmake /a /f cexe.mak
    To produce a C VSL   : nmake /a /f cvsl.mak
    To produce a C++ EXE : nmake /a /f cppexe.mak
    To produce a C++ VSL : nmake /a /f cppvsl.mak

To build a project under Borland C/C++ load the IDE file representing the flavor of build you want.  They are:

	To build a C EXE   : CEXE.IDE
	To build a C VSL   : CVSL.IDE
	To build a C++ EXE : CPPEXE.IDE
	To build a C++ VSL : CPPVSL.IDE

You may notice that there are four different MAKs and IDEs.  That's because we provide an example in both C and C++ that compiles as both an EXE and a VSL.  What's the difference between and EXE and a VSL? First of all, an EXE is a standard Windows EXE.  A VSL, however, is just a standard Windows DLL with a special function called VisioLibMain that Visio calls directly.  Therefore, add-ons written as EXEs or VSLs are subject to the same limitations that Windows EXEs and DLLs are subject to.  Please see the Window's SDK for information about programming EXEs and DLLs.

The real advantage of a VSL is that it is faster because it runs inside Visio's task space.  EXEs will run slower because they incur OLE 2.0's LRPC interface when talking to Visio.  We recommend that you develop your larger Visio add-ons in C/C++ as EXEs, and smaller, quick running add-ons as VSLs. VSLs are discussed in more detail later.

To control Visio under C/C++ through OLE Automation, you must include the file IVISAUTO.H in your program.  This file includes two other files, all of which are described below:

IVISAUTO.H
	This file contains the interface declaration for Visio's IAutoSupport interface.  Don't worry to much about this file because we supply a special file called IVISREG that takes care of the special work associated with the IAutoSupport interface.

IVISPROX.H
	When you need to find a property or a method of a particular Visio "object," this is where you look.  This file contains all the Visio interface definitions.  It also contains standard OLE interfaces for every "object" that is documented in Visio's PROGREF.HLP.  Interfaces begin with the directive:

	DECLARE_INTERFACE_(IVisioApplication , IUnknown)

	The interface is declared for the Application object as discussed in PROGREF.HLP.  Every property and method is declared with the STDMETHOD macro.  This macro dictates that every property and method return an HRESULT.  Look in the example code to see how this HRESULT is used.

VISCONST.H
	This file contains constants that PROGREF.HLP will make reference to.  It is automatically included by IVISAUTO.H.  Whenever you see a constant such as visDrawing or visSheet you can reference this file.

The following table shows what files are required for each flavor of add-on you want to build from our sample code.  Please feel free to use these files as a starting point for your own add-ons by copying them to another directory and adding on to them.

C EXE         C++ EXE	
--------------------------
CEXE.MAK/IDE  CPPEXE.MAK/IDE
MAIN.C        MAIN.C          
GENERIC.C     GENERIC.CPP
IVISREG.C     IVISREG.CPP
GENERIC.RC    GENERIC.RC
GENERIC.ICO   GENERIC.ICO
RESOURCE.H    RESOURCE.H
IVISREG.H     IVISREG.H
IVISAUTO.H    IVISAUTO.H
IVISPROX.H    IVISPROX.H
VISCONST.H    VISCONST.H
EXE.DEF       EXE.DEF

C VSL         C++ VSL	
--------------------------
CVSL.MAK/IDE  CPPVSL.MAK/IDE
LIB.C         LIB.C
VAO.C         VAO.C
GENERIC.C     GENERIC.CPP
IVISREG.C     IVISREG.CPP
GENERIC.RC    GENERIC.RC
GENERIC.ICO   GENERIC.ICO
RESOURCE.H    RESOURCE.H
VAO.H         VAO.H
IVISREG.H     IVISREG.H
IVISAUTO.H    IVISAUTO.H
IVISPROX.H    IVISPROX.H
VISCONST.H    VISCONST.H
VSL.DEF       VSL.DEF

Bear in mind that these examples may share source files, so changing one affects the others.  For instance, IVISAUTO.H is included by every project. By changing it you will affect all the projects.  You will need to have the standard OLE 2.0 and Windows headers accessible to your compiler.  For more information on how these examples work, read the source code provided as they contain many comments that should help you through the code.  Programmers who have already used Visio through OLE Automation under Visual Basic will probably understand the result of the example code.  Although we have tried to make it as easy as possible to control Visio from C and C++ you may have to refer to the OLE 2.0 API for more information on how OLE works from C or C++.


II. Includes
------------
When building an add-on you must #include IVISAUTO.H to get the Visio interface declarations.  This file then includes IVISPROX.H and VISCONST.H. These provide the OLE interfaces for driving Visio through automation.  However, these files also require some Windows headers, so make sure that you have at least the following in each source that needs to control Visio:

	#include <windows.h>
	#include <ole2.h> 
	#include <dispatch.h>  

	#include "ivisauto.h"

If you are using a pre-compiled header, place the above #includes into it for better compilation times.  You do not need to include IVISPROX.H or VISCONST.H because IVISAUTO.H includes them automatically.

When building a VSL, you must also include the file VAO.H.  Because of the way our sample code is built, you'll notice that VAO.H is included seperately from the IVISAUTO.H include.  This is because the inner workings of the add-on code are separated from both the VSL and EXE support files, LIB.C and MAIN.C, respectively.  We recommend you do the same so that converting your add-ons to VSLs requires nothing more than recompiling.

III. Support Interface
----------------------
Throughout this file and the example code we will make reference to getting and creating Visio instances.  This corresponds to the act of getting the active instance of Visio, if one is running, and creating a new instance of Visio, regardless if one is running or not.  Please note the differences between these two acts and feel free to modify the example code to see the differences for real.  For Visual Basic users, getting the active Visio instance is the same as making a GetObject call, and creating an instance of Visio is the same as making a CreateObject call.

The first thing you must do to get Visio running is to retrieve the support interface.  The support interface has a special function called GetVisioObject that makes the job of Getting and Creating Visio instances much easier.  To get the support interface use the C code shown below:

	LPVAUTOSUPPORT     ipIVAS = NULL;
	LPVISIOAPPLICATION ipIVApp = NULL;
	CLSID clsid;
	IID   iid;
	SCODE sc;

	...

	CLSIDFromString( CLSID_VISIOAUTOPROXY, &clsid );
	IIDFromString( IID_VISIOAUTOSUPPORT, &iid );

	sc = GetScode(CoCreateInstance(&clsid,
	                               NULL,
	                               CLSCTX_INPROC,
	                               &iid,
	                               (LPVOID FAR *)&ipIVAS ));

	if ( !ipIVAS )
		goto CleanUp;

	ipIVAS->lpVtbl->GetVisioObject(ipIVAS, FALSE, &ipIVApp);

	if ( !ipIVApp )
		goto CleanUp;

	...

CleanUp:
	if ( ipIVAS )
		ipIVAS->Release();
	if ( ipIVApp )
		ipIVApp->Release();

First, this sample creates an instance of the IAutoSupport interface using the OLE function CoCreateInstance.  If no interface pointer was returned it jumps to CleanUp.  Otherwise it attempts to retrieve a Visio instance through the GetVisioObject method of IAutoSupport.

The second parameter to GetVisioObject determines whether or not a Get or Create is performed.  In this example it is FALSE, so the function attempts to create a new instance of Visio; if it was TRUE then the function would attempt to retrieve the active instance.

To tell whether or not the call was successful (i.e. if a Visio instance was returned), this example checks to see if the Visio Application interface pointer it passed in, ipIVApp, is no longer NULL.  If it's not NULL then it's safe to go on; otherwise, go to CleanUp.  Fortunately we provide a library called IVISREG that takes care of this overhead.


IV. IVISREG
-----------
If you've programmed Visio through Visual Basic then you're probably familiar with the function vaoGetObject() provided by VISREG.BAS.  This file was first included with Visio 2.0 and provides useful functions for getting and creating instances of Visio.  The same file was rewritten for use with C and C++.  To use it, just add IVISREG.C or IVISREG.CPP to your project and insert #include "ivisreg.h" after your #include "ivisauto.h" directive.

IVISREG contains three very important functions, the prototypes of which are shown below:

	short vaoGetObject(LPVISIOAPPLICATION FAR *);
	short vaoGetVisio(BOOL,	BOOL, LPVISIOAPPLICATION FAR *);
	HRESULT vaoGetLastError();

Both functions return a VAO_ result code is defined in IVISREG.H.  The simplest is vaoGetObject. It takes the fewest parameters and does the most work.  If vaoGetObject returns VAO_SUCCESS, then its first parameter is a Visio application interface.  Otherwise, it couldn't get or create an instance of Visio and some error code will be returned. (See IVISREG.H for more information on the VAO_ error codes.)

vaoGetVisio does the same thing as vaoGetObject, but you have more control over how it works.  The first parameter determines whether vaoGetVisio should try to get the active Visio instance. The second parameter determines whether vaoGetVisio should try to create a new instance of Visio. If you passed TRUE in for both parameters, then vaoGetVisio first attempts to get the active instance of Visio and then, if one was running, return an Application interface pointer for it. Otherwise vaoGetVisio attempts to create a new instance of Visio and return an Application interface pointer for it. If either of these attempts succeeds then VAO_SUCCESS is returned, otherwise vaoGetVisio returns an error codes.

The following table shows the possible error codes returned from vaoGetVisio depending upon the first two parameters.  Each one is described below.

Get               Create                  Return Code(s)
----------------------------------------------------------------
TRUE  TRUE        VAO_GET                 Get Succeeded
                  VAO_CREATE              Create Succeeded
                  VAO_NOT_INSTALLED       Visio not installed
                  VAO_ERROR               General Error

TRUE FALSE        VAO_GET
                  VAO_NOT_RUNNING         Visio not running
                  VAO_ERROR

FALSE TRUE        VAO_CREATE
                  VAO_ERROR
                  VAO_NOT_INSTALLED

FALSE FALSE       VAO_ERROR

One last function that IVISREG supplies is vaoGetLastError.  If either vaoGetObject or vaoGetVisio returns an error code (i.e., something besides VAO_GET, VAO_CREATE or VAO_SUCCESS), then calling vaoGetLastError returns the HRESULT that OLE returned to IVISREG.  Use it to provide more detailed debugging information.


V. VSLs - Visio Libraries
-------------------------
VSLs are just DLLs that have a special entry point for Visio, namely VisioLibMain.  For Visio to recognize VSLs, they must have the extension VSL and reside in Visio's add-ons path.  See the make files CVSL.MAK and CPPVSL.MAK to find out how they build the DLL and rename it to a VSL.  The IDE files that build VSLs will not rename the DLLs to VSLs, so you will have to do that manually.  For more information on how to change Visio's add-ons path, consult your Using Visio manual.  Note that if you copy a VSL into Visio's add-ons directory while Visio is running, the VSL won't show up in Visio's Run Add-on dialog until you restart it.

To build a VSL you will need 5 files that are included here: IVISAUTO.H, IVISPROX.H, LIB.C, VAO.H and VAO.C.  First, create a new DLL project using your C/C++ development environment, be it Borland or Microsoft.  Then, make sure these five files are in the project's directory.  Add VAO.C and LIB.C to the project.  The core of a VSL is its VisioLibMain procedure.  Study LIB.C's VisioLibMain and the associated VAOREGSTRUCT to see how Add-ons are registered and run by Visio.  You'll notice that LIB.C is the hub of a VSL in that it tells Visio what add-ons are in your VSL and executes them when Visio sends it the V2LMSG_RUN message.  Below is a discussion of these three files.  Remember you still need to #include "ivisauto.h" as discussed earlier.

LIB.C
	LIB.C contains the VisioLibMain function.  It is already filled out for registering one add-on, the VSL Automation Demo.  Notice first the array VAOREGSTRUCT stc_myAddons[].  Each VSL may have multiple add-ons as defined by this structure.  Each element in the array defines an add-on by name and index.  When your VSL is first asked to register itself, the V2LMSG_ENUMADDONS message is sent, then you pass it this structure and the names of your add-ons are displayed in the Run Add-On dialog in Visio.  Secondly, you must specify a unique index for each of your add-ons.  This is because Visio, when sending the V2LMSG_RUN message, indicates which add-on to run by its index in the VAOREGSTRUCT you passed to it earlier.  Other messages are handled by the VAOUtil_DefVisMainProc function in VAO.C.

VAO.H
	VAO.H contains all of the function prototypes, constants and structure definitions needed to run as a VSL.

VAO.C
	VAO.C contains the supporting functions for running as a VSL. Most important, it contains the LibMain and WEP functions for your VSL.  If you need to do any per DLL initialization or clean-up, you will need to modify these functions.

One important thing to remember is that VSLs are DLLs; thus, you are limited in the 16-bit world to one data segment.  Because of this you must make sure that every entry point for your DLL is not only prefixed with the CALLBACK macro but a __loadds declarator.  If you fail to place the __loadds before callbacks your DS will equal SS and errors will occur.  We recommend that you use the macro below.  Notice that you must define the symbol _DLL before using it.  The symbol VAOCB is also defined inside of VAO.H so we make sure not to redefine it.

	#ifdef _DLL && !defined(VAOCB)
	#define VAOCB __loadds CALLBACK
	#else
	#define VAOCB CALLBACK
	#endif

For example, your dialog procedures should be declared as follows:

	BOOL VAOCB MyDialogProc(HWND, UINT, WPARAM, LPARAM);


*****************
End of ReadMe.txt
*****************
