home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 January / pcwk_01_1999.iso / Wtestowe / Vistdstd / Install / Data.Z / Ivisreg.CPP < prev    next >
C/C++ Source or Header  |  1997-09-09  |  10KB  |  387 lines

  1. /*    IVISREG.CPP - Helper functions for starting Visio
  2.  *  Copyright (C) 1991-1997 Visio Corporation. All rights reserved.
  3.  */
  4.  
  5. #include <windows.h>
  6. #include <ole2.h>
  7.  
  8. #if !defined (_WIN32)
  9.     #include <dispatch.h>
  10. #endif
  11.  
  12. #include <initguid.h>
  13.  
  14. #define NO_VISIO_41_COMPATIBILITY_LAYER
  15.  
  16. #include "ivisreg.h"
  17.  
  18. /*
  19.  *    Note - This file is meant to work as either a C or C++ module.  To
  20.  *    do so we need a special macro for invoking properties and methods
  21.  *    on our Visio interfaces.  The macro below handles the translation
  22.  *    between C and C++ for us but, unfortunately, it makes our function
  23.  *    calls look very strange.  For instance here is a comparison of the
  24.  *    different methods.  The advantage is we need only write one file.
  25.  *
  26.  *    In C            lpIVApp->lpVtbl->Version(lpIVApp, &bstr);
  27.  *    In C++            lpIVApp->Version(&bstr);
  28.  *    INVOKE Macro    INVOKE(lpIVApp, Version) &bstr);
  29.  *
  30.  *    But to make some things easier to read there is a second macro for
  31.  *    methods that have no arguments.  It reads:
  32.  *
  33.  *    In C            lpIVApp->lpVtbl->Release(lpIVApp);
  34.  *    In C++            lpIVApp->Release();
  35.  *    INVOKE Macro    INVOKE_(lpIVApp, Release);
  36.  */
  37.  
  38. #ifdef __cplusplus
  39. #define REF(r) (r)
  40. #define INVOKE(i, m)    i->m(
  41. #define INVOKE_(i, m)    i->m();
  42. #else
  43. #define REF(r) (&(r))
  44. #define INVOKE(i, m)    i->lpVtbl->m(i,
  45. #define INVOKE_(i, m)    i->lpVtbl->m(i);
  46. #endif
  47.  
  48.  
  49. /*************************************************************************
  50.  *                        Private Declarations
  51.  *
  52.  * lpIVAS - Our very own proxy object that we register every time
  53.  *          this module is entered.  Supporting calls go through this 
  54.  *          proxy for Application objects.  It gets cleaned up after
  55.  *          we make our Get/Create calls for the application interface.
  56.  *
  57.  * hLastError - Contains the last error that occurred.  Should be
  58.  *          retrieved through vaoGetLastError for detailed error
  59.  *          reporting.
  60.  */
  61.  
  62. static LPVAUTOSUPPORT lpIVAS     = NULL;
  63. static HRESULT        hLastError = NOERROR;
  64.  
  65.  
  66. /*
  67.  * Forward Prototypes of private (static) helpers
  68.  */
  69.  
  70. static short vaoInit(void);
  71.  
  72. static short vaoUnInit(void);
  73.  
  74. static short vaoGetVisioApp(
  75.     LPVISIOAPPLICATION FAR *);
  76.     
  77. static short vaoCreateVisioApp(
  78.     LPVISIOAPPLICATION FAR *);
  79.  
  80. static void SetLastResult(HRESULT);
  81.  
  82. /*************************************************************************
  83.  *                          Private Functions Bodes
  84.  ************************************************************************/
  85.  
  86. /*************************************************************************
  87.  *+ vaoInit
  88.  *
  89.  *    Initializes the module by getting an instance of the Visio 
  90.  *    automation proxy.
  91.  */
  92.  
  93. static short vaoInit()
  94.     {
  95.     CLSID clsid;
  96.     IID iid;
  97.     SCODE sc;
  98.     
  99.     if ( NULL != lpIVAS )
  100.         return VAO_SUCCESS;
  101.     
  102.     CLSIDFromString(CLSID_VISIOAUTOPROXY, &clsid);
  103.     IIDFromString(IID_VISIOAUTOSUPPORT, &iid);
  104.     
  105.     sc = GetScode(CoCreateInstance(REF(clsid), NULL, CLSCTX_INPROC, REF(iid),
  106.                                     (LPVOID FAR *)&lpIVAS));
  107.     
  108.     SetLastResult(ResultFromScode(sc));
  109.     
  110.     if ( NULL != lpIVAS )
  111.         {
  112.         if ( !(INVOKE(lpIVAS, CanRunProxy) PROXVER)) )
  113.             {
  114.             vaoUnInit();
  115.             return VAO_BAD_VERSION;
  116.             }
  117.         else
  118.             {
  119.             return VAO_SUCCESS;
  120.             }
  121.         }
  122.     else
  123.         {
  124.         return VAO_NOT_INSTALLED;
  125.         }
  126.     }
  127.  
  128.     
  129. /*************************************************************************
  130.  *+ vaoUnInit
  131.  *
  132.  *    Releases the Visio proxy being used by the module.
  133.  */
  134.  
  135. static short vaoUnInit()
  136.     {
  137.     if ( NULL != lpIVAS )
  138.         {
  139.         INVOKE_(lpIVAS, Release);
  140.         lpIVAS = NULL;
  141.         }
  142.     
  143.     return VAO_SUCCESS;
  144.     }
  145.  
  146.  
  147. /*************************************************************************
  148.  *+ vaoGetVisioApp
  149.  *
  150.  *    Using GetActiveObject, attempts to retrieve the 
  151.  *    active instance of Visio, if one is running.
  152.  */
  153.  
  154. static short vaoGetVisioApp(
  155.     LPVISIOAPPLICATION FAR * lplpIVApp)
  156.     {
  157.     HRESULT hResult;
  158.     IUnknown FAR *pUnk = NULL;
  159.  
  160.     *lplpIVApp = NULL;
  161.  
  162. #ifdef OLD_VISIO
  163.     //    Not dual interface; uses proxies
  164.     hResult = INVOKE(lpIVAS, GetVisioObject) TRUE, lplpIVApp);
  165. #else
  166.     //    Dual interface; doesn't use proxies
  167.     hResult = GetActiveObject(REF(CLSID_Application), NULL, &pUnk);
  168.  
  169.     if (pUnk!=NULL)
  170.         {
  171.         INVOKE(pUnk, QueryInterface) REF(IID_IVApplication), (LPVOID *) lplpIVApp);
  172.  
  173.         INVOKE_(pUnk, Release);
  174.         pUnk= NULL;
  175.         }
  176. #endif
  177.  
  178.     SetLastResult(hResult);
  179.  
  180.     if ( NULL != *lplpIVApp )
  181.         return VAO_GET;
  182.     else
  183.         return VAO_NOT_RUNNING;
  184.     }
  185.  
  186.     
  187. /*************************************************************************
  188.  *+ vaoCreateVisioApp
  189.  *
  190.  *    Using the proxy support interface, attempts to create a new 
  191.  *    Visio application instance.
  192.  */
  193.  
  194. static short vaoCreateVisioApp(
  195.     LPVISIOAPPLICATION FAR * lplpIVApp)
  196.     {
  197.     HRESULT hResult;
  198.  
  199. #ifdef OLD_VISIO
  200.     //    Not dual interface; uses proxies
  201.     hResult = INVOKE(lpIVAS, GetVisioObject) FALSE, lplpIVApp);
  202. #else
  203.     //    Dual interface; doesn't use proxies
  204.     hResult = CoCreateInstance
  205.                 (
  206.                     REF(CLSID_Application), NULL,
  207.                     CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,
  208.                     REF(IID_IVApplication), (LPVOID *) lplpIVApp
  209.                 );
  210. #endif
  211.  
  212.     SetLastResult(hResult);
  213.  
  214.     /*
  215.      *    Notice we return VAO_ERROR if we don't get the app interface
  216.      *    because we're assuming if we get the support interface Visio
  217.      *    must be installed.
  218.      */
  219.  
  220.     if ( NULL != *lplpIVApp )
  221.         return VAO_CREATE;
  222.     else
  223.         return VAO_ERROR;
  224.     }
  225.     
  226.     
  227. /*************************************************************************
  228.  *+ SetLastResult
  229.  *
  230.  *    Private function for setting the last error.
  231.  */
  232.  
  233. static void SetLastResult(HRESULT hError)
  234.     {
  235.     hLastError = hError;
  236.     }
  237.  
  238. /*************************************************************************
  239.  *                         Public Functions
  240.  ************************************************************************/
  241.  
  242. /*************************************************************************
  243.  *+ vaoGetVisio
  244.  *
  245.  *    Gets a Visio Application interface by retrieving the active
  246.  *    instance, creating a new one or doing both if the user specifies.
  247.  *    A flag is passed for both and if the get active fails a new one
  248.  *    is created.
  249.  *
  250.  *    The return value is one of the VAO_ result codes which are defined
  251.  *    in IVISREG.H.
  252.  */
  253.  
  254. #ifdef __cplusplus
  255. extern "C" {
  256. #endif
  257.  
  258. short vaoGetVisio(                            // VAO_ result code
  259.     BOOL fActive,                            // TRUE => Get Active
  260.     BOOL fCreate,                            // TRUE => Create New
  261.     LPVISIOAPPLICATION FAR * lplpIVApp)        // Application Interface
  262.     {
  263.     short sResult;    //    intentionally uninitialized - assigned to immediately
  264.                     //    below by call to vaoInit
  265.  
  266.     /*
  267.      * First we make sure that we can get an automation support
  268.      * proxy.  If not we can't do anything.  Then, if the application
  269.      * interface passed in is set we have to release it!
  270.      */
  271.      
  272.     if ( !fActive && !fCreate )
  273.         return VAO_ERROR;
  274.         
  275.     if ( VAO_SUCCESS != (sResult = vaoInit()) )
  276.         return sResult;
  277.     
  278.     if ( NULL != *lplpIVApp )
  279.         {
  280.         INVOKE_((*lplpIVApp), Release);
  281.         *lplpIVApp = NULL;
  282.         }
  283.         
  284.     /*
  285.      * Now we get to the real stuff.
  286.      */
  287.      
  288.     if ( fActive )
  289.         sResult = vaoGetVisioApp(lplpIVApp);
  290.     
  291.     if ( (VAO_GET != sResult) && fCreate )
  292.         sResult = vaoCreateVisioApp(lplpIVApp);
  293.         
  294.     vaoUnInit();
  295.     
  296.     return sResult;
  297.     }
  298.  
  299.  
  300. /*************************************************************************
  301.  *+ vaoGetObject
  302.  *
  303.  *    A more general form of vaoGetVisio that will attempt to get a running
  304.  *    instance of Visio by either getting the active instance or, if that
  305.  *    fails, creating a new one.  If either of these fails then either a
  306.  *    fatal error has occurred or Visio is not installed.
  307.  *
  308.  *    Return Value:
  309.  *
  310.  *    The return value is either VAO_SUCCESS or one of the errors 
  311.  *    returned through vaoGetVisio.
  312.  */
  313.  
  314. short vaoGetObject(
  315.     LPVISIOAPPLICATION FAR * lplpIVApp)        // Visio App Interface
  316.     {
  317.     short sResult;    //    intentionally uninitialized - assigned to immediately
  318.                     //    below by call to vaoGetVisio
  319.  
  320.     /*
  321.      *    We simply call our fellow internal to either Get or Create
  322.      *    a Visio instance.
  323.      */
  324.      
  325.     sResult = vaoGetVisio(TRUE, TRUE, lplpIVApp);
  326.     
  327.     if ( VAO_CREATE == sResult || VAO_GET == sResult )
  328.         sResult = VAO_SUCCESS;
  329.         
  330.     return sResult;
  331.     }
  332.  
  333.  
  334. #ifdef __cplusplus
  335. //    Overloaded function for linker to find:
  336.  
  337. #ifndef OLD_VISIO
  338. #ifndef NO_VISIO_41_COMPATIBILITY_LAYER
  339. //    Also provide a version the linker can find for other files that get
  340. //    compiled with NO_VISIO_41_COMPATIBILITY_LAYER defined...
  341.  
  342. //    In THIS *.cpp file, LPVISIOAPPLICATION is "IVisioApplication *"
  343. //    In *.cpp files with NO_... defined, LPVISIOAPPLICATION is "Application *"
  344. //    They're really two different names for the same thing.
  345.  
  346. #ifdef Application
  347. #undef Application
  348. #endif
  349.  
  350. #ifdef __cplusplus
  351. interface Application;
  352. #else
  353. typedef interface Application Application;
  354. #endif
  355.  
  356. typedef Application FAR * _LPVISIOAPPLICATION;
  357.  
  358. short vaoGetObject(
  359.     _LPVISIOAPPLICATION FAR *lplpIVApp)        // Visio App Interface
  360.     {
  361.     short sResult= vaoGetObject((LPVISIOAPPLICATION FAR *)lplpIVApp);
  362.     return sResult;
  363.     }
  364.  
  365. #endif    //    NO_VISIO_41_COMPATIBILITY_LAYER
  366. #endif    //    OLD_VISIO
  367. #endif    //    __cplusplus
  368.  
  369. /*************************************************************************
  370.  *+ vaoGetLastError
  371.  *
  372.  *    Returns the last error encountered by this module.  Should be called 
  373.  *    immediately after the error occurs because future operations will
  374.  *    probably reset the flag.
  375.  */
  376.  
  377. HRESULT vaoGetLastError()
  378.     {
  379.     return hLastError;
  380.     }
  381.     
  382. #ifdef __cplusplus
  383. }
  384. #endif
  385.  
  386.     
  387.