OLE Client Specification

From RISC OS

(Difference between revisions)
Jump to: navigation, search
(Created, based on OLEClient.txt)
m (Quitting the client: typo)
 
(28 intermediate revisions not shown)
Line 1: Line 1:
-
---------------------------------------------------------------------------
+
:''There are still many points unclear about this protocol. You can discuss them on the [[Talk:OLE Client Specification|Talk page]].
-
$Id: OLEClient.txt 1.11 2009-01-16 14:54:41+01 erikgrnh Exp $
+
This page is intended as a full description of the [[Computer Concepts]] [[OLE]] protocol as seen from the client side. A programmer writing an application should be able to find here all the information required to let the application work as an OLE client. To let the application work as an OLE server, see the [[OLE Server Specification]].
-
  ---------------------------------------------------------------------------
+
   
 +
==The client==
-
Originator - Mike
+
A client application (such as a desktop publishing program, or a mail handler)
-
Purpose    - Specification of generic 'OLE' interface and mechanisms
+
may wish to edit data it is
-
Version    - $Revision: 1.11 $
+
capable of loading and rendering (such as drawfiles or plain text files).
-
Started    - 14th August 1993
+
Such an application could provide facilities to edit these
 +
files itself, or use an already resident editor by sharing the file with it.
-
$Log: OLEClient.txt $
 
-
Revision 1.11  2009-01-16 14:54:41+01  erikgrnh
 
-
Corrected some typos. Minor clarifications. Some added comments.
 
-
All comments from the author are now in the form "[Note EG: ... ]".
 
-
 
-
Revision 1.10  2004-02-29 19:56:10+01  erikgrnh
 
-
Split the specification into a description for the client and a
 
-
description for the server. Embelished with more detail.
 
-
 
-
---------------------------------------------------------------------------
 
-
 
-
Overview
 
-
========
 
-
 
-
OLE or object linking and embedding allows an application to share
 
-
data with a secondary or server application which can edit that
 
-
data and return it. This allows compliant applications to gain
 
-
features provided by specific graphics or text servers without having
 
-
to re-implement those features.
 
-
This documentation defines the message passing protocols necessary for
 
-
this kind of data sharing.
 
-
 
-
 
-
The client
 
-
==========
 
-
 
-
A client application (such as Impression) may wish to edit data it is
 
-
capable of loading and rendering (such as drawfiles). There are two options
 
-
open for such an application. Either it can provide facilities to edit these
 
-
files itself, or use an already resident editor by sharing the file with it.
 
It seems sensible and easier to choose the second option, in which case
It seems sensible and easier to choose the second option, in which case
-
the client needs to ask a 'compliant' server to engage in a two way data
+
the client needs to ask a 'compliant' server to engage in a two-way data
-
sharing session. It does so by the use of a OLEServer$<UniqueName> system
+
sharing session.
-
variable which the server provides.
+
 +
==An OLE session==
-
The server variable
+
An OLE session should be initiated by a client application.
-
===================
+
-
Any application which provides its own file type and is capable of editing
+
===Checking the environment variable===
-
such files may set itself up to be an OLE server. To do so it needs to create
+
The client should check to see if an OLEServer$Type_XXX variable
-
a system variable, outlining the file type it can edit.
+
exists for its file type.
 +
If it cannot find such a variable then there is no server known for
 +
that file type at the moment.
 +
The client may then choose to
 +
use the OLESupport module. It can simulate the response of a server
 +
for a chosen file type.
 +
If the client does not want to use the OLESupport module, then the OLE attempt
 +
has failed at this point. The client should inform the user and clean
 +
up any internal data.
-
The syntax of this variable is as follows
+
Note that if the OLESupport module has been used earlier for a particular
 +
file type, then there will already be an environment variable, which points
 +
to the module. If that is so, the client will find this variable in the first
 +
step, and transparently use the module, using the normal message protocol.
-
Variable name  = OLEServer$Type_XXX
+
It is advisable to check for this variable every time an OLE session is requested,
-
Variable value = -N <UniqueName> -R <run><Run$Path>
+
and not, e.g. only once when the client application starts or when the first OLE
 +
session is started. During the runtime of the client the variable may well change,
 +
