Admin Production ni-theme
Current Publication

Completing Advanced Object-Specific Tasks in ActiveX Applications

LabWindows/CVI

Completing Advanced Object-Specific Tasks in ActiveX Applications

The Object Helper Functions class contains functions that you can use to perform advanced object-specific tasks. Calling CA_ServerLockActiveObject on an ActiveX object results in an additional internal reference to the object, independent of the external ActiveX references to the object. Call CA_ServerLockActiveObject when the ActiveX object displays a user interface that appears on the screen. Lock the object to prevent the user interface from disappearing when the last external reference to the ActiveX object is released. You must call CA_ServerUnlockActiveObject when the user interface of a previously locked ActiveX object is being hidden or discarded. Call CA_ServerDestroyActiveObject to destroy, in response to an interactive user command, an ActiveX object that was locked when it appeared. CA_ServerDestroyActiveObject destroys an ActiveX object even though clients might be holding external references to the object. Use CA_ServerDestroyActiveObject only for the preceding purpose.

Example Code: Locking, Unlocking, and Destroying User Interface Objects

The following sample demonstrates locking, unlocking, and destroying user interface objects:

/* User ActiveX function for method Show of interface IFoo in object UIObj */
HRESULT CVIFUNC UIObjIFooShow (CAServerObjHandle objHandle)
{
   HRESULT hr = S_OK;
   int panel = 0;

   panel = GetUserInterfacePanel (objHandle); // Internal call: Get the UI panel

   if (panel > 0 && !IsPanelVisible (panel)) {
      // Lock the object as its lifetime is now determined by the user interface
      hr = CA_ServerLockActiveObject (objHandle);
      if (FAILED (hr))
         return hr;
      DisplayPanel (panel); // Display the user interface
   }
   return hr;
}
/* User ActiveX function for method Hide of interface IFoo in object UIObj */
HRESULT CVIFUNC UIObjIFooHide (CAServerObjHandle objHandle)
{
   HRESULT hr = S_OK;
   int panel = 0;

   panel = GetUserInterfacePanel (objHandle); // Internal call: Get the UI panel

   if (panel > 0 && IsPanelVisible (panel)) {
      HidePanel (panel); // Hide the user interface
      // Unlock the object as its lifetime is now determined by COM
      hr = CA_ServerUnlockActiveObject (objHandle);
      if (FAILED (hr))
         return hr;
   }
   return hr;
}
/* User interactive callback to quit the user interface of the ActiveX object */
int CVICALLBACK QuitCb (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
   if (event == EVENT_COMMIT) {
      CAServerObjHandle objHandle = 0;

      // Internal call: Get the ActiveX object's handle
      objHandle = GetActiveXObjHandle (panel);
      if (objHandle && IsPanelVisible (panel)) {
         // Destroy the ActiveX object cleanly, as it was locked when it was made visible
         CA_ServerDestroyActiveObject (objHandle);
      }
      // Quit the user interface
      QuitUserInterface (0);
   }
}

Example Code: Specifying Error Information

If an ActiveX object provides rich error information you must call CA_ServerSetErrorInfo in the feature functions to specify error information for the returned failure code. If the feature functions return a success return value, do not call CA_ServerSetErrorInfo. On error, a feature function compatible with ErrorInfo must free resources, call CA_ServerSetErrorInfo, and return immediately after CA_ServerSetErrorInfo returns. The following code sample demonstrates the use of CA_ServerSetErrorInfo:

Note Note  To enable rich error information, enable the Support ErrorInfo option in the Edit ActiveX Object Advanced Options dialog box.

/* User ActiveX function for method Foo of interface IFoo in object Obj */
HRESULT CVIFUNC ObjIFooFoo (CAServerObjHandle objHandle)
{
   HRESULT hr = S_OK;
   char *pcBuf = NULL;

   // Try allocating a 1K buffer
   pcBuf = CA_AllocMemory (sizeof (char) * 1024);
   if (pcBuf) {
      // Make some internal call with buffer
      hr = MyInternalCall (pcBuf);
      if (FAILED (hr))
         goto Error;
   }
   else {
      hr = E_OUTOFMEMORY;
      goto Error;
   }
   Error:
      // Clean up resources
      if (pcBuf)
         CA_FreeMemory (pcBuf);
      // Set error info
      if (FAILED (hr)) {
         CA_ServerSetErrorInfo (
            objHandle, // handle of object setting error
            &IID_IFoo, // IID of interface setting error
            "Error occurred", // error description
            "MyServer.chm", // help file containing more info
            HLP_CTX_ERROR // help context in help file
         );
      }
      // Return immediately after setting error info
      return hr;
}