Navigation: Language Reference > App A - DDE, OLE, and OCX > Object Linking and Embedding >====== OLE Container Properties ====== | |
Contents:
Clarion OLE/OCX library and object hierarchies
There are a number of properties associated with an OLE container control that deal only with OLE objects (not .OCX controls).
Attribute Properties
PROP:Create | The CREATE attribute (blank if none). (WRITE ONLY) |
PROP:Open | The OPEN attribute (blank if none). (WRITE ONLY) |
PROP:Document | The DOCUMENT attribute (blank if none). (WRITE ONLY) |
PROP:Link | The LINK attribute (blank if none). (WRITE ONLY) |
PROP:Clip | The CLIP attribute. A toggle attribute. Assigning a null string () or zero turns it off, and '1' or 1 turns it on. (WRITE ONLY) |
| PROP:Stretch | The STRETCH attribute. A toggle attribute. Assigning a null string ( ) or zero turns it off, and '1' or 1 turns it on. (WRITE ONLY) |
PROP:Autosize | The AUTOSIZE attribute. A toggle attribute. Assigning a null string () or zero turns it off, and '1' or 1 turns it on. (WRITE ONLY) |
| PROP:Zoom | The ZOOM attribute. A toggle attribute. Assigning a null string ( ) or zero turns it off, and '1' or 1 turns it on. (WRITE ONLY) |
PROP:Compatibility | The COMPATIBILITY attribute (blank if none). (WRITE ONLY) |
Undeclared Properties
PROP:Blob | Convert an object to and from a blob. (READ/WRITE) | ||||
PROP:SaveAs | Saves the object to an OLE Compound Storage file. (WRITE ONLY) The syntax for placing the object in the file is 'filename\!component' For example: | ||||
?controlx{PROP:SaveAs} = 'myfile\!objectx' | |||||
PROP:DoVerb | Executes an OLE doverb command from the following set of commands (WRITE ONLY): | ||||
DOVERB:Primary (0) | Calls the object's primary action. The object, not the container, determines this action. If the object supports in-place activation, the primary verb usually activates the object in-place. | | | ||
DOVERB:Show (-1) | Tells the object to show itself for editing or viewing. Called to display newly inserted objects for initial editing and to show link sources. This is usually an alias for some other object-defined action. | | | ||
DOVERB:Open (-2) | Tells the object to open itself for editing in a separate window from its container (this includes objects that support in-place activation). If the object does not support in-place activation, this has the same action as DOVERB:Show. | | | ||
DOVERB:Hide (-3) | Tells the object to remove its user interface. This applies only to objects activated in-place. | | | ||
DOVERB:UIActivate (-4) | Activates the object in place, along with its full set of user-interface tools, including menus, toolbars, and its name in the title bar of the container window. | | | ||
DOVERB:InPlaceActivate (-5) | Activates the object in-place without displaying the tools (menus and toolbars) that end-users need to change the behavior or appearance of the object. | | | ||
DOVERB:DiscardUndoState (-6) | Tells the object to discard any undo state that it may be maintaining without deactivating the object. | | | ||
DOVERB:Properties (-7) | Invokes the modal system property browser for the object to allow the user to set its properties. | | |
PROP:Deactivate | Deactivates an in-place active OLE object. (READ/WRITE/EXECUTE) |
PROP:Update | Tells the OLE object to update itself. (READ/WRITE/EXECUTE) |
PROP:CanPaste | Can you paste the object in the clipboard? (READ ONLY) |
PROP:Paste | Pastes an object from the clipboard to an OLE container control. (READ/WRITE/EXECUTE) |
PROP:CanPasteLink | Can the object in the clipboard be pasted as a link? (READ ONLY) |
PROP:PasteLink | Pastes and links an object from the clipboard to an OLE container control. (READ/WRITE/EXECUTE) |
PROP:Copy | Copies an object in an OLE container control to the clipboard. (READ/WRITE/EXECUTE) |
PROP:ReportException | Report OLE exceptions (for debug). (WRITE ONLY) |
PROP:OLE | Is there an OCX or OLE object in the container? (READ ONLY) |
PROP:Language | The number for the language used for OLE Automation or OCX Method. The number for US English is 0409H, and other language numbers can be computed from the data in the WINNT.H file in the MS Windows SDK. (READ/WRITE) |
Example Program:
PROGRAM
MAP
INCLUDE('OCX.CLW')
SelectOleServer PROCEDURE(OleQ PickQ),STRING
END
INCLUDE 'XL.CLW' !Constants that Excel uses
INCLUDE 'ERRORS.CLW' !Include errorcode constants
SaveLinks FILE,DRIVER('TopSpeed'),PRE(SAV),CREATE
Object BLOB
Record RECORD
LinkType STRING(1) !F = File, B = BLOB
LinkFile STRING(64) !OLE Compound Storage file name and object
END
END
i LONG !Loop counters
j LONG
ResultQ QUEUE !Queue to hold return from OLEDIRECTORY
Name CSTRING(64)
CLSID CSTRING(64)
ProgID CSTRING(64)
END
MainWin WINDOW('OLE Demo'),AT(,,350,200),STATUS(-1,-1),SYSTEM,GRAY,RESIZE,MAX,TIMER(1)
MENUBAR
MENU('&File')
ITEM('e&xit'),USE(?exit)
END
MENU('&Objects')
ITEM('Create Object'),USE(?CreateObject)
ITEM('Paste Object'),USE(?PasteObject)
ITEM('PasteLink Object'),USE(?PasteLinkObject)
ITEM('Save Object to BLOB'),USE(?SaveObjectBlob),DISABLE
ITEM('Save Object to OLE File'),USE(?SaveObjectFile),DISABLE
ITEM('Retrieve Saved Object'),USE(?GetObject),DISABLE
END
MENU('&Activate')
ITEM('&Spreadsheet'),USE(?ActiveExcel)
ITEM('&Any OLE Object'),USE(?ActiveOLE),DISABLE
END
END
OLE,AT(5,10,160,100),COLOR(0808000H),USE(?ExcelObject)
MENUBAR
MENU('&Clarion App')
ITEM('&Deactivate Excel'),USE(?DeactExcel)
END
END
END
OLE,AT(170,10,160,100),USE(?AnyOLEObject),AUTOSIZE
MENUBAR
MENU('&Clarion App')
ITEM('&Deactivate Object'),USE(?DeactOLE)
END
END
END
END
CODE
OPEN(SaveLinks)
IF ERRORCODE() !Check for error on Open
IF ERRORCODE() = NoFileErr !if the file doesn't exist
CREATE(SaveLinks) !then create it
IF ERRORCODE() THEN HALT(,ERROR()) END
OPEN(SaveLinks) !then open it for use
IF ERRORCODE() THEN HALT(,ERROR()) END
ELSE
HALT(,ERROR())
END
END
OPEN(MainWin)
?ExcelObject{PROP:Create} = 'Excel.Sheet.5' !Create an Excel spreadsheet object
DO BuildSheetData !populate it with some random data
IF RECORDS(SaveLinks) !Check for existing saved record
SET(SaveLinks) !and get it
NEXT(SaveLinks)
POST(EVENT:Accepted,?GetObject) !and display it
DO MenuEnable
ELSE
ADD(SaveLinks) !or add blank record
END
IF ERRORCODE() THEN HALT(,ERROR()) END
ACCEPT
CASE EVENT()
OF EVENT:CloseWindow
?ExcelObject{PROP:Deactivate} !Deactivate the OLE Server applications
?AnyOLEObject{PROP:Deactivate}
OF EVENT:Timer
IF CLIPBOARD()
IF ?AnyOLEObject{PROP:CanPaste} !Can Paste object from the clipboard?
IF ?PasteObject{PROP:Disable}
ENABLE(?PasteObject)
END
ELSIF NOT ?PasteObject{PROP:Disable}
DISABLE(?PasteObject)
END
IF ?AnyOLEObject{PROP:CanPasteLink} !Can PasteLink object from clipboard?
IF ?PasteLinkObject{PROP:Disable}
ENABLE(?PasteLinkObject)
END
ELSIF NOT ?PasteLinkObject{PROP:Disable}
DISABLE(?PasteLinkObject)
END
END
OF EVENT:Accepted
CASE FIELD()
OF ?Exit
POST(EVENT:CloseWindow)
OF ?CreateObject
OLEDIRECTORY(ResultQ,0) !Get a list of installed OLE Servers
?AnyOLEObject{PROP:Create} = SelectOleServer(ResultQ) !Let the user pick one
?AnyOLEObject{PROP:DoVerb} = 0 !Activate OLE Server in its default mode
DO MenuEnable
OF ?PasteObject
?AnyOLEObject{PROP:Paste} !Paste the object
SETCLIPBOARD('Paste Completed') !Assign non-object text to clipboard
DO MenuEnable
OF ?PasteLinkObject
?AnyOLEObject{PROP:PasteLink} !PasteLink the object
SETCLIPBOARD('PasteLink Completed') !Assign non-object text to clipboard
DO MenuEnable
OF ?SaveObjectBlob !Save object to BLOB
SAV:Object{PROP:Handle} = ?AnyOLEObject{PROP:Blob}
SAV:LinkType = 'B'
PUT(SaveLinks)
IF ERRORCODE() THEN STOP(ERROR()) END
OF ?SaveObjectFile !Save to OLE Compound Storage file
?AnyOLEObject{PROP:SaveAs} = 'TEST1.OLE\!Object'
SAV:LinkFile = 'TEST1.OLE\!Object'
SAV:LinkType = 'F'
PUT(SaveLinks)
IF ERRORCODE() THEN STOP(ERROR()) END
OF ?GetObject
IF SAV:LinkType = 'F' !Saved to OLE Compound Storage file?
?AnyOLEObject{PROP:Open} = SAV:LinkFile
ELSIF SAV:LinkType = 'B' !Saved to BLOB?
?AnyOLEObject{PROP:Blob} = SAV:Object{PROP:Handle}
END
DISPLAY
OF ?ActiveExcel
?ExcelObject{PROP:DoVerb} = 0 !In-place activate Excel
OF ?ActiveOLE
?AnyOLEObject{PROP:DoVerb} = 0 !Activate OLE Server in its default mode
OF ?DeactExcel
?ExcelObject{PROP:Deactivate} !Return to the Clarion application
OF ?DeactOLE
?AnyOLEObject{PROP:Deactivate} !Return to the Clarion application
END !CASE FIELD()
END !CASE EVENT0()
END !ACCEPT
BuildSheetData ROUTINE !Use OLE Automation to build spreadsheet
?ExcelObject{PROP:ReportException} = TRUE !Excel will report any errors
?ExcelObject{'Application.Calculation'} = xlManual !turn off auto recalc
LOOP i = 1 TO 3 !Fill Sheet with some values
LOOP j = 1 TO 3
?ExcelObject{'Cells(' & i & ',' & j & ').Value'} = Random(100,900)
END
?ExcelObject{'Cells(4,' & i & ').Value'} = 'Sum'
?ExcelObject{'Cells(5,' & i & ').FormulaR1C1'} = '=SUM(R[-4]C:R[-2]C)'
?ExcelObject{'Cells(6,' & i & ').Value'} = 'Average'
?ExcelObject{'Cells(7,' & i & ').FormulaR1C1'} = '=AVERAGE(R[-6]C:R[-4]C)'
END
!turn auto recalc back on
?ExcelObject{'Application.Calculation'} = xlAutomatic
DISPLAY
MenuEnable ROUTINE !Enable menu items
ENABLE(?ActiveOLE)
ENABLE(?SaveObjectBlob,?GetObject)
SelectOleServer PROCEDURE(OleQ PickQ)
window WINDOW('Choose OLE Server'),AT(,,122,159),CENTER,SYSTEM,GRAY
LIST,AT(11,8,100,120),USE(?List),HVSCROLL, |
FORMAT('146L~Name~@s64@135L~CLSID~@s64@20L~ProgID~@s64@'),FROM(PickQ)
BUTTON('Select'),AT(42,134),USE(?Select)
END
CODE
OPEN(window)
SELECT(?List,1)
ACCEPT
CASE ACCEPTED()
OF ?Select
GET(PickQ,CHOICE(?List))
IF ERRORCODE() THEN STOP(ERROR()) END
POST(EVENT:CloseWindow)
END
END
RETURN(PickQ.ProgID)
Interface Properties
PROP:Object | Gets the Dispatch interface for the object. (READ ONLY) |
In VB the toolbar and tree control use the image-list control to show icons in the tree control and on the buttons on the toolbar. To associate an image control with a toolbar, use the following code: | |
?toolbar{'ImageList'} = ?imagelist{prop:object} | |
PROP:SelectInterface | Selects the interface to use with the object. (WRITE ONLY) |
?x{PROP:SelectInterface} = 'x.y' | |
?x{'z(1)'} = 1 | |
?x{'z(2)'} = 2 | |
has the same meaning as | |
?x{'x.y.z(1)'} = 1 | |
?x{'x.y.z(2)'} = 2 | |
PROP:AddRef | Increments the reference count for an interface. (WRITE ONLY) |
PROP:Release | Decrements the reference count for an interface. (WRITE ONLY) |
Clarion OLE/OCX library and object hierarchies:
At the time of the design and implementation of the Clarion OLE library, the lack of access to secondary objects created by a primary object (example from excel: ExcelUse{'Application.Charts.Add'}), was not considered a problem as there were other ways of accessing the object(ExcelUse {'Application.Charts(Chart1).ChartWizard(' &?ex{'Range(A5:C5)'}&','&xl3DPie&',7,1,0,0,2,,,,)'})
At the time there was only one known instance where this was not the case. This is probably still true today as the OLE standard states that an object implement a collection, must also implement a method for accessing the objects by indexing.
Due to the special case mentioned above, when an object was created by one control and passed onto an other object as a parameter, a method which would be more or less transparent to the user, was implemented.
Calling a method which returns an IDispatchInterface is converted into a special representation (a '`' followed by a number of digits). This special representation is recognized in a couple of places in the OLE library.
The place that you will find most useful is, when the special representation is in the place where an interface could occur in the property syntax it will replace any previous interface in the access of the properties or methods of the object. For example:
x=y{'charts.add()')
y{x&'p(7)'}
where y is an ole object and x is a cstring. This is an example of a method returning an interface and later this interface is used to access a method p with the parameter 7.
In this context a further complication arises form the reference counting used in OLE. Which means that if the object are used more than once it must have it's reference count increased before use.
x=y{'charts.add()')
y{PROP:AddRef}=x
y{x&'p(7)'}
y{x&'p(7)'} ;last use of x