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 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;
}