Chapter Contents |
Previous |
Next |
SAS Companion for the Microsoft Windows Environment |
OLE custom controls differ from other OLE objects in these ways:
OLE controls are packaged in their own dynamic linked library (with a file extension of OCX). Using SCL code, your FRAME entry can respond to events generated by the OLE control (mouse clicks, key presses, and so on). The events exposed by OLE controls vary among controls. For a list of events, see the documentation for the control you are using. After inserting the control into the FRAME entry, you can view the event map by selecting Object Attributes for the OLE control object and then Event Map.
Note: The OLE controls that SAS provides require 32-bit
containers, which makes them unusable with Windows applications that offer
only 16-bit container support. Also, because SAS is a 32-bit container, you
cannot use 16-bit controls with it.
Inserting an OLE Control in a FRAME Entry |
To insert an OLE control in a FRAME entry:
Registering OLE Controls |
If you want to install other controls for use with SAS or other applications, you must register the control with Windows (unless the control was installed by a process that performed the registration for you). The OLE control will not be available from the Insert Object dialog box until it is registered.
To register an OLE control:
When you click on [OK], the control is added to the list of registered controls in the Insert Object dialog box.
Accessing OLE Control Properties |
To invoke the properties page for a control, click on the right mouse button within the control's region in the BUILD: DISPLAY window and then select Properties from the pop-up menu. The properties page for the control appears. An Example Properties Page shows an example of a properties page for an OLE control.
OLE controls provide a Properties verb, which you can use with the _EXECUTE_ method in SCL to bring up the Properties page for the control. Or, you can access the pop-up menu for the control, then choose the cascading menu with the control's name. The Properties verb is available off that cascading menu.
You can use the properties page to view or change settings for some of the exposed properties.
Note that the control is not active (that is, you cannot
interact with its interface) while you are in DISPLAY mode. The control becomes
active in TESTAF mode.
Before you can access a property, you must know:
For example, suppose you have a combo box control named
sascombo
in your FRAME entry, and you want to set the list style to
simple
(represented
by the integer 1):
call notify ('sascombo', '_set_property_', 'Style', 1);
If you want to retrieve data from a property, you must use a variable that is of the same type as the data you want to read. For example, if you want to learn what text the user specified in the edit portion of a combo box, include the following code:
length text $ 200; call notify ('sascombo', '_get_property_', 'Text', text);
Interacting with the OLE Control Using SCL Methods |
call notify('sascombo', '_DO_', 'Clear');
length item $ 80; call notify('sascombo', '_COMPUTE_', 'GetItem', 2, item);When this call returns, item contains the text of the item at position 2 (the third item in the list).
Responding to OLE Control Events |
To assign SCL code to run when an OLE control event occurs:
Note: You can specify the same SCL source entry that
is stored with the FRAME entry; however, in addition to compiling the code
with the FRAME entry, you must also compile the SCL entry outside of the FRAME
context (that is, outside of the BUILD: SOURCE and BUILD: DISPLAY windows)
in order for the event handler to recognize the SCL label. Thus, it is more
efficient to store event-handling code for OLE controls in an SCL source entry
that is not associated with a FRAME entry.
Note: Many
OLE controls include a LostFocus
event, which
they generate when the control loses window focus. Because of the way that
SAS/AF software communicates with the control, mapping the LostFocus event
sometimes has the effect of placing focus back on the control that just lost
it. Although you can still respond to the LostFocus event in your FRAME entry,
be aware that this might cause unusual focus behavior.
Some OLE control events also include parameters you might find
useful. For example, the SAS ComboBox control generates a KeyPress event
that also reports the ASCII value of the key that was pressed. If a particular
event passes an argument back to the FRAME entry, the type of value returned
is indicated in the Event Map dialog box. A numeric value is indicated with
an
N
; a character value is indicated with a
C
.
To retrieve the value returned by an OLE control event, you must define a method (using the METHOD statement in SCL) in the event-handling code. In the argument list for the METHOD statement, specify a variable of the type that you expect the OLE control to return. This variable contains the value returned by the event. You can then use that variable as you wish inside your event-handler.
For example, suppose you want to retrieve the value of the key that triggered the KeyPress event in the SAS ComboBox control and then report it as an ASCII character. The KeyPress event returns an integer that represents the ASCII value of the key pressed. Your event-handling code would look like the following:
/* Label specified in Event Map dialog box */ KEYPRESS: /* Define a method with an integer argument */ method keyval 8; /* Convert the integer to an ASCII character */ keychar=byte(keyval); put keychar=; /* Output the character */ endmethod;
When mapping OLE control events, you can do one of the following:
The following example shows how to structure the SCL code when all events for an OLE control are mapped to a single label, which in turn runs the object's label to determine the event and act accordingly:
length event $ 80; /* All OLE control events are mapped to this label */ RUNLABEL: /* Call the object's label */ call send(_self_, '_OBJECT_LABEL_'); return; /* This is the label of the OLE control */ OBJ1: /* Determine the last event */ call notify('obj1', '_GET_EVENT_', event); select (event); when('Click') put 'Click received'; when('DblClick') put 'DblClick received'; otherwise put event=; end; return;
You can achieve this by creating a subclass of the OLE
class and adding methods to your derived class. When you insert the OLE control
into your FRAME entry, be sure to insert it as an instance of the new class
that you define (instead of OLE - Insert Object).
The examples provided here contain sample code you can use to abstract the
methods of a control. They do not include details about how to create subclasses.
For information about creating subclasses of a SAS/AF classes, see SAS/AF Software: FRAME Class Dictionary.
/* Add a new item to a ComboBox list. */ ADDITEM: method text $200 row 8 rc 8; /* adjust for zero-based index */ ocxrow = row-1; call send(_self_, '_COMPUTE_', 'AddItem', text, ocxrow, rc); if ( rc = 0 ) then _MSG_="ERROR: Could not add item to list."; endmethod;
Assuming you mapped this code to a new method called ADD_ITEM, you would use this syntax to add a new item to the control:
/* Adds 'Item 1' at the first position */ /* in the control */ length success 8; call notify('sascombo', 'ADD_ITEM', 'Item 1', 1, success);
FINDITEM: method text $200 row 8; call send(_self_, '_COMPUTE_', 'FindItem', text, row); row = row + 1; /* adjust for zero-based */ endmethod; /* index */
Assuming you mapped this code to the FIND_ITEM method, you would then use it as in this example:
length position 8; call notify('sascombo','FIND_ITEM', 'Lost Item', position);
GETTEXT: method text $200; call send(_self_, '_GET_PROPERTY_', 'Text', text); endmethod;
You would then access the Text property of a control the same way you access the text of other SAS/AF widget objects:
length text $ 200; call notify('sasedit', '_GET_TEXT_', text);
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.