/*	VAO.H - Visio 3.0 VSL Interface
 *	Copyright (C) 1992-1994 Shapeware Corporation. All rights reserved.
 */
 

#if !defined(_VAO_H)
#define _VAO_H

#ifndef _INC_WINDOWS
#include <windows.h>
#endif

// The definitions in this file are intended to be "C" definitions. If
// included from C++, we don't want C++ name munging to occur. Ending
// brace for the "extern C" is at end of file.
//
#if defined(__cplusplus)
extern "C"
	{
#endif

#define PRIVATE		static
#define LOADDS		_loadds
#define F_CBKEY(type) 	type LOADDS PASCAL FAR		// portable form

// Prototypes below that are within "MACRO(proto)" are really implemented
// as C macros. The intent is that callers should treat them as if they are
// real functions as implied by the prototype.
//
#if !defined(MACRO)
	#define MACRO(proto)
#endif

#if !defined(VAOU_PROC)
	#define VAOU_PROC(type)	F_CBKEY(type)
#endif

#if !defined(VAOU_CPROC)
	#define VAOU_CPROC(type) type LOADDS CDECL FAR
#endif


// Even though definitions in this interface are "C" definitions, we want
// it to be possible to embed structures defined as part of the interface
// within C++ objects. Since structs are really classes in C++, it is
// required that C++ know whether the "this" of the struct is near or
// far. Any struct defined as part of this interface that is declared
// using VAO_EMBEDDABLE_STRUCT can be embedded within a FAR C++ instance
// as well as being used as an ordinary C structure.
//
#if !defined(VAO_EMBEDDABLE_STRUCT)
	#if defined(__cplusplus)
		#define VAO_EMBEDDABLE_STRUCT typedef struct FAR
	#else
		#define VAO_EMBEDDABLE_STRUCT typedef struct
	#endif
#endif

#define VAO_IFMAJOR ((WORD)2)		// Major interface version number.
#define VAO_IFMINOR ((WORD)2)		// Minor interface version number.

//---------------------------------------------------------------------------
//
//	EXPECTED ADD-ON LIBRARY ENTRY POINT
//	-----------------------------------
//
//	An Add-on library is expected to have an exported entry point of type
//	VAOFUNC whose name is LPVAOENTRYNAME. When Visio loads an Add-on library
//	it determines the address of the library's entry point by calling
//	GetProcAddress() on this name.
//
//---------------------------------------------------------------------------

#define LPVAOENTRYNAME ((LPSTR)"VisioLibMain")


typedef WORD VAORC, FAR* LPVAORC;
typedef WORD VAOMSG, FAR* LPVAOMSG; // A Visio Add-on Message code.

#define VAOCB LOADDS PASCAL FAR

typedef VAORC (VAOCB VAOFUNC) (VAOMSG,WORD,LPVOID);

typedef VAOFUNC *LPVAOFUNC;


// VAOV2LSTRUCT - Call back info passed by Visio to lib.
// ------------
//
// A VAOV2LSTRUCT also has a lpCmdLineArgs field that passes a string supplied
// by the invoker of the session. This is analogous to the "command line
// argument" string passed by Visio to an executable file when it WinExec's
// such a file (e.g. when it WinExec's a compiled EXE file in it's add-ons
// directory). The recipient of the VAOV2LSTRUCT can parse this line if so 
// inclined.  It should never assume non-null string will be passed, and it
// should expect that the passed string can be arbitrary, and it should behave
// reasonably regardless of the string value passed to it.
//
VAO_EMBEDDABLE_STRUCT
	{
	HINSTANCE	hVisInst;			// Handle to running Visio instance.
	LPVAOFUNC	lpfunc; 			// 
	WORD		wSessID;			// 

	LPVOID		lpArgs; 			// Pointer to session arguments.
									// Currently always null.
									
	// Above fields were present in Visio 2.0 and Visio Express. Below 
	// fields weren't. Don't dereference below here if Visio interface 
	// version is <= 2.2. Visio passes interface version with V2LMSG_LOAD.
									
	LPSTR		lpCmdLineArgs;		// Analog of "cmd line args" passed to
									// an exe when it gets WinExec'd. 
									// Recipient shouldn't assume this is
									// non-null or depend on any particular
									// string to be passed to it.

	} VAOV2LSTRUCT, FAR* LPVAOV2LSTRUCT;

#define VAO_INV_SESSID ((WORD)0xFFFF)


// VAOREGSTRUCT - Add-on registration structure.
// ------------
//
// A library passes a pointer to a VAOREGSTRUCT as lparam when it sends
// Visio when it sends L2VMSG_REGADDON.
//
// A VAOREGSTRUCT describes an Add-on to Visio. In particular, it specifies:
//
//	- The Add-on's ordinal. When Visio tells the library to run an Add-on
//	  it identifies which Add-on by specifying the Add-on's ordinal.
//	- Several attributes of the Add-on.
//	- The enabling policy the Add-on wants to use.
//	- the name of the Add-on.
//

// VAO_ORDINAL: Specifies an add-on's ordinal.
//
typedef WORD VAO_ORDINAL, FAR* LPVAO_ORDINAL;

#define VAO_INV_ORD (0) 			// The ordinal no valid Add-on can have.
									// We choose 0 for invalid id because
									// resources having id's equal to
									// to VAO_ORDINAL are quite likely and
									// resid's of 0 aren't cool.


// VAO_ATTS: Specifies an add-on's attributes in the form of a mask of
// zero or more VAO_AOATTS_xxx values.
//
typedef WORD VAO_ATTS, FAR* LPVAO_ATTS;

#define VAO_AOATTS_ISACTION	0x0001	// Add-on performs actions.
#define VAO_AOATTS_HASABOUT	0x0002	// Add-on supplies an about for itself
#define VAO_AOATTS_HASHELP	0x0004	// Add-on supplies help about itself.
#define VAO_AOATTS_WAITCRSR 0x0008	// Keep wait cursor up when Add-on runs.


// VAO_ENABMASK: Specifies an add-on's enabling policy.
//
typedef WORD VAO_ENABMASK, FAR* LPVAO_ENABMASK;

#define VAO_ENABLEALWAYS	0xFFFF	// Add-on is always enabled.

typedef WORD VAO_INVOKEMASK, FAR* LPVAO_INVOKEMASK;
typedef WORD VAO_NOTIFYMASK, FAR* LPVAO_NOTIFYMASK;

// This is the maximum add-on name length we'll allow an add-on name to
// have (not counting the null at its end). Names over 20 or so characters
// will be truncated when made visible by the UI, so names much longer
// than that aren't particularly useful anyway.
//
#define VAOMAXAONAME 100

VAO_EMBEDDABLE_STRUCT
	{
	VAO_ORDINAL		ord;			// Ordinal of Add-on. This should be
									// a value other than VAO_INV_ORD. Each
									// Add-on registered by a given Add-on
									// library should be assigned a distinct
									// ordinal.

	VAO_ATTS		atts;			// Attributes of Add-on.
	VAO_ENABMASK	enabMask;		// Add-on's enabling policy.
	VAO_INVOKEMASK	invokeOnMask;	// 
	VAO_NOTIFYMASK	notifyOnMask;	// 

	LPSTR			lpName;			// Add-on's name.
									//
									//	- Visio makes a copy of the name
									//	  hence the lib needn't keep memory
									//	  pointed to by lpName around.
									//
									//	- Name can be null or "", but it
									//	  won't show up in Run Add-on
									//	  dialog and analogous dialogs.
									//
									//	- If the name isn't null, Visio will
									//	  return an error if a given Add-on
									//	  lib registers more than one Add-on
									//	  with the same name.
									//
									//	- Visio assumes name is an ansi (as
									//	  opposed to an oem) string. This
									//	  makes a difference if the name
									//	  container e.g. accented characters.
	} VAOREGSTRUCT, FAR* LPVAOREGSTRUCT;


//---------------------------------------------------------------------------
//	MESSAGES THAT CROSS THE VISIO/ADD-ON LIBRARY INTERFACE
//---------------------------------------------------------------------------


#define _VAOGEN_INVBASE	(0x0000)	// First invariant generic message/rc
#define _VAOGEN_SENBASE	(0x1000)	// First int sensitive generic message/rc

#define _V2L_INVBASE	(0x2000)	// First invariant v2l message/rc
#define _V2L_SENBASE	(0x3000)	// First int sensitive v2l message/rc

#define _L2V_INVBASE	(0x4000)	// First invariant l2v message/rc
#define _L2V_SENBASE	(0x5000)	// First int sensitive l2v message/rc

typedef enum
	{
	INVALID_VAOMSG			= _VAOGEN_INVBASE,	// The code no msg can have.
	V2LMSG_LOAD				= _V2L_INVBASE,
	V2LMSG_UNLOAD,
	V2LMSG_ENUMADDONS		= _V2L_SENBASE,
	V2LMSG_ISAOENABLED,
	V2LMSG_RUN,
	V2LMSG_RUNABOUT,
	V2LMSG_RUNHELP,
	V2LMSG_KILLSESSION,

	_V2LMSG_FIRSTFREE,
	L2VMSG_AVAILCALLS		= _L2V_INVBASE,
	L2VMSG_REGADDON			= _L2V_SENBASE,
	L2VMSG_UNREGADDON,
	L2VMSG_ISAOENABLED,
	L2VMSG_ISCMDENABLED,
	L2VMSG_ENABLEMENU,
	L2VMSG_ISCMDQUERY,
	L2VMSG_GETARGSIZE,
	L2VMSG_AVAILMODES,
	L2VMSG_EXECUTE,
	L2VMSG_ENUMDOCS,
	L2VMSG_ENUMCONS,
	L2VMSG_ENUMSHEETS,
	L2VMSG_SESSIONDONE,
	L2VMSG_PROMPTUSER,
	L2VMSG_obsDBL2ASCII,	// Obsolete. But consume id so others unaffected.
	L2VMSG_obsASCII2DBL,	// Obsolete. But consume id so others unaffected.
	L2VMSG_GETAPPINFO,
	L2VMSG_DEBUGMSG,

	_L2VMSG_FIRSTFREE,

	} VAOMSG_ENUM, FAR* LPVAOMSG_ENUM;


// --------------------
// GENERIC RETURN CODES
// --------------------

#define VAORC_L2V_LOADFAILED	(_L2V_INVBASE+0)
								// Prescribed error response to V2LMSG_LOAD.

#define VAORC_L2V_ENABLED		(_L2V_SENBASE+0)

#define VAORC_L2V_MODELESS		(_L2V_SENBASE+1)

#define VAORC_L2V_GOTNOABOUT	(_L2V_SENBASE+2)
								// Prescribed lib response to V2LMSG_RUNABOUT
								// meaining lib didn't respond to Visio's
								// request. Visio will respond by displaying
								// a very generic about box. Note that Visio
								// will only send V2LMSG_RUNABOUT to Add-ons
								// that declare VAO_AOATTS_HASABOUT in their
								// registration structure. So Add-ons that
								// really don't provide about should say so
								// when registering.

#define VAORC_L2V_GOTNOHELP		(_L2V_SENBASE+3)
								// Prescribed lib response to V2LMSG_RUNHELP
								// meaining lib didn't respond to Visio's
								// request. Visio will respond by displaying
								// very generic. Note that Visio will only
								// send V2LMSG_RUNHELP to Add-ons that
								// declare VAO_AOATTS_HASHELP in their
								// registration structure. So Add-ons that
								// really don't provide help should say so
								// when registering.
								
#define VAORC_L2V_BADMSG		(_L2V_SENBASE+5)
								// Lib returns this if sent illegal message.

#define VAORC_SUCCESS			(_VAOGEN_INVBASE+0)
											// ASSERT(VAORC_SUCCESS==0);

#define VAORC_FAILURE			(_VAOGEN_SENBASE+0)


//---------------------------------------------------------------------------
//
//	INDIVIDUAL MESSAGE DESCRIPTIONS:
//	-------------------------------
//
//	Messages sent from Visio to library
//	-----------------------------------
//
//	wmsg				wparam			lparam			return
//	----				------			------			------


//	V2LMSG_LOAD			Visio Version	LPVAOFUNC		VAO_L2V_VERSION() |
//														VAORC_L2V_LOADFAILED
//
//
//		Visio sends V2LMSG_LOAD to an Add-on library right after it has
//		done LoadLibrary() and GetProcAddress(LPVAOENTRYNAME) on the library.
//
//		The value of the wparam passed with V2LMSG_LOAD indicates the Add-on
//		interface version being used by the sending Visio. Typically the
//		receiving library shouldn't care. However, if it so chooses, it can
//		refuse to load itself based on the version of Visio it is running
//		with. WParam packs the major and minor interface version numbers
//		being used by Visio in the same fashion as described below for
//		VAO_L2V_VERSION(). [See (*) below.]
//
//		The value of the lparam passed	with V2LMSG_LOAD is a pointer to the
//		procedure in Visio the library is to call when it wants to make calls
//		back into Visio later.
//
//		Visio expects a response of VAO_L2V_VERSION() to V2LMSG_LOAD unless
//		the library fails to initialize itself. If initialization fails, the
//		response should be VAORC_L2V_LOADFAILED, in which case Visio will
//		perform an immediate FreeLibrary() and send the lib no more messages.
//
//		Note: This value should never have _L2V_INVBASE bit set in it!
//		That way we can always distinguish it from VAORC_L2V_LOADFAILED.
//
		#define VAO_L2V_VERSION() ((VAORC)( (VAO_IFMAJOR<<8) | VAO_IFMINOR ))
//
//		Visio disables library call backs when it sends V2LMSG_LOAD.
//
//		Note that a Visio INSTANCE will send V2LMSG_LOAD when it loads an
//		Add-on library. Thus a library may receive V2LMSG_LOAD multiple
//		times without receiving intervening V2LMSG_UNLOADs if multiple Visio
//		instances are running. Thus a library wanting to perform instance
//		independent initialization can take one of several tacks:
//
//		option1:	Do instance independent initialization in its LibMain().
//		option2:	Keep a global load count around that's initialized to 0,
//					incremented when V2LMSG_LOAD is received and decremented
//					when V2LMSG_UNLOAD is received. Instance Instance
//					independent initialization should then occur when
//					V2LMSG_LOAD is received and the load count is 0. Services
//					implementing this option are available in vlibutils.h/c.
//
//		(*): Visio 2.0, which implemented version 2.1 of the Add-on interface,
//		passed wparam as VAO_INV_SESSID. Versions of Visio that implement
//		version 2.2 or later of the Add-on interface pass the interface
//		version they are using in wparam as described above.
//
		#define _21VISIO VAO_INV_SESSID


//	V2LMSG_UNLOAD		undefined		NULL			moot
//
//		Visio sends V2LMSG_UNLOAD to an Add-on library right before it is
//		about to do a FreeLibrary() on the library (probably because it is
//		quitting). The library has no choice in this matter, V2LMSG_UNLOAD
//		doesn't allow the library to respond that it doesn't want to be
//		unloaded. The result a library returns in response to V2LMSG_UNLOAD
//		is really moot (but VAORC_SUCCESS is suggested).
//
//		Note that Visio doing a FreeLibrary() doesn't necessarily imply the
//		library is really about to be unloaded. Windows will decrement the
//		library's use count when Visio does the FreeLibrary() and actually
//		unload the library only if the use count decrements to zero. The use
//		count may still be non-zero if multiple instances of Visio have loaded
//		the library. If the library has instance independent cleanup that it
//		only wants to perform when it is really going to be unloaded, it can
//		put the cleanup in its WEP() procedure or maintain a use count as
//		described above in the V2LMSG_LOAD discussion.
//
//		Visio disables library call backs when it sends V2LMSG_UNLOAD.
//
//		Note that Visio will never send V2LMSG_UNLOAD to a library that has
//		modeless sessions in progress (see V2LMSG_RUN). Rather, it will send
//		V2LMSG_KILLSESSIONs until no sessions remain, then send V2LMSG_UNLOAD.


//	V2LMSG_ENUMADDONS	0				LPVAOV2LSTRUCT	VAORC
//
//		Visio sends V2LMSG_ENUMADDONS to a library when it is requesting
//		the library to enumerate its Add-ons. Typically a library will respond
//		by sending L2VMSG_REGADDON messages back to Visio.
//
//		The VAOV2LSTRUCT pointed to by lparam specifies information the
//		library will need in order to make calls back into Visio.
//
//		When it sends V2LMSG_ENUMADDONS, Visio enables all call backs except
//		requests to execute action commands.
//
//		If the result returned by the library in response to V2LMSG_ENUMADDONS
//		isn't VAORC_SUCCESS, Visio will send an immediate V2LMSG_UNLOAD and
//		not deal further with the library. If some but not all of a library's
//		Add-ons register successfully and if the library wishes to continue,
//		it should respond VAORC_SUCCESS to V2LMSG_ENUMADDONS.


//	V2LMSG_RUN			i				LPVAOV2LSTRUCT	VAORC_SUCCESS |
//														VAORC_L2V_MODELESS |
//														VAORC_SomeError
//
//		Visio sends V2LMSG_RUN to a library when it is requesting the library
//		to run the Add-on whose ordinal is passed in wparam. Visio will only
//		send this message if the targeted Add-on has been deemed currently
//		enabled according to the enabling policy declared for it when it was
//		registered.
//
//		The VAOV2LSTRUCT pointed to by lparam specifies information the
//		library will need in order to make calls back into Visio.
//
//		If the targeted Add-on was declared to have an attribute of
//		VAO_AOATTS_ISACTION when it was registered, then Visio enables
//		all call backs when it sends this message. Otherwise all call backs
//		except requests to execute action commands will be enabled.
//
//		If the invoked Add-on completes whatever operation it performs in
//		response to V2LMSG_RUN, then VAORC_SUCCESS or VAORC_SomeError should
//		be returned by the library to Visio in response to the message.
//


//	V2LMSG_RUNABOUT		i				LPVAOV2LSTRUCT	VAORC_SUCCESS |
//														VAORC_L2V_MODELESS |
//														VAORC_SomeError
//
//		Visio sends V2LMSG_RUNABOUT to a library when it is requesting the
//		library to invoke "about" for the the Add-on whose ordinal is passed
//		in wparam. Visio will only send this message if the targeted Add-on
//		was declared to provide "about" when it was registered.
//
//		The VAOV2LSTRUCT pointed to by lparam specifies information the
//		library will need in order to make calls back into Visio.
//
//		The result Visio expects a library to return in response to
//		V2LMSG_RUNABOUT is exactly as described for V2LMSG_RUN.


//	V2LMSG_RUNHELP		i				LPVAOV2LSTRUCT	VAORC_SUCCESS |
//														VAORC_L2V_MODELESS |
//														VAORC_SomeError
//
//		Visio sends V2LMSG_RUNHELP to a library when it is requesting the
//		library to invoke help for the the Add-on whose ordinal is passed
//		in wparam. Visio will only send this message if the targeted Add-on
//		was declared to provide help when it was registered.
//
//		The VAOV2LSTRUCT pointed to by lparam specifies information the
//		library will need in order to make calls back into Visio.
//
//		The result Visio expects a library to return in response to
//		V2LMSG_RUNHELP is exactly as described for V2LMSG_RUN.


//---------------------------------------------------------------------------
//
//	DEFAULT HANDLING OF MESSAGES FROM VISIO:

VAOU_PROC(VAORC)
				VAOUtil_DefVisMainProc
									( VAOMSG	wMsg,
									  WORD		wParam,
									  LPVOID	lpParam,
									  HINSTANCE hResources );


VAOU_PROC(VOID)	VAOUtil_SetVisCallBack	( LPVAOFUNC lpfunc );


VAOU_PROC(LPVAOFUNC)
				VAOUtil_VisCallBack		( VOID );


VAOU_PROC(HINSTANCE)
				VAOUtil_hAppInst		( VOID );


VAOU_PROC(VAORC)
				VAOUtil_RegisterAddons
									( WORD			 wSessID,
									  LPVAOREGSTRUCT lpRegStructArray,
									  WORD			 nRegStructs );

//---------------------------------------------------------------------------
//
//	GLOBAL DATA DEPENDENCIES
//---------------------------------------------------------------------------

// --- Per dll instance globals that are referenced in this file ---
//
// Gbl_hDLLModule is the instance handle for the dll this code is running
// in. It gets set in LibMain() when this dll gets loaded. VLIBUTL_hModule()
// simply returns gbl_hDLLModule to its callers.
//
extern HINSTANCE gbl_hDLLModule;


//---------------------------------------------------------------------------
//
//	DEFINITIONS OF PROVIDED SERVICES:
//	--------------------------------
//
//---------------------------------------------------------------------------


// LibMain():			Default dll initialization procedure.
//
int CALLBACK LibMain				( HINSTANCE		hModule,
									  WORD			wDataSeg,
									  WORD			cbHeapSize,
									  LPSTR			lpNotUsed );


// WEP(): Default Windows Exit Procedure for dll.
//
int CALLBACK WEP					( int			bSystemExit );


// VLIBUTL_hModule():	Returns module (instance) handle of dll.
//
MACRO(
HINSTANCE	VLIBUTL_hModule			( VOID );
)


#define VLIBUTL_hModule() gbl_hDLLModule


#if defined(__cplusplus)
	}        /* End of extern "C" { */
#endif

#endif /* _VAO_H */
