When a client application calls a function that invokes a server application, actions taken by the client and server can be asynchronous. For example, the actions of updating a document and closing a server are asynchronous. Whenever an asynchronous operation begins, the client library returns OLE_WAIT_FOR_RELEASE. When a client application receives this notification, it must wait for the OLE_RELEASE notification before it quits. If the client cannot take further action until the asynchronous operation finishes, it should enter a message-dispatch loop and wait for OLE_RELEASE. Otherwise, it should allow the main message loop to continue dispatching messages so that processing can continue.
An application can run only one asynchronous operation at a time for an object; each asynchronous operation must end with the OLE_RELEASE notification before the next one begins. The client's callback function must receive OLE_RELEASE for all pending asynchronous operations before calling the OleRevokeClientDoc function.
Some of the object-creation functions return OLE_WAIT_FOR_RELEASE. The client application can continue to work with the document while waiting for OLE_RELEASE, but some functions (for example, OleActivate) cannot be called until the asynchronous operation has been completed.
If an application calls a function for an object before receiving OLE_RELEASE for that object, the function may return OLE_BUSY. The server also returns OLE_BUSY when processing a new request would interfere with the processing of a current request from a client application or user. When a function returns OLE_BUSY, the client application can display a message reporting the busy condition at this point or it can enter a loop to wait for the function to return OLE_OK. (The OLE_QUERY_RETRY notification is also sent to the client's callback function when the server is busy; when the callback function returns FALSE, the transaction with the server is ended.) Note that if the server uses the OleBlockServer function to postpone OLE activities, the OLE_QUERY_RETRY notification is not sent to the client.
The following example shows a message-dispatch loop that allows a client application to transact messages while waiting for the OLE_RELEASE notification:
while ((olestat = OleQueryReleaseStatus(lpObject)) == OLE_BUSY) {
if (GetMessage(&msg, NULL, NULL, NULL)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if (olestat == OLE_ERROR_OBJECT) {
.
. /* The lpObject parameter is invalid. */
.
}
else { /* if olestat == OLE_OK */
.
. /* The object is released, or the server has terminated. */
.
}
A server application could end unexpectedly while a client is waiting for OLE_RELEASE. In this case, the client library recovers properly only if the client uses the OleQueryReleaseStatus function, as shown in the preceding example.
The following table shows which OLE functions can return the OLE_WAIT_FOR_RELEASE or OLE_BUSY value to a client application:
Function | OLE_BUSY | OLE_WAIT_FOR_RELEASE |
OleActivate | Yes | Yes |
OleClose | Yes | Yes |
OleCopyFromLink | Yes | Yes |
OleCreate | No | Yes |
OleCreateFromClip | No | Yes |
OleCreateFromFile | No | Yes |
OleCreateFromTemplate | No | Yes |
OleCreateLinkFromClip | No | Yes |
OleCreateLinkFromFile | No | Yes |
OleDelete | Yes | Yes |
OleExecute | Yes | Yes |
OleLoadFromStream | No | Yes |
OleObjectConvert | Yes | No |
OleReconnect | Yes | Yes |
OleRelease | Yes | Yes |
OleRequestData | Yes | Yes |
OleSetBounds | Yes | Yes |
OleSetColorScheme | Yes | Yes |
OleSetData | Yes | Yes |
OleSetHostNames | Yes | Yes |
OleSetLinkUpdateOptions | Yes | Yes |
OleSetTargetDevice | Yes | Yes |
OleUnlockServer | No | Yes |
OleUpdate | Yes | Yes |