for example because a server was seen by the Filer.
-
X          = 0..9 | A..F
+
===Using the OLESupport module===
-
AlphaChar  = 0..9 | A..Z | a..z
+
: ''See [http://www.xs4all.nl/~erikgrnh/riscos/OLESuppDoc.txt OLESuppDoc] for the original document.
-
UniqueName = [1..16]*<AlphaChar> (i.e. one to sixteen AlphaChars)
+
First the client must check if the module is loaded, by calling the OLE_Version SWI
-
run        = 'run ' or '/'
+
in the X variant:
-
 
+
  SWI XOLE_Version (&67B00)
-
Spaces must be used as separators.
+
  On entry -
-
 
+
  On exit  - R0 = Major revision number
-
Typical examples are
+
            R1 = Minor revision number
-
 
+
            R2 = Task handle (0 if task not running)
-
  OLEServer$Type_AFF : -N OLESupport -R /Desktop_OLESupport
+
  Errors  - Overflow set if SWI is not known
-
  OLEServer$Type_FFF : -N StrongED -R /ADFS::Csite.$.Apps.!StrongED
+
On normal exit (overflow clear) the module is already loaded. The server should proceed by calling the OLE_SimulateSession SWI as described below.
-
 
+
-
 
+
-
Tokens
+
-
------
+
-
 
+
-
-N : Name
+
-
 
+
-
    This token specifies a unique name to identify the server in
+
-
    an OpenSession message. This message is broadcast so it is up to
+
-
    the server who recognises the name to respond. This string can
+
-
    be up to 16 characters long. When passed in messages it should be
+
-
    specified as a 16 byte string with all unused bytes zeroed.
+
-
    Note the server name should be modelled on the application name
+
-
    such as 'OLESupport' used by the support module or 'StrongED' as
+
-
    used by the StrongED text editor.
+
-
 
+
-
-R : Run
+
-
    This token allows a potential client to Wimp_StartTask the server.
+
-
    It must provide a run$path string which uniquely locates the
+
-
    server. This could be an expanded pathname or more usually
+
-
    a system variable. It should be preceded with a run command so the
+
-
    whole string can be passed straight to Wimp_StartTask.
+
-
    eg 'run <Draw$Dir>'.
+
-
        '/<Draw$Dir>' etc
+
-
 
+
-
 
+
-
 
+
-
Creating an OLE session
+
-
=======================
+
-
  An OLE session should be opened by a client application which cannot itself
+
If an error is returned the module is not yet loaded. The client should then try to start it with:
-
edit a particular data format and wishes to share the data with a server
+
  SWI XWimp_StartTask (&600DE)
-
in order to do so.
+
  On entry - R0 = ^ "<Path$Dir>.OLESupport"
 +
  On exit - R0 = Task handle of module task (0 if task quit)
 +
  Errors  - Overflow set if command failed
 +
:''Note: the command string in R0 was taken from OLESuppDoc. It should be replaced with the correct string to start a module task. Should probably be "System:Modules.OLESupport".''
 +
If an error is returned, the module could not be found and the OLE session will have failed.  
-
A clients point of view
+
Now that the module is running, the client can ask it to handle sessions for the
-
=======================
+
desired file type by calling OLE_SimulateSession:
 +
  SWI OLE_SimulateSession (&47B05)
 +
  On entry - R0 = file type
 +
  On exit  -
 +
The module will create an environment variable of the form
 +
  OLEServer$Type_XXX : -N OLESupport -R /Desktop_OLESupport
 +
and will be ready to receive and send all OLE messages relevant to this file type.
 +
In effect the client can communicate transparently with the module as if it were
 +
a real OLE server.
-
(1) The client should check to see if an OLEServer$Type_XXX variable
+
The next step for the client is to start from the top: read the environment variable, send a broadcast, etc. Care must be taken not to fall into an endless loop if the environment variable the client looks for is not found. It should only attempt to start the module at most once for each OLE session.
-
    exists for its file type.
+
-
    (If it cannot find such a variable, then the client may wish to
+
-
    use the OLESupport module which simulates the response of a client
+
-
    for particular file types. See OLESupDoc for information on how to
+
-
    use this module task).
+
-
    [Note EG: this OLESupDoc is lost in the mists of time. If anyone can
+
-
    supply a copy this would be appreciated.]
+
-
(2) Having found a server variable, the client should save its data to
+
===Start the session===
-
    disc and send an OpenSession message with format 0 as a broadcast,
+
Having found a server variable, the client should save its data to
-
    using the unique name specified in the variable. If the server is
+
disc in a suitable temporary location (see [[Programming Conventions#Scrap usage]])
-
    already running it will respond with an acknowledge.
+
and send an OpenSession message with format 0 as a User_Message_Recorded (18) broadcast
-
      If there is no acknowledgement, the client will get it's message back
+
using the unique name specified in the variable.  
-
    as a User_Message_Acknowledge (19) message. It should then try to
+
-
    start the server using the -R token and again broadcast the OpenSession
+
-
    message, this time with format 1. If again the message is not
+
-
    acknowledged, the session failed. The client should delete the data
+
-
    file it created and tidy up.
+
-
      In the case that all is well, the server will have acknowledged the
+
-
    OpenSession message and will also respond by sending a
+
-
    Message_OLEOpenSessionAck to inform the client a session is truely
+
-
    open.
+
     Message_OLEOpenSession (&80E21)
     Message_OLEOpenSession (&80E21)
     -------------------------------
     -------------------------------
-
 
+
     SWI Wimp_SendMessage (&400E7)
     SWI Wimp_SendMessage (&400E7)
     On entry - R0 = User message recorded (18)
     On entry - R0 = User message recorded (18)
Line 137: Line 88:
                 +4 = not used on entry
                 +4 = not used on entry
                 +8 = not used on entry
                 +8 = not used on entry
-
                 +12 = your_ref (0 for original message)
+
                 +12 = your_ref (=0, this is an original message)
                 +16 = message number (&80E21)
                 +16 = message number (&80E21)
-
                 +20 = the 16 byte unique name from the -N tag, padded with zeros
+
                 +20 = the 16 byte unique name from the -N tag, padded with zero bytes
                 +36 = window handle of display holding file
                 +36 = window handle of display holding file
                 +40 = x offset of data in window
                 +40 = x offset of data in window
Line 152: Line 103:
                 format > 2 (reserved for future expansion)
                 format > 2 (reserved for future expansion)
             - R2 = 0 (broadcast)
             - R2 = 0 (broadcast)
-
 
+
     On exit  - R0 = corrupted
     On exit  - R0 = corrupted
             Message block is updated:
             Message block is updated:
Line 158: Line 109:
               R1+8 = my_ref (unique Wimp-generated word > 0)
               R1+8 = my_ref (unique Wimp-generated word > 0)
 +
If the server is
 +
already running it will respond with an acknowledge.
-
      Format 0 messages should be sent initially. If a task is running
+
If there is no acknowledgement, the client will get its message back
-
    which recognises the message it will reply correctly. If the client
+
as a User_Message_Acknowledge (19) message. It should then try to
-
    receives the same message back (format 0) because no-one acknowledged
+
start the server using the -R token and again broadcast a recorded OpenSession
-
    it, it should attempt to start the server task (specified in the
+
message, this time with format 1. If again the message is not
-
    OLEServer$ variable). It should then set the format to 1 and broadcast
+
acknowledged, the session failed. The client should inform the user,
-
    the message again. If it receives a format 1 message back
+
delete the data file it created and tidy up.
-
    unacknowledged it knows the server has died in some way and it should
+
-
    remove the data file.
+
-
      [Note EG: The original document says "send the same message off again
+
-
    to the task". This suggests sending the message to the specific task
+
-
    handle of the server you just started. You can probably use the task
+
-
    handle returned by Wimp_StartTask.]
+
-
      If a client knows it already has a link to a server, it should not
+
-
    attempt to send a format 0 open session message. It can send a format
+
-
    2 message which will inform a server that the user has tried to perform
+
-
    an OLE action on the same data a second time. This gives those
+
-
    applications which allow documents to be closed, but not lost from memory
+
-
    (eg ArtWorks) a chance to reopen an edit window on the data. If a
+
-
    format 2 message comes back unacknowledged, the server has presumably
+
-
    died in the meantime. The client should start from scratch with a
+
-
    format 0 message.
+
 +
In the case that all is well, the server will have acknowledged the
 +
OpenSession message by sending an
 +
OLEOpenSessionAck message to inform the client a session is truely
 +
open.
 +
:''Note: the following information on format 2 messages is dubious. See the [[Talk:OLE Client Specification#Format 2|talk page]]''
 +
If a client knows it already has a link to a server, it should not
 +
attempt to send a format 0 open session message. It can send a format
 +
2 message which will inform a server that the user has tried to perform
 +
an OLE action on the same data a second time. This gives those
 +
applications which allow documents to be closed, but not lost from memory
 +
(eg ArtWorks) a chance to reopen an edit window on the data.
 +
 +
If a
 +
format 2 message comes back unacknowledged, the server has presumably
 +
died in the meantime. The client should start from scratch with a
 +
format 0 message.
 +
 +
===The server replies===
     Message_OLEOpenSessionAck (&80E22)
     Message_OLEOpenSessionAck (&80E22)
     ----------------------------------
     ----------------------------------
-
 
+
     The server returns the same block as OpenSession but copies my_ref (+8)
     The server returns the same block as OpenSession but copies my_ref (+8)
-
     to your_ref (+12). This message tells the client that a session was
+
     to your_ref (+12) and puts the OLEOpenSessionAck code (&80E22) in the
-
    opened successfully and may expect Message_OLEFileChanged messages.
+
    message number field (+16).
-
 
+
This message tells the client that a session was
 +
opened successfully and may expect OLEFileChanged messages. The sending
 +
of this message by the server has several effects:
 +
*Because it sets the your_ref field to the my_ref field of the OLEOpenSession message, it tells the WIMP that it has acknowledged that message and the client will not get that OLEOpenSession message bounced back to it.
 +
*A new message (OLEOpenSessionAck) is sent to the client and can be used by the client to mark the session as open.
 +
*It tells the client what the task handle of the server is. Though the client might have gotten a task handle from the Wimp_StartTask call it used to start the server, in the most common cases the server will already be running, so this is the first point at which the client is informed of the task handle of the server.
-
(3) Whenever the server saves data back to file, it sends an OLEFileChanged
+
===The data has changed===
-
    User message to the client (using the task handle passed in
+
Whenever the server saves data back to file, it sends an OLEFileChanged
-
    OLEOpenSession). This message format is as follows
+
User message to the client (using the task handle passed in
 +
OLEOpenSession). This message format is as follows
     Message_OLEFileChanged (&80E1E)
     Message_OLEFileChanged (&80E1E)
Line 200: Line 162:
                 +8 = my ref
                 +8 = my ref
                 +12 = 0
                 +12 = 0
-
                 +16 = message number
+
                 +16 = message number (&80E1E)
                 +20 = format number
                 +20 = format number
                   format = 0 (saved to a different file) then
                   format = 0 (saved to a different file) then
Line 211: Line 173:
                   +24... reserved for future extensions
                   +24... reserved for future extensions
-
    Note, the server should not feel it owns the file and thus should not
+
Note that the server should not feel it owns the file and thus should not
-
    attempt to delete the file during emergencies. If the server corrupts
+
attempt to delete the file during emergencies. However, when the OLESupport module is
-
    the file, the client should be capable of working out that the file
+
used the editing program invoked by the module will have no such limitations and might
-
    format has been compromised when it receives an OLEFileChanged.
+
delete the file.
-
      The server will send a format 1 message when it saved the data to
+
-
    the same file. If the data was saved to a different file, it will send
+
-
    a format 0 message, providing the new pathname at +28.
+
-
      The client can now read the changed file from disk.
+
-
(4) Whenever the server throws data away through user action, it sends a
+
If the server corrupts
-
    User message back to the client informing it that the session has
+
the file, the client should be capable of working out that the file
-
    been terminated.
+
format has been compromised when it receives an OLEFileChanged and reads back the file.
 +
 
 +
The server will send a format 1 message when it saved the data to
 +
the same file. If the data was saved to a different file, it will send
 +
a format 0 message, providing the new pathname at +28.
 +
 
 +
The client should now read the changed file from disk.
 +
 
 +
===Closing the session===
 +
Whenever the server throws data away through user action (in particular
 +
when the editing window is closed), it sends a
 +
User message back to the client informing it that the session has
 +
been terminated.
     Message_OLECloseSession (&80E23)
     Message_OLECloseSession (&80E23)
Line 236: Line 206:
                   format > 0 reserved for future extensions
                   format > 0 reserved for future extensions
-
?? Note, the client can send this message to a client or broadcast it to
+
This message tells the client that the session has ended and the file
-
?? all clients when sessions are being closed from the clients end. (ie
+
was not modified any further. It should remove the file and drop this
-
?? the user is closing the application down or removing one of its
+
session from its list.
-
?? documents).
+
-
    [Note EG:
+
Note that not only can a server send this message to a client,
-
      It is unclear what is meant here. A client can send a message to a
+
the client can send this message to a server or broadcast it to
-
    client? Which client and how does it know to which client?  And
+
all servers when sessions are being closed from the client's end. (i.e.
-
    why should it want to? Clients should not interfere with
+
the user is closing the application down or removing one of its
-
    each other. Maybe it should read:
+
documents).
-
      "Note, the server can send this message to a client or broadcast it
+
-
    to all clients when sessions are being closed from the server's end.
+
-
    (i.e. the user is closing the server application down or removing one
+
-
    ot its documents)."
+
-
      Or maybe: "The client can send this message to a server or broadcast
+
-
    it when sessions are being closed from the client's end. (i.e. when
+
-
    the user is closing the client application down or removing one of
+
-
    its documents)."
+
-
      This last interpretation is the most likely and was used to write the
+
-
    paragraphs below. Note that servers should then watch for this message
+
-
    too.
+
-
    ]
+
-
    This message tells the client that the session has ended and the file
+
When a document is removed from the client (e.g. a Draw picture is
-
    was not modified any further. It should remove the file and drop this
+
deleted from a DTP application document) and there was an OLE session
-
    session from its list.
+
for that document, the client should send this message to the server
 +
with the appropriate Session number filled in. The server can then
 +
abandon the edit of this document.
-
    When a client is closing down, it should broadcast this message with
+
When a client is closing down, it should broadcast this message with
-
    the Session number set to -1. The servers that are handling its OLE
+
the Session number set to -1. The servers that are handling its OLE
-
    editing sessions then know that these sessions can be abandoned.
+
editing sessions then know that sessions for this client can be abandoned.
-
    When a document is removed from the client (e.g. a Draw picture is
+
Similarly, when a server closes down, it will also send a broadcast
-
    deleted from a DTP application document) and there was an OLE session
+
of this message with the Session number set to -1. Clients who have
-
    for that document, the client should send this message to the server
+
sessions open with this server (recognised by the server task handle)
-
    with the appropriate Session number filled in. The server can then
+
should drop those sessions.
-
    abandon the edit of this document.
+
 +
==Actions a client should take==
-
Session numbers & task handles
+
===Starting a session===
-
==============================
+
When a client wants to start an OLE session, it
 +
should write the file to disk and check for the environment variable
 +
for the proper file type.
 +
If no environment variable (and thus no server) is found, it could try to use the OLESupport
 +
module, which can be made to create an appropriate variable and operate as a server.
 +
The client
 +
should make sure it can handle the messages as described in
 +
[[#Messages to be handled by the client]], i.e. have the appropriate
 +
message handlers installed. It should
 +
generate a Session number and remember it belongs to this particular session
 +
in its internal data. It should then broadcast an OLEOpenSession format 0
 +
User_Message_Recorded (type 18) message.
-
  To provide context for OLE sessions a session number and task handle
+
The handler for the OLEOpenSession message will deal with any problems in
-
should be kept by the client and server for each session opened. Session
+
case the server was not running. The other handlers will deal with the
-
numbers must be allocated by the client task in a way which makes them
+
rest of the session.
-
unique for the run time of the program. The client should also keep a copy
+
-
of the server's task handle which it will receive via
+
-
Message_OLEOpenSessionAck. This way it can inform the server whenever it
+
-
closes down.
+
-
[Note EG: The text so far was a modified version of the original OLESpec.txt
+
===Discarding a file===
-
file, focussing on the client side and adding some extra information. All
+
When the user takes an action in the client application
-
that follows below is original work by me.]
+
that discards an object for which an OLE
 +
session is in progress, the client should send an OLECloseSession User
 +
message to the server. It should then clean up (remove the file, etc).
 +
===Quitting the client===
 +
If the client is closing down and it still has sessions open, it should
 +
either send each of the servers it knows about an OLECLoseSession User
 +
message with the Session number set to -1 ( = close all sessions),
 +
or broadcast such a message.
-
Messages to be handled by the client
+
Actually, the client could simply broadcast the message, regardless of
-
====================================
+
whether it has, or ever had, any sessions open.
-
[Note EG: I am a bit hazy on the message protocol. In the list below some
+
==Messages to be handled by the client==
-
entries for my ref (+8) and your ref (+12) may be given as zero, when they
+
 
-
in fact hold a sensible value]
+
===OLEOpenSession===
 +
Message_OLEOpenSession (&80E21)
 +
-------------------------------
 +
      +0 = length of block
 +
      +4 = task handle of the sender (a client)
 +
      +8 = my_ref
 +
    +12 = 0
 +
    +16 = message number (&80E21)
 +
    +20 = 16 byte unique name padded with zeros
 +
    +36 = window handle of display holding file
 +
    +40 = x offset of data in window
 +
    +44 = y offset of data in window
 +
    +48 = format number
 +
      format = 0 or 1 (edit file)
 +
      +52 = Session number
 +
      +56 = file type
 +
      +60 = full pathname of data, zero terminated
 +
      format = 2 (re-edit file)
 +
      +52 = Session number
 +
      format > 2 (reserved for future expansion)
 +
 
 +
The client receives one of these messages as a type 19 message
 +
(User_Message_Acknowledge) when the broadcast of the message by the
 +
client itself was not acknowledged. It should take further action to
 +
try to get the server to respond.
 +
 
 +
Note that this message may also arrive due to a broadcast by another
 +
client who is looking for a server, or even receive its own message
 +
back as part of the broadcast. In that case
 +
it will be a type 17
 +
(User_Message) or, more likely, type 18 (User_Message_Recorded) message.
 +
These should be ignored by the client.
 +
 
 +
====Format 0====
 +
If a format 0 message comes back, this means the server is not running.
 +
The client should try to start the server using the value in the -R field
 +
of the environment variable to Wimp_StartTask. If that fails
 +
(it returned an error or a task handle of 0)
 +
the client should consider the attempted OLE session failed, display an appropriate
 +
message to the user, and clean up (remove the temporary file, remove the session
 +
from its internal list, etc).
 +
 
 +
If the server was started successfully, the client should send a new OLEOpenSession User_Message_Recorded (18)
 +
message directly
 +
to the server, using the task handle returned by Wimp_StartTask,
 +
this time with format set to 1.
 +
:''Note: experiments have shown that existing clients often broadcast this message. See [[Talk:OLE Client Specification#Broadcast or direct]]''
 +
 
 +
====Format 1====
 +
If a format 1 message comes back, this means that we tried to start the
 +
server but it either died or does not acknowledge the message (i.e. it
 +
refuses to handle the file for some reason). The client should assume the
 +
session failed, inform the user with a suitable message,
 +
and clean up (remove the temporary file, remove the session
 +
from its internal list, etc).
 +
 
 +
====Format 2====
 +
If a format 2 message comes back, the server apparently has died since
 +
the last contact. The client should clean up the old session and start a
 +
new OLE session from scratch, i.e. read the environment variable,
 +
send an OLEOpenSession message with
 +
format 0 and continue the same way as for the original session.
 +
 
 +
===OLEOpenSessionAck===
 +
Message_OLEOpenSessionAck (&80E22)
 +
----------------------------------
 +
      +0 = length of block
 +
      +4 = task handle of the sender (the server)
 +
      +8 = my_ref
 +
    +12 = your_ref (copy of my_ref from the OLEOpenSession sent by the client)
 +
    +16 = message number (&80E22)
 +
    +20 = 16 byte unique name padded with zeros
 +
    +36 = window handle of display holding file
 +
    +40 = x offset of data in window
 +
    +44 = y offset of data in window
 +
    +48 = format number
 +
      format = 0 or 1 (edit file)
 +
      +52 = Session number
 +
      +56 = file type
 +
      +60 = full pathname of data, zero terminated
 +
    format = 2 (re-edit file)
 +
      +52 = Session number
 +
    format > 2 (reserved for future expansion)
 +
 
 +
This message means we are in business. The server is working on the
 +
document and the client may expect OLEFileChanged messages for it.
 +
 
 +
It is a copy of the OLEOpenSession message the client sent to the
 +
server, with the your_ref field filled with the value of the my_ref of the
 +
client's original message, and the message code replaced with the
 +
code for OLEOpenSessionAck (&80E22).
 +
 
 +
The client should check the your_ref value to see if it matches the my_ref
 +
of an OLEOpenSession message it sent, and check the Session number. If
 +
there is no match, the message should be ignored.
 +
 
 +
If the message is recognised the client should make a note of
 +
the task handle of the sender for this
 +
Session number. It will need this task handle to recognise messages coming
 +
from this server and when sending a message to the server.
 +
 
 +
 
 +
 
 +
===OLEFileChanged===
 +
Message_OLEFileChanged (&80E1E)
 +
-------------------------------
 +
      +0 = length of block
 +
      +4 = task handle of sender (the server)
 +
      +8 = my ref
 +
    +12 = 0
 +
    +16 = message number (&80E1E)
 +
    +20 = format number
 +
      format = 0 (saved to a different file) then
 +
        +24 = Session number
 +
        +28 = full pathname of data, zero terminated
 +
      format = 1 (saved to the same file) then
 +
        +24 = Session number
 +
              (format used by OLESupport)
 +
      format > 1 then
 +
        +24... reserved for future extensions
 +
 
 +
This is what OLE is all about. The client is informed that the file has
 +
been changed by the server.
 +
 
 +
The client must check if it knows the task handle of the server as
 +
given in the message, and has a session with the given Session number
 +
open with it. If not, it should ignore the message.
 +
 
 +
If there is a session, it can read the modified file (from the
 +
original path for format 1, the given path for format 0). The client
 +
may want to display the modified file in its own window.
 +
 
 +
Note that this message does not imply that the session is over. The
 +
server may issue more OLEFileChanged messages for this file.
-
Message_OLECloseSession (&80E23)
+
===OLECloseSession===
-
--------------------------------
+
Message_OLECloseSession (&80E23)
-
    +0 = length of block
+
--------------------------------
-
    +4 = task handle of sender
+
      +0 = length of block
-
    +8 = my ref
+
      +4 = task handle of sender (a server or client)
-
    +12 = 0
+
      +8 = my ref
-
    +16 = message number (&80E23)
+
    +12 = 0
-
    +20 = format number
+
    +16 = message number (&80E23)
-
      format = 0 then
+
    +20 = format number
-
        +24 = Session number (-1 means all sessions are closing)
+
      format = 0 then
-
      format > 0 reserved for future extensions
+
        +24 = Session number (-1 means all sessions are closing)
 +
      format > 0 reserved for future extensions
-
  This message is sent by a server when it wants to close a session
+
This message is sent by a server when it wants to close a session
(probably because the user has finished editing the object) or when it is
(probably because the user has finished editing the object) or when it is
-
shutting down, in which case all its sessions should be closed.
+
shutting down, in which case all its sessions should be closed  
-
  The client must check if it knows the task handle of the Server as
+
(Session number = -1).
-
given in the message, and has open sessions associated with it. If not,
+
 
-
it should ignore the message.
+
The client must check if it knows the task handle of the sender as
-
  For the given session number the client should remove the file on disk
+
a server it has open sessions associated with.
 +
If not, it should ignore the message.
 +
 
 +
For the given session number the client should remove the file on disk
(if it still exists), and remove the session from its list of active sessions.
(if it still exists), and remove the session from its list of active sessions.
If the session number was -1, it should do so for all open sessions which
If the session number was -1, it should do so for all open sessions which
were handled by the server identified by the given task handle.
were handled by the server identified by the given task handle.
 +
==The server variable==
-
Message_OLEFileChanged (&80E1E)
+
Any application which provides its own file type and is capable of editing
-
-------------------------------
+
such files may set itself up to be an OLE server. To do so it needs to create
-
    +0 = length of block
+
a system variable, outlining the file type it can edit.
-
    +4 = task handle of sender
+
-
    +8 = my ref
+
-
    +12 = 0
+
-
    +16 = message number
+
-
    +20 = format number
+
-
      format = 0 (saved to a different file) then
+
-
      +24 = Session number
+
-
      +28 = full pathname of data, zero terminated
+
-
      format = 1 (saved to the same file) then
+
-
      +24 = Session number
+
-
            (format used by OLESupport)
+
-
      format > 1 then
+
-
      +24... reserved for future extensions
+
-
  This is what OLE is all about. The client is informed that the file has
+
The syntax of this variable is as follows:
-
been changed by the server. It should read the modified file (from the
+
-
original path for format 1, the given path for format 0). The client
+
-
presumably may want to display the modified file in its own window.
+
-
  Note that this message does not imply that the session is over. The
+
-
server may issue more OLEFileChanged messages for this file.
+
 +
Variable name  = OLEServer$Type_XXX
 +
Variable value = -N <UniqueName> -R <RunCommand>
 +
 +
X          = 0..9 | A..F
 +
AlphaChar  = 0..9 | A..Z | a..z
 +
UniqueName = [1..16]*<AlphaChar> (i.e. one to sixteen AlphaChars)
 +
RunCommand = A * command string that will start the server
-
Message_OLEOpenSessionAck (&80E22)
+
Spaces must be used as separators. The '''-N''' token should always be first and the '''-R''' token last. Both tokens must be present.
-
----------------------------------
+
-
    +0 = length of block
+
-
    +4 = task handle of the sender
+
-
    +8 = my_ref
+
-
    +12 = your_ref
+
-
    +16 = message number (&80E22)
+
-
    +20 = 16 byte unique name padded with zeros
+
-
    +36 = window handle of display holding file
+
-
    +40 = x offset of data in window
+
-
    +44 = y offset of data in window
+
-
    +48 = format number
+
-
    format = 0 or 1 (edit file)
+
-
      +52 = Session number
+
-
      +56 = file type
+
-
      +60 = full pathname of data, zero terminated
+
-
    format = 2 (re-edit file)
+
-
      +52 = Session number
+
-
    format > 2 (reserved for future expansion)
+
-
  This message means we are in business. The server is working on the
+
Typical examples are
-
document and the client may expect OLEFileChanged messages for it.
+
-
  It is a copy of the OLEOpenSession message the client sent to the
+
-
server, with the your_ref field filled with the value of the my_ref of the
+
-
client's original message.
+
-
  The client should make a note of the task handle in combination with
+
-
the Session number. When the client at some point wishes to drop the
+
-
document that is being edited by the server, it can tell the server by
+
-
sending a OLECloseSession message directly to the server using the task
+
-
handle received in this message. Also, the server is identified by its
+
-
task handle in all the messages that it sends to clients, such as
+
-
Message_OLECloseSession.
+
 +
  OLEServer$Type_AFF : -N OLESupport -R /Desktop_OLESupport
 +
  OLEServer$Type_FFF : -N StrongED -R /ADFS::HardDisk4.$.Apps.!StrongED
-
Message_OLEOpenSession (&80E21)
 
-
-------------------------------
 
-
    +0 = length of block
 
-
    +4 = task handle of the sender
 
-
    +8 = my_ref
 
-
    +12 = 0
 
-
    +16 = message number (&80E21)
 
-
    +20 = 16 byte unique name padded with zeros
 
-
    +36 = window handle of display holding file
 
-
    +40 = x offset of data in window
 
-
    +44 = y offset of data in window
 
-
    +48 = format number
 
-
    format = 0 or 1 (edit file)
 
-
      +52 = Session number
 
-
      +56 = file type
 
-
      +60 = full pathname of data, zero terminated
 
-
    format = 2 (re-edit file)
 
-
      +52 = Session number
 
-
    format > 2 (reserved for future expansion)
 
-
  The client receives one of these messages as a type 19 message
+
===Tokens===
-
(User_Message_Acknownledge) when the broadcast of the message by the
+
-
client itself was not acknowledged. It should take further action to
+
-
try to get the server to respond.
+
-
  If a format 0 message comes back, this means the server is not running.
+
-
The client should try to start the server using the value in the -R field
+
-
of the environment variable and broadcast a new OLEOpenSession message,
+
-
this time with format set to 1.
+
-
  If a format 1 message comes back, this means that we tried to start the
+
-
server but it either died or does not acknowledge the message (i.e. it
+
-
refuses to handle the file for some reason). The client should assume the
+
-
session failed and clean up (remove the saved file, remove the session
+
-
from its internal list, etc).
+
-
  If a format 2 message comes back, the server apparently has died since
+
-
the last contact. The client should clean up the old session and start a
+
-
new OLE session from scratch, i.e. send an OLEOpenSession message with
+
-
format 0 and continue the same way as for the original session.
+
-
  Note that this message may also come by due to a broadcast by another
+
;-N <UniqueName>
-
client who is looking for a server. In that case it will be a type 17
+
:This token specifies a unique '''name''' to identify the server in an OpenSession message. This message is broadcast so it is up to the server who recognises the name to respond. This string can be up to 16 characters long. When passed in messages it should be specified as a 16 byte string with all unused bytes zeroed.
-
(User_Message) or, more likely, type 18 (User_Message_Recorded) message.
+
:Note the server name should be modelled on the application name such as 'OLESupport' used by the support module or 'StrongED' as used by the StrongED text editor.
-
These should be ignored by the client.
+
 +
;-R <RunCommand>
 +
:This token allows a potential client to '''run''' the server. It should provide a string which can be passed directly to Wimp_StartTask. This should start with a run command and be followed by the location of the server. This location could be an expanded pathname or more usually a system variable. Note that the RunCommand can contain spaces, and for convenience '''-R''' should be the last token in the variable. Examples:
 +
run <Draw$Dir>
 +
/<Draw$Dir>
-
Actions a client should take
+
==Session numbers & task handles==
-
============================
+
-
Starting a session
+
To provide context for OLE sessions a session number and task handle
-
------------------
+
should be kept by the client and server for each session opened. Session
-
  As described above, when a client wants to start an OLE session, it
+
numbers must be allocated by the client task in a way which makes them
-
should write the file to disk and check for the environment variable. It
+
unique for the run time of the program. The client should also keep a copy
-
should make sure it can handle the messages as described above. It should
+
of the server's task handle which it will receive via
-
generate a Session number and remember it belongs to this particular item
+
the OLEOpenSessionAck message. This way it can inform the server whenever it
-
in its internal data. It should then broadcast an OLEOpenSession
+
closes down and recognise messages sent by the server.
-
User_Message_Recorded (type 18) message.
+
-
The handler for the OLEOpenSession message will deal with any problems in
+
-
case the server was not running. The other handlers will deal with the
+
-
rest of the session.
+
 +
Note that the combination of client task handle and session number uniquely
 +
identifies a session.
-
Discarding a file
+
A session number is limited to 24 bits (it is unknown why this is), so using
-
-----------------
+
pointers to internal data structures as session numbers is not practical.
-
  When the user takes an action that discards an object for which an OLE
+
A recommended strategy for generating session numbers by a client is to simply
-
session is in progress, the client should send an OLECloseSession User
+
start at 1 when the application starts and increment by one for each new session.
-
message to the server. It should then clean up (remove the file, etc).
+
Assuming the user starts a new OLE session every 5 seconds for 12 hours a day,
 +
seven days a week it will take more than five years for the counter to run out.
 +
==See Also==
 +
*[[OLE]]
 +
*[[OLE Specification]]
 +
*[[OLE Server Specification]]
 +
*[[User Messages]]
-
Quitting the client
+
[[Category:Protocols]]
-
-------------------
+
-
  If the client it closing down and it still has sessions open, it should
+
-
either send each of the servers it knows about an OLECLoseSession User
+
-
message with the Session number set to -1, or broadcast such a message
+
-
(recommended). (Note: this implies that servers should pay attention to the
+
-
task handle of the sender in OLECloseSession messages it receives, and
+
-
only stop editing the documents for that particular client). Actually, the
+
-
client need not check if it has sessions open, it can simply broadcast the
+
-
message.
+

Latest revision as of 16:32, 16 January 2014

There are still many points unclear about this protocol. You can discuss them on the Talk page.

This page is intended as a full description of the Computer Concepts OLE protocol as seen from the client side. A programmer writing an application should be able to find here all the information required to let the application work as an OLE client. To let the application work as an OLE server, see the OLE Server Specification.

Contents

The client

A client application (such as a desktop publishing program, or a mail handler) may wish to edit data it is capable of loading and rendering (such as drawfiles or plain text files). Such an application could provide facilities to edit these files itself, or use an already resident editor by sharing the file with it.

It seems sensible and easier to choose the second option, in which case the client needs to ask a 'compliant' server to engage in a two-way data sharing session.

An OLE session

An OLE session should be initiated by a client application.

Checking the environment variable

The client should check to see if an OLEServer$Type_XXX variable exists for its file type. If it cannot find such a variable then there is no server known for that file type at the moment. The client may then choose to use the OLESupport module. It can simulate the response of a server for a chosen file type. If the client does not want to use the OLESupport module, then the OLE attempt has failed at this point. The client should inform the user and clean up any internal data.

Note that if the OLESupport module has been used earlier for a particular file type, then there will already be an environment variable, which points to the module. If that is so, the client will find this variable in the first step, and transparently use the module, using the normal message protocol.

It is advisable to check for this variable every time an OLE session is requested, and not, e.g. only once when the client application starts or when the first OLE session is started. During the runtime of the client the variable may well change, for example because a server was seen by the Filer.

Using the OLESupport module

See OLESuppDoc for the original document.

First the client must check if the module is loaded, by calling the OLE_Version SWI in the X variant:

 SWI XOLE_Version (&67B00)
 On entry -
 On exit  - R0 = Major revision number
            R1 = Minor revision number
            R2 = Task handle (0 if task not running)
 Errors   - Overflow set if SWI is not known

On normal exit (overflow clear) the module is already loaded. The server should proceed by calling the OLE_SimulateSession SWI as described below.

If an error is returned the module is not yet loaded. The client should then try to start it with:

 SWI XWimp_StartTask (&600DE)
 On entry - R0 = ^ "<Path$Dir>.OLESupport"
 On exit  - R0 = Task handle of module task (0 if task quit)
 Errors   - Overflow set if command failed
Note: the command string in R0 was taken from OLESuppDoc. It should be replaced with the correct string to start a module task. Should probably be "System:Modules.OLESupport".

If an error is returned, the module could not be found and the OLE session will have failed.

Now that the module is running, the client can ask it to handle sessions for the desired file type by calling OLE_SimulateSession:

 SWI OLE_SimulateSession (&47B05)
 On entry - R0 = file type
 On exit  -

The module will create an environment variable of the form

 OLEServer$Type_XXX : -N OLESupport -R /Desktop_OLESupport

and will be ready to receive and send all OLE messages relevant to this file type. In effect the client can communicate transparently with the module as if it were a real OLE server.

The next step for the client is to start from the top: read the environment variable, send a broadcast, etc. Care must be taken not to fall into an endless loop if the environment variable the client looks for is not found. It should only attempt to start the module at most once for each OLE session.

Start the session

Having found a server variable, the client should save its data to disc in a suitable temporary location (see Programming Conventions#Scrap usage) and send an OpenSession message with format 0 as a User_Message_Recorded (18) broadcast using the unique name specified in the variable.

   Message_OLEOpenSession (&80E21)
   -------------------------------

   SWI Wimp_SendMessage (&400E7)
   On entry - R0 = User message recorded (18)
            - R1 = ^Block
                +0 = length of block
                +4 = not used on entry
                +8 = not used on entry
               +12 = your_ref (=0, this is an original message)
               +16 = message number (&80E21)
               +20 = the 16 byte unique name from the -N tag, padded with zero bytes
               +36 = window handle of display holding file
               +40 = x offset of data in window
               +44 = y offset of data in window
               +48 = format number
                format = 0 or 1 (edit file)
                 +52 = Session number (24 bit number invented by the client)
                 +56 = file type
                 +60 = full pathname of the data file, zero terminated
                format = 2 (re-edit file)
                 +52 = Session number (24 bit number invented by the client)
                format > 2 (reserved for future expansion)
            - R2 = 0 (broadcast)

   On exit  - R0 = corrupted
            Message block is updated:
              R1+4 = task handle of sender (i.e. us, the client)
              R1+8 = my_ref (unique Wimp-generated word > 0)

If the server is already running it will respond with an acknowledge.

If there is no acknowledgement, the client will get its message back as a User_Message_Acknowledge (19) message. It should then try to start the server using the -R token and again broadcast a recorded OpenSession message, this time with format 1. If again the message is not acknowledged, the session failed. The client should inform the user, delete the data file it created and tidy up.

In the case that all is well, the server will have acknowledged the OpenSession message by sending an OLEOpenSessionAck message to inform the client a session is truely open.

Note: the following information on format 2 messages is dubious. See the talk page

If a client knows it already has a link to a server, it should not attempt to send a format 0 open session message. It can send a format 2 message which will inform a server that the user has tried to perform an OLE action on the same data a second time. This gives those applications which allow documents to be closed, but not lost from memory (eg ArtWorks) a chance to reopen an edit window on the data.

If a format 2 message comes back unacknowledged, the server has presumably died in the meantime. The client should start from scratch with a format 0 message.

The server replies

   Message_OLEOpenSessionAck (&80E22)
   ----------------------------------

   The server returns the same block as OpenSession but copies my_ref (+8)
   to your_ref (+12) and puts the OLEOpenSessionAck code (&80E22) in the
   message number field (+16).

This message tells the client that a session was opened successfully and may expect OLEFileChanged messages. The sending of this message by the server has several effects:

  • Because it sets the your_ref field to the my_ref field of the OLEOpenSession message, it tells the WIMP that it has acknowledged that message and the client will not get that OLEOpenSession message bounced back to it.
  • A new message (OLEOpenSessionAck) is sent to the client and can be used by the client to mark the session as open.
  • It tells the client what the task handle of the server is. Though the client might have gotten a task handle from the Wimp_StartTask call it used to start the server, in the most common cases the server will already be running, so this is the first point at which the client is informed of the task handle of the server.

The data has changed

Whenever the server saves data back to file, it sends an OLEFileChanged User message to the client (using the task handle passed in OLEOpenSession). This message format is as follows

   Message_OLEFileChanged (&80E1E)
   -------------------------------
                +0 = length of block
                +4 = task handle of sender
                +8 = my ref
               +12 = 0
               +16 = message number (&80E1E)
               +20 = format number
                 format = 0 (saved to a different file) then
                  +24 = Session number
                  +28 = full pathname of data, zero terminated
                 format = 1 (saved to the same file) then
                  +24 = Session number
                        (format used by OLESupport)
                 format > 1 then
                  +24... reserved for future extensions

Note that the server should not feel it owns the file and thus should not attempt to delete the file during emergencies. However, when the OLESupport module is used the editing program invoked by the module will have no such limitations and might delete the file.

If the server corrupts the file, the client should be capable of working out that the file format has been compromised when it receives an OLEFileChanged and reads back the file.

The server will send a format 1 message when it saved the data to the same file. If the data was saved to a different file, it will send a format 0 message, providing the new pathname at +28.

The client should now read the changed file from disk.

Closing the session

Whenever the server throws data away through user action (in particular when the editing window is closed), it sends a User message back to the client informing it that the session has been terminated.

   Message_OLECloseSession (&80E23)
   --------------------------------
                +0 = length of block
                +4 = task handle of sender
                +8 = my ref
               +12 = 0
               +16 = message number (&80E23)
               +20 = format number
                 format = 0 then
                   +24 = Session number (-1 means all sessions are closing)
                 format > 0 reserved for future extensions

This message tells the client that the session has ended and the file was not modified any further. It should remove the file and drop this session from its list.

Note that not only can a server send this message to a client, the client can send this message to a server or broadcast it to all servers when sessions are being closed from the client's end. (i.e. the user is closing the application down or removing one of its documents).

When a document is removed from the client (e.g. a Draw picture is deleted from a DTP application document) and there was an OLE session for that document, the client should send this message to the server with the appropriate Session number filled in. The server can then abandon the edit of this document.

When a client is closing down, it should broadcast this message with the Session number set to -1. The servers that are handling its OLE editing sessions then know that sessions for this client can be abandoned.

Similarly, when a server closes down, it will also send a broadcast of this message with the Session number set to -1. Clients who have sessions open with this server (recognised by the server task handle) should drop those sessions.

Actions a client should take

Starting a session

When a client wants to start an OLE session, it should write the file to disk and check for the environment variable for the proper file type. If no environment variable (and thus no server) is found, it could try to use the OLESupport module, which can be made to create an appropriate variable and operate as a server. The client should make sure it can handle the messages as described in #Messages to be handled by the client, i.e. have the appropriate message handlers installed. It should generate a Session number and remember it belongs to this particular session in its internal data. It should then broadcast an OLEOpenSession format 0 User_Message_Recorded (type 18) message.

The handler for the OLEOpenSession message will deal with any problems in case the server was not running. The other handlers will deal with the rest of the session.

Discarding a file

When the user takes an action in the client application that discards an object for which an OLE session is in progress, the client should send an OLECloseSession User message to the server. It should then clean up (remove the file, etc).

Quitting the client

If the client is closing down and it still has sessions open, it should either send each of the servers it knows about an OLECLoseSession User message with the Session number set to -1 ( = close all sessions), or broadcast such a message.

Actually, the client could simply broadcast the message, regardless of whether it has, or ever had, any sessions open.

Messages to be handled by the client

OLEOpenSession

Message_OLEOpenSession (&80E21)
-------------------------------
     +0 = length of block
     +4 = task handle of the sender (a client)
     +8 = my_ref
    +12 = 0
    +16 = message number (&80E21)
    +20 = 16 byte unique name padded with zeros
    +36 = window handle of display holding file
    +40 = x offset of data in window
    +44 = y offset of data in window
    +48 = format number
     format = 0 or 1 (edit file)
      +52 = Session number
      +56 = file type
      +60 = full pathname of data, zero terminated
     format = 2 (re-edit file)
      +52 = Session number
     format > 2 (reserved for future expansion) 

The client receives one of these messages as a type 19 message (User_Message_Acknowledge) when the broadcast of the message by the client itself was not acknowledged. It should take further action to try to get the server to respond.

Note that this message may also arrive due to a broadcast by another client who is looking for a server, or even receive its own message back as part of the broadcast. In that case it will be a type 17 (User_Message) or, more likely, type 18 (User_Message_Recorded) message. These should be ignored by the client.

Format 0

If a format 0 message comes back, this means the server is not running. The client should try to start the server using the value in the -R field of the environment variable to Wimp_StartTask. If that fails (it returned an error or a task handle of 0) the client should consider the attempted OLE session failed, display an appropriate message to the user, and clean up (remove the temporary file, remove the session from its internal list, etc).

If the server was started successfully, the client should send a new OLEOpenSession User_Message_Recorded (18) message directly to the server, using the task handle returned by Wimp_StartTask, this time with format set to 1.

Note: experiments have shown that existing clients often broadcast this message. See Talk:OLE Client Specification#Broadcast or direct

Format 1

If a format 1 message comes back, this means that we tried to start the server but it either died or does not acknowledge the message (i.e. it refuses to handle the file for some reason). The client should assume the session failed, inform the user with a suitable message, and clean up (remove the temporary file, remove the session from its internal list, etc).

Format 2

If a format 2 message comes back, the server apparently has died since the last contact. The client should clean up the old session and start a new OLE session from scratch, i.e. read the environment variable, send an OLEOpenSession message with format 0 and continue the same way as for the original session.

OLEOpenSessionAck

Message_OLEOpenSessionAck (&80E22)
----------------------------------
     +0 = length of block
     +4 = task handle of the sender (the server)
     +8 = my_ref
    +12 = your_ref (copy of my_ref from the OLEOpenSession sent by the client)
    +16 = message number (&80E22)
    +20 = 16 byte unique name padded with zeros
    +36 = window handle of display holding file
    +40 = x offset of data in window
    +44 = y offset of data in window
    +48 = format number
     format = 0 or 1 (edit file)
      +52 = Session number
      +56 = file type
      +60 = full pathname of data, zero terminated
    format = 2 (re-edit file)
      +52 = Session number
    format > 2 (reserved for future expansion)

This message means we are in business. The server is working on the document and the client may expect OLEFileChanged messages for it.

It is a copy of the OLEOpenSession message the client sent to the server, with the your_ref field filled with the value of the my_ref of the client's original message, and the message code replaced with the code for OLEOpenSessionAck (&80E22).

The client should check the your_ref value to see if it matches the my_ref of an OLEOpenSession message it sent, and check the Session number. If there is no match, the message should be ignored.

If the message is recognised the client should make a note of the task handle of the sender for this Session number. It will need this task handle to recognise messages coming from this server and when sending a message to the server.


OLEFileChanged

Message_OLEFileChanged (&80E1E)
-------------------------------
     +0 = length of block
     +4 = task handle of sender (the server)
     +8 = my ref
    +12 = 0
    +16 = message number (&80E1E)
    +20 = format number
      format = 0 (saved to a different file) then
       +24 = Session number
       +28 = full pathname of data, zero terminated
      format = 1 (saved to the same file) then
       +24 = Session number
             (format used by OLESupport)
      format > 1 then
       +24... reserved for future extensions

This is what OLE is all about. The client is informed that the file has been changed by the server.

The client must check if it knows the task handle of the server as given in the message, and has a session with the given Session number open with it. If not, it should ignore the message.

If there is a session, it can read the modified file (from the original path for format 1, the given path for format 0). The client may want to display the modified file in its own window.

Note that this message does not imply that the session is over. The server may issue more OLEFileChanged messages for this file.

OLECloseSession

Message_OLECloseSession (&80E23)
--------------------------------
     +0 = length of block
     +4 = task handle of sender (a server or client)
     +8 = my ref
    +12 = 0
    +16 = message number (&80E23)
    +20 = format number
      format = 0 then
        +24 = Session number (-1 means all sessions are closing)
      format > 0 reserved for future extensions

This message is sent by a server when it wants to close a session (probably because the user has finished editing the object) or when it is shutting down, in which case all its sessions should be closed (Session number = -1).

The client must check if it knows the task handle of the sender as a server it has open sessions associated with. If not, it should ignore the message.

For the given session number the client should remove the file on disk (if it still exists), and remove the session from its list of active sessions. If the session number was -1, it should do so for all open sessions which were handled by the server identified by the given task handle.

The server variable

Any application which provides its own file type and is capable of editing such files may set itself up to be an OLE server. To do so it needs to create a system variable, outlining the file type it can edit.

The syntax of this variable is as follows:

Variable name  = OLEServer$Type_XXX
Variable value = -N <UniqueName> -R <RunCommand>

X          = 0..9 | A..F
AlphaChar  = 0..9 | A..Z | a..z
UniqueName = [1..16]*<AlphaChar> (i.e. one to sixteen AlphaChars)
RunCommand = A * command string that will start the server

Spaces must be used as separators. The -N token should always be first and the -R token last. Both tokens must be present.

Typical examples are

  OLEServer$Type_AFF : -N OLESupport -R /Desktop_OLESupport
  OLEServer$Type_FFF : -N StrongED -R /ADFS::HardDisk4.$.Apps.!StrongED


Tokens

-N <UniqueName>
This token specifies a unique name to identify the server in an OpenSession message. This message is broadcast so it is up to the server who recognises the name to respond. This string can be up to 16 characters long. When passed in messages it should be specified as a 16 byte string with all unused bytes zeroed.
Note the server name should be modelled on the application name such as 'OLESupport' used by the support module or 'StrongED' as used by the StrongED text editor.
-R <RunCommand>
This token allows a potential client to run the server. It should provide a string which can be passed directly to Wimp_StartTask. This should start with a run command and be followed by the location of the server. This location could be an expanded pathname or more usually a system variable. Note that the RunCommand can contain spaces, and for convenience -R should be the last token in the variable. Examples:
run <Draw$Dir>
/<Draw$Dir>

Session numbers & task handles

To provide context for OLE sessions a session number and task handle should be kept by the client and server for each session opened. Session numbers must be allocated by the client task in a way which makes them unique for the run time of the program. The client should also keep a copy of the server's task handle which it will receive via the OLEOpenSessionAck message. This way it can inform the server whenever it closes down and recognise messages sent by the server.

Note that the combination of client task handle and session number uniquely identifies a session.

A session number is limited to 24 bits (it is unknown why this is), so using pointers to internal data structures as session numbers is not practical. A recommended strategy for generating session numbers by a client is to simply start at 1 when the application starts and increment by one for each new session. Assuming the user starts a new OLE session every 5 seconds for 12 hours a day, seven days a week it will take more than five years for the counter to run out.

See Also

Personal tools