Office Compatible 97—Document Routing

by Ross Comer
Development Lead, Microsoft Office Compatible

June 1996

Abstract

This article provides a detailed description of the document routing feature of Office Compatible and the steps necessary to implement this feature into your custom application.  It also provides sample code for both a C/C++ interface and an OLE Automation interface accessible from Visual Basic or VBA. This feature will work with any mail server which has implemented MAPI, but works best with Exchange or Outlook.

Description

Document Routing facilitates the flow of information among a group of users. With Document Routing features as part of a client application, a user can route any type of file to co-workers by attaching it to an e-mail message. It can be sent either to one person at a time or to the group simultaneously.  This feature works the same as the File Send option in Office applications, using the same dialogs. Using this feature eliminates the need to understand and implement MAPI calls that provide the same functionality.

Office Compatible provides OLE Automation and C interfaces to allow applications to take advantage of Document Routing technology and to bring up the Routing dialogs.

Dialogs

The document routing dialog allows the user to do several things:

Keep in mind that this API set only supports adding the routing slip and specifying the recipients.  The application must supply a way to route the document either by bringing up a dialog or by supplying a menu item command.

C Interface

To get the IMsocRouteSlip Interface, use the PirsCreateRoutingSlip() method.  If the result of this call is non-NULL, the call succeeded, and you are holding the IMsocRouteSlip interface to a RoutingSlip object. Once you have the interface, you can access and manipulate its properties as needed.  For the example below, check that pRouteSlip is non-NULL.

   // Get the Routing interface
   IMsocRouteSlip *pRouteSlip = PirsCreateRoutingSlip();

Release the IMsocRouteSlip Object by calling the Release() method on the RouteSlip object.  A RoutingSlip object must be released when it is no longer needed, that is, when the user closes the document.

The IMsocRouteSlip Interface

Use the following APIs get and set the RouteSlip options.

   HRESULT SetOption(DWORD dwOption);
   HRESULT GetOption(DWORD * pdwOption);

Where the routing options are:

   // Notice RSLIP_ALL_AT_ONCE must be used by itself
   // other options can be set together using bit-wise 
   #define  RSLIP_ALL_AT_ONCE        0x00000000
   #define  RSLIP_ONE_AFTER_ANOTHER  0x00000001
   #define  RSLIP_RETURN_WHEN_DONE   0x00000002
   #define  RSLIP_TRACK_STATUS       0x00000004

These options correspond to the same options the user can set on the bottom of the Routing dialog.

Set and get the list of recipients using the following calls.

   HRESULT GetRecipients(SAFEARRAY** ppsa);
   HRESULT SetRecipients(SAFEARRAY* psa);

The user sets this list using the address button under the recipient list box of the Routing dialog. The user can also set the order using the move keys to the right of the list box.

The Address… button brings up the Address Book dialog by default. 

Various RoutingSlip settings can be set and retrieved using the following APIs, where dwStr is the setting.  The value itself is returned in wzBuf.

   HRESULT GetStringValue(DWORD dwStr, LPWSTR wzBuf,  int cchMax);
   HRESULT SetStringValue(DWORD dwStr, LPWSTR wzBuf);

Valid dwStr values are below.  Some of these values are document property types. The routing feature assumes these values have been stored as properties with the document. If these properties have not been stored with the document or no document properties are available for this document, the call will return NULL.

   // Returns the name of the calling application
   #define RSLIP_APPNAME   0x00000001
   // Returns the registered document type
   #define RSLIP_DOCTYPE   0x00000002
   // Returns the document title property
   #define RSLIP_DOCTITLE   0x00000003
   // Returns the system filename
   #define RSLIP_FILENAME   0x00000004
   // Returns the string contained in the Message Text edit box 
   // of the Routing Slip dialog
   #define RSLIP_MESSAGE   0x00000005
   // Returns the string contained in the Subject edit box 
   // of the Routing Slip dialog
   #define RSLIP_SUBJECT   0x00000006
   // Returns the summary property
   #define RSLIP_SUMMARY   0x00000007
   // Returns the (email) name of the document originator.  
   // This name is displayed in the From text area of the dialog.
   #define RSLIP_ORIGINATOR   0x00000008

It is the responsibility of the calling application to save the routing slip information in the application's document.  This is necessary if the developer wants the application to use any routing option other than RSLIP_ALL_AT_ONCE.  The information to be saved with the document is stored in a SAFEARRAY.  The data in the array should not be looked at by the application other than to determine the type and to save it in the document stream.  If the application loads a document with Routing data, it should create a routing slip and call the SetInfoToSave method to fill in the routing slip data.

   HRESULT GetInfoToSave(SAFEARRAY** ppsa);
   HRESULT SetInfoToSave(SAFEARRAY* psa);

Routing a document takes two distinct steps: PrepareToRoute and Route. The PrepareToRoute call tells OfficeCompatible to increment the routing information so that it can be appropriately routed to the next person. After calling PrepareToRoute, the application should Save the document to a temporary file. During the save, GetInfoToSave should be called to get the routing slip information that should be saved with the document. Then Route can be called to route the temporary document.

   HRESULT PrepareToRoute();
   HRESULT Route(LPWSTR wzFileName);

Reset is used to clear all data in a RoutingSlip.  This call functions the same as the Clear button on the Routing Slip dialog.

   HRESULT Reset();

Release must be called when the application is done using the routing slip:

   HRESULT Release();

Sample C Code

// Get the OfficeCompatible interface
IOfficeCompatible *pOC = CreateOfficeCompatible(L"SampleApp", L"SampleAplication")

if (pOC != NULL)
   {
   // Get the Routing interface
   IMsocRouteSlip *pRouteSlip = PirsCreateRoutingSlip();

   if (pRouteSlip == NULL)
      return();

   // Allow the user to set the recipients and message
   pRouteSlip->ShowEditDialog(hwndMain);
   
   pRouteSlip->PrepareToRoute();

   SAFEARRAY* psa = CreateSafeArray();
   pRouteSlip->GetInfoToSave(&psa);

   // Application routine to save the file to a temporary file 
   // with RouteSlip information
   WCHAR wzFileName[256];
   SaveTempFileWithRouteSlip(psa, wzFileName);

   pRouteSlip->Route(wzFileName);
   }

Automation Interface

Document Routing is also available through the Office Compatible Automation interfaces.

Use the CreateRoutingSlip method of the OfficeCompatible interface to create a new routing slip.  The properties of the RoutingSlip object compare to the C calls described earlier. These properties contain information about the document itself as well as the information entered by the user through the Routing Slip dialog.

RoutingSlip
properties
Application - Returns the application object
Parent - Returns the application object
Message – Set or return the text message of the routing slip 
Recipients([in]bstrArray) - Array of strings of recipient names 
ReturnWhenDone – Set or return whether the original document is to be sent back to the owner 
Status – Return the routing status of the document,
where status is one of the following:

msocNoTrackStatus 
msocNotYetRouted 
msocRoutingInProgress 
msocRoutingComplete

Subject – Set or return the subject string of the routing mail 
TrackStatus – Set or return whether to track the routing status of the document 
InfoToSave – Set or return a variant array of routing information to be saved with the document 
ApplicationName – Set or return the attachment application name 
DocumentType – Set or return a description of document type 
DocumentTitle – Set or return the document Title 
Delivery - Set or return the delivery style, which may be the constants msocAllAtOnce or msocOneAfterAnother 

methods
Reset - Clean up the routing slip

      // This method gets called to inform OC that we are about to route
      // App then  gets InfoToSave and saves it with document in temp file
      // App then calls Route
      PrepareToRoute - Increment routing information for document

Route([in]BSTR FileName) - Route the document
ShowRoutingDialog([in, opt]varhWnd) - Standard Microsoft Office Routing dialog
ShowSendDialog([in]BSTR fileName, [in, opt]VARIANT varhWnd) - Standard Microsoft Office Send dialog

Sample VB Code

   Set OC = CreateObject("OfficeCompatible.Application")
   If OC Is Nothing Then Exit Sub
    
   On Error Resume Next
   OC.Init "OCBSamp", "Office Compatible Basic Sample App"

   If (Err.Number <> 0) Then
      Set OC = Nothing
      On Error GoTo 0
      Exit Sub
   End If
        
   On Error GoTo 0

   Set RouteSlip = OC.CreateRoutingSlip
   If Not RouteSlip Is Nothing Then
      RouteSlip.ShowRoutingDialog

      RouteSlip.PrepareToRoute

      SaveInfo = pRouteSlip.InfoToSave

      ' Application subroutine to save the file to a temporary file 
      ' with RouteSlip information
      TempFileName = SaveTempFileWithRouteSlip(SaveInfo)

      pRouteSlip->Route(TempFileName);
   End If