The Windows Specific Classes

This section describes the Windows-specific classes supplied with ooRexx.

The Windows MenuObject Class

The MenuObject class provides methods to query, manipulate, and interact with the menu or submenu of a window.

Access to MenuObjects requires that the following directive appear in the Rexx program.

::requires 'winsystm.cls'

Methods the MenuObject Class Defines

isMenu

>>-isMenu------------------------------------------------------><

Returns 1 if the associated window is a menu, otherwise 0.

items

>>-items-------------------------------------------------------><

Returns the number of menu items contained in the associated menu.

idOf

>>-idOf--(--position--)----------------------------------------><

Returns the ID of the menu item at the specified position, starting with 0.

textOf(position)

>>-textOf--(--position--)--------------------------------------><

Returns the text of the menu item at the specified position, starting with 0. A mnemonic (underscored letter) is represented by a leading ampersand (&). If the menu item contains an accelerator, it is separated by a tab.

textOf(id)

>>-textOf--(--id--)--------------------------------------------><

Returns the text of menu item id. A mnemonic is represented by a leading ampersand (&). If the menu item contains an accelerator, it is separated by a tab.

submenu

>>-submenu--(--position--)-------------------------------------><

Returns an instance of the MenuObject class that is associated with the submenu at the specified position, starting with 0. If no submenu exists at this position, the .Nil object is returned.

Example:

sub = menu~submenu(5)
    if sub \= .Nil then do
         say "Items:" sub~items
    end

findSubmenu

>>-findSubmenu--(--label--)------------------------------------><

Returns an instance of the MenuObject class that is associated with the submenu with the specified label. If the associated menu does not contain such a submenu, the .Nil object is returned.

findItem

>>-findItem--(--label--)---------------------------------------><

Returns the ID of the menu item label. If the specified label does not include an accelerator, the comparison excludes the accelerators of the menu items. If no menu item is found that matches the specified label, 0 is returned.

Example:

f = menu~findItem("&Tools" || "9"x || "Ctrl+T")
    if f \= 0 then menu~processItem(f)

processItem

>>-processItem--(--id--)---------------------------------------><

Selects the menu item id. This causes a WM_COMMAND to be sent to the window owning the menu.

The Windows OLEObject Class

This class provides support for OLE automation. OLE (Object Linking and Embedding) is an implementation of COM (Component Object Model). OLE automation makes it possible for one application to manipulate objects implemented in another application, or to expose objects so they can be manipulated.

An automation client is an application that can manipulate exposed objects belonging to another application. An automation server is an application that exposes the objects. The OLEObject class enables Rexx to be an OLE automation client. Note that the OLE acronym has now been replaced by ActiveX.

Applications can provide OLE objects, and OLE objects that support automation can be used by a Rexx script to remotely control the object through the supplied methods. This lets you write a Rexx script that, for example, starts a Web browser, navigates to a certain page, and changes the display mode of the browser.

Every application that supports OLE places a unique identifier in the registry. This identifier is called the class ID (CLSID) of the OLE object. It consists of several hexadecimal numbers separated by the minus symbol.

Example: CLSID of Microsoft® Internet Explorer (Version 5.00.2014.0216):

"{0002DF01-0000-0000-C000-000000000046}"

The CLSID number can prove inconvenient when you want to create or access a certain object, so a corresponding easy-to-remember entry is provided in the registry, and this entry is mapped to the CLSID. This entry is called the ProgID (the program ID), and is a string containing words separated by periods.

Example: ProgID of Microsoft Internet Explorer: "InternetExplorer.Application"

To find the ProgID of an application, you can use the sample script OLEINFO.REX or the Microsoft OLEViewer, or you can consult the documentation of the application or search the registry manually.

The OLEObject class is a built-in class.

Several sample programs are provided in the Object Rexx installation directory under Samples\OLE.

Methods available to the OLEObject class:

dispatch
init
getConstant
getKnownEvents
getKnownMethods
getObject(Class method)
getOutParameters
unknown

Note: The Rexx OLE object acts as a proxy to the real OLE object. The OLE object has its own methods, depending on its individual implementation; its methods are accessed transparently through the method mechanism unknown.

dispatch

>>-dispatch(methodname--+------------+--)----------------------><
                        |  +------+  |
                        |  V      |  |
                        +----,arg-+--+

Dispatches a method with the optionally supplied arguments.

init

                    +-, "NOEVENTS"---+
>>-init(-+-ProgID-+-+----------------+-)-----------------------><
         +-CLSID--+ +-, "WITHEVENTS"-+

Instantiates an OLE object of the given ProgID or CLSID. If the creation fails, an error will be raised (see list of OLE specific errors.

The optional parameter "events" defines whether events are to be used or not. Allowed values for events are 'NOEVENTS' (the default) and 'WITHEVENTS'.

Example:

myOLEObject = .OLEObject~new("InternetExplorer.Application")

getConstant

>>-getConstant(-+--------------+-)-----------------------------><
                +-ConstantName-+

Retrieves the value of a constant that is associated with this OLE object. If no constant of that name exists, the .Nil object will be returned. You can also omit the name of the constant; this returns a stem with all known constants and their values. In this case the constant names will be prefixed with a "!" symbol.

Example 1:

myExcel = .OLEObject~new("Excel.Application")
say "xlCenter has the value" myExcel~getConstant("xlCenter")
myExcel~quit
exit

Possible output:

xlCenter has the value -4108

Example 2:

myExcel = .OLEObject~new("Excel.Application")
constants. = myExcel~getConstant
myExcel~quit

do i over constants.
  say i"="constants.i
end

Possible output:

!XLFORMULA=5
!XLMOVE=2
!XLTEXTMAC=19
...

getKnownEvents

>>-getKnownEvents----------------------------------------------><

Returns a stem with information on the events that the OLE object can create. It collects this information from the type library of the object. A type library provides the names, types, and arguments of the provided methods.

The stem provides the following information:

Table 5-1. Stem Information

stem.0The number of events.
stem.n.!NAMEName of n-th event.
stem.n.!DOCDescription of n-th event (if available).
stem.n.!PARAMS.0Number of parameters for n-th event.
stem.n.!PARAMS.i.!NAMEName of i-th parameter of n-th event.
stem.n.!PARAMS.i.!TYPEType of i-th parameter of n-th event.
stem.n.!PARAMS.i.!FLAGSFlags of i-th parameter of n-th event; can be "in", "out", "opt", or any combination of these.

If no information is available, the .NIL object is returned and this OLE object does not have any events.

Example script:

myIE = .OLEObject~new("InternetExplorer.Application","NOEVENTS")
events. = myIE~getKnownEvents

if events. == .nil then
  say "Sorry, this object does not have any events."
else do
  say "The following events may occur:"
  do i = 1 to events.0
    say events.i.!NAME
  end
end

exit

Sample output:

The following events may occur:
ONTHEATERMODE
ONFULLSCREEN
ONSTATUSBAR
...

For an example of how to use events, see examples OLE\APPS\SAMP12.REX and OLE\APPS\SAMP13.REX in the SAMPLES directory.

getKnownMethods

>>-getKnownMethods---------------------------------------------><

Returns a stem with information on the methods that the OLE object supplies. It collects this information from the type library of the object. A type library provides the names, types, and arguments of the provided methods. Parts of the supplied information have only informational character as you cannot use them directly.

The stem provides the following information:

Table 5-2. Stem Information

stem.0The number of methods.
stem.!LIBNAMEName of the type library that describes this object.
stem.!LIBDOCA help string describing the type library. Only set when the string is available.
stem.!COCLASSNAMECOM class name of this object.
stem.!COCLASSDOCA string describing the COM class. Only set when the string is supplied by the type library.
stem.n.!NAMEThe name of the n-th method.
stem.n.!DOCA help string for the n-th method. If this information is not supplied in the type library this value will not be set.
stem.n.!INVKINDA number that represents the invocation kind of the method: 1 = normal method call, 2 = property get, 4 = property put. A normal method call is used with brackets; for a property get only the name is to be specified; and a property set uses the "=" symbol, as in these examples: object~methodCall(a,b,c) object~propertyPut="Hello" say object~propertyGet
stem.n.!RETTYPEThe return type of the n-th method. The return type will be automatically converted to a Rexx object (see Type Conversion in the description of the UNKNOWN method of the OLEObject class).
stem.n.!MEMIDThe MemberID of the n-th method. This is only used internally to call the method.
stem.n.!PARAMS.0The number of parameters of the n-th method.
stem.n.!PARAMS.i.!NAMEThe name of the i-th parameter of the n-th method.
stem.n.!PARAMS.i.!TYPEThe type of the i-th parameter of the n-th method.
stem.n.!PARAMS.i.!FLAGSThe flags of the i-th parameter of the n-th method; can be "in", "out", "opt", or any combination of these (for example: "[in, opt]").

If no information is available, the .NIL object is returned.

Note: An object might provide additional methods that cannot be retrieved for display but that can be invoked. In these cases, consult the documentation of those objects.

There are mechanisms to 'hide' methods from the user, because these methods can only be used internally. It might happen that these are not hidden properly and will get displayed. Be careful with methods like:

AddRef
GetTypeInfoCount
GetTypeInfo
GetIDsOfNames
QueryInterface
Release

Example script:

myOLEObject = .OLEObject~new("InternetExplorer.Application")
methods. = myOLEObject~getKnownMethods

if methods. == .nil then
  say "Sorry, no information on the methods available!"
else do
  say "The following methods are available to this OLE object:"
  do i = 1 to methods.0
    say methods.i.!NAME
  end
end

exit

Sample output:

The following methods are available to this OLE object:
GoBack
GoForward
GoHome
...

getObject

>>-getObject(Moniker-+--------+-)------------------------------><
                     +-,class-+

This is a class method that allows you to obtain an OLE object through the use of a so-called moniker or nickname (a string). A moniker is used to find out which object has to be created or, if it is already running, addressed. The moniker itself tells OLE which type of object is required. The optional parameter class can be used to specify a subclass of OLEObject, and can be used to obtain an OLE object that supports events (the 'WITHEVENTS' option will be used in this case). This method is similar to the Init method where you have to specify a ProgID or CLSID.

Example:

/* create a Word.Document by opening a certain file */
myOLEObject = .OLEObject~GetObject("C:\DOCS\HELLOWORLD.DOC")

getOutParameters

>>-getOutParameters--------------------------------------------><

Returns an array containing the results of the single out parameters of the OLE object, or the .NIL object if it does not have any. Out parameters are arguments to the OLE object that are filled in by the OLE object. As this is not possible in Rexx due to data encapsulation, the results are placed in the array mentioned above.

Example:

Consider an OLE object method with the following signature:

aMethod([in] A, [in] B, [out] sumAB)

The resulting out parameter of the method invocation will be placed in the out array at position one; the "normal" return value gets processed as usual. In this case the method will return the .NIL object:

resultTest = myOLEObject~aMethod(1, 2, .NIL)
say "Invocation result  :" resultTest
say "Result in out array:" myOLEObject~getOutParameters~at(1)

The output of this sample script will be:

The NIL object
3

Out parameters are placed in the out array in order from left to right. If the above OLE method looked like this:

aMethod([in] A, [in] B, [out] sumAB, [out] productAB),

then the out array would contain the sum of A and B at position one, and the product at position two.

unknown

>>-unknown(messagename--+----------------+--)------------------><
                        +--,messageargs--+

The unknown message is the central mechanism through which methods of the OLE object are called.

For further information, see Defining an unknown Method.

You can invoke the methods of the real OLE object by simply stating their names to the Rexx (proxy) OLE object like this:

myOLEObject~OLEMethodName

This calls the method "OLEMethodName" of the real OLE object for any message that does not exist for the Rexx OLE object by dispatching the call to the real OLE object.

If an OLE object offers a method with a name that is identical to one that is defined for OLEObject, you must call unknown directly, like this:

msgs = .array~of("Hello","World")
val = myOLEObject~unknown("Unknown",msgs)

This invokes the method "unknown" of the OLE object with two arguments, "Hello" and "World".

Parameters for the OLE object are used in the usual way, with the exception of so-called "out" parameters. Out parameters will be filled in by the OLE object itself. As this is not possible in Rexx due to data encapsulation, a special method, getOutParameters, has to be used. Specify the .Nil object for any Out parameters when invoking this method.

Type Conversion

Unlike Rexx, OLE uses strict typing of data. Conversion to and from these types is done automatically, if conversion is possible. OLE types are called variants, because they are stored in one structure that gets flagged with the type it represents. The following is a list of all variant types valid for use with OLE Automation and the Rexx objects that they are converted from or into.

Table 5-3. OLE/Rexx Types

VARIANT typeRexx object
VT_EMPTY.NIL
VT_NULL.NIL
VT_ERROR.NIL
VT_I1Rexx string (a whole number)
VT_I2Rexx string (a whole number)
VT_I4Rexx string (a whole number)
VT_I8Rexx string (a whole number)
VT_UI1Rexx string (a whole, positive number)
VT_UI2Rexx string (a whole, positive number)
VT_UI4Rexx string (a whole, positive number)
VT_UI8Rexx string (a whole, positive number)
VT_INTRexx string (a whole number)
VT_UINTRexx string (a whole, positive number)
VT_DECIMALRexx string (a decimal number)
VT_R4Rexx string (a real number)
VT_R8Rexx string (a real number)
VT_CYRexx string (currency, a fixed-point number with 15 digits to the left of the decimal point and 4 digits to the right)
VT_DATERexx string (a date)
VT_BSTRRexx string
VT_DISPATCH RexxOLEObject
VT_BOOL.TRUE or .FALSE
VT_VARIANTAny Rexx object that can be represented as a VARIANT
VT_UNKNOWNOLEObject
VT_ARRAY *Rexx Array
VT_BYREF *Any Rexx object

* VT_ARRY and VT_BYREF are combined with any of the other variant types and never used alone. VT_ARRAY and another variant type are used for a SAFEARRAY datatype, an array of the other variant type. VT_BYREF and another variant type are used to pass the other variant type to or from an OLE object by reference. The programmer need not worry about this passing by reference, the OLE support handles this transparently.

The Windows OLEVariant Class

The OLEVariant class enhances the support for OLE Automation provided by the OLEObject class and is used in conjunction with that class. An OLEVariant object is used as a parameter in a method call of an OLEObject object. In the OLEObject's role as a proxy for a OLE / COM object, the parameters in method calls are forwarded on to the actual OLE / COM object. (OLE / COM objects will be referred to simply as COM objects.)

There are two areas where the OLEVariant adds to the capabilities of OLEObject method calls.

In general, the automatic type conversion in the OLE support uses type libraries to determine how to format the parameters being sent to an OLE object in a method call. The information in a type library specifies the variant type an ooRexx object, used as a parameter, needs to be converted to. Type libraries also detail how a parameter is to be flagged when it is sent to the COM object.

However, COM objects are not required to supply type libraries. When there is no type library, ooRexx uses an educated guess to determine this information. On rare occasions this guess is wrong and the method call fails. In theses cases, if the ooRexx programmer knows what the correct information is, the programmer can use an OLEVariant to specify this information. The programmer can supply either or both of these pieces of information by specifying the variant type for the converted ooRexx object and the parameter flags.

The following is a real world example where the automatic conversion in the OLE support does not work and shows how the OLEVariant is used to specify the correct conversion. The snippet comes from code to automate a CICS client. In this case the variant type that the ooRexx object needs to be converted to is specified. The parameter flags are omitted. The fourth parameter to the ~link method call is the parameter where the default conversion was failing.

  connect  = .OLEObject~new("Ccl.Connect")
  flow     = .OLEObject~new("Ccl.Flow")
  buffer   = .OLEObject~new("Ccl.Buffer")

  uow      = .OLEVariant~New(.nil, VT_DISPATCH)
  ...
  connect~link(flow, "FOO", buffer, uow)

Note: It is extremely rare that the OLE support fails to do the right thing with its automatic conversion. 99.999% of the time the ooRexx programmer does not need to use an OLEVariant object to specify the type conversion. This use of the OLEVariant is provided for those few times when it is necessary to override the default conversion. Furthermore, if the ooRexx programmer does not know what variant type to specify, this usage will not be much help. Normally the ooRexx programmer would know what type to specify through the documentation for the COM class the programmer is using.

The next example shows how the OLEVariant can be used to transport the data returned in an "out" parameter back to the calling ooRexx program. This usage will be more common and does not require that the ooRexx have a lot of detailed knowledge of the COM object. Obviously, the programmer does need to know that the parameter is an out parameter. This example comes from updating a MS Access database where the number of records affected by the update is returned in an "out" parameter. Here the out parameter is the second parameter in the ~execute method call.

  sql = "update myTable set id=id*3 where id > 7"
  param = .OLEVariant~new(0)
  conn~execute(sql, param)
  count = param~!varValue_
  say count "record(s) were affected."

Finally an example where the OLE support does not use the correct parameter flags for the method call. The Windows Management Instrumentation, Win32_Process COM class does not supply a type library. The fourth parameter in the ~create method call is an "out" parameter. That information is known by the ooRexx programmer through the documentation of the class. However, without a type library, ooRexx has no way to know that. Here the variant type specification is omitted (signaling ooRexx to go ahead and use its automatic conversion) and the parameter flags are specified. Since this an out parameter, the OLEVariant object is also used to transport the returned data back to the calling program.

  objProcess = .oleObject~getObject("WinMgmts:Win32_Process")

  param = .OLEVariant~new( 0, , "IN,OUT" )
  ret = objProcess~create('notepad.exe', .nil, .nil, param)
  if ret == 0 then do
    pid = param~!varValue_
    say 'The notepad process was created and its PID is' pid
  end

Methods available to the OLEVariant class

new
!varValue_
!varValue_=
!varType_
!varType_=
!paramFlags_
!paramFlags_=

Note: A possible future enhancement of the OLEVariant class requires that its method names be unique, which is the reason for the method name style. In normal usage the ooRexx programmer would only be concerned with the new and the !varValue methods. Therefore the slightly unorthodox method names should not present a problem.

new Class method

>>-new(valueObject-+----------+--+-------------+-)-------------><
                   +-,varType-+  +-,paramFlags-+

Instantiates a new OLEVariant object to be used as a parameter in an OLEObject method call. The first argument is the ooRexx object to be converted to a variant type for the method call. It is the object to be used in the method call. This argument is required. The varType and paramFlags arguments are optional.

The varType argument is used to specify the type of the variant that the valueObject is to be converted to. If this argument is omitted or is .nil then ooRexx will use the default conversion for the valueObject. If it is not omitted it must be a valid OLE Automation variant type and ooRexx will attempt to convert the valueObject to this variant type.

The valid variant type symbols are listed in Table OLE/Rexx Types. In addition any of those symbols can be combined with the VT_BYREF or the VT_ARRAY symbol. When symbols are combined a comma is used to separate the two symbols. This of course necessitates that the argument be quoted. Case does not matter for this argument. For example vt_bool, VT_bool, or VT_BOOL are all treated the same.

The paramFlags argument is used to specify the flags for the parameter. The flags are separated by a comma. Although any combination of valid PARAMFLAGS as defined for OLE Automation will be accepted, in practice the ooRexx programmer will probably only need to use "IN,OUT" for this argument.

The PARAMFLAGS defined for OLE Automation:

PARAMFLAG_NONE
PARAMFLAG_FIN
PARAMFLAG_FOUT
PARAMFLAG_FLCID
PARAMFLAG_FRETVAL
PARAMFLAG_FOPT
PARAMFLAG_FHASDEFAULT
PARAMFLAG_FHASCUSTDATA

The ooRexx programmer should only use the last portion of the symbol. I.e., NONE, IN, OUT, LCID, RETVAL, OPT, HASDEFAULT, or HASCUSTOMDATA. Case also does not matter for this argument and "in,out" is equivalent to "IN,OUT"

If the paramFlags argument is omitted or .nil, (the normal case,) ooRexx will determine the flags for the parameter through its default mechanism. If the argument is not omitted, ooRexx will use the specified flags unconditionally.

Note: If either the varType or paramFlags arguments are used, and not the .nil object, they must be valid variant types or param flags for OLE Automation. If they are not valid, a syntax error will be raised.

manager = .oleObject~new("com.sun.star.ServiceManager", "WITHEVENTS")
cf = manager~createInstance("com.sun.star.reflection.CoreReflection")
...
classSize = .cf~forName("com.sun.star.awt.Size")

param = .OLEVariant~new(.nil, "VT_DISPATCH,VT_BYREF", "IN,OUT")

retVal = classSize~createObject(param)

!VARVALUE_

>>-!VARVALUE_--------------------------------------------------><

Returns the value object set within an instance of an OLEVariant. If the parameter in a COM method call that the OLEVariant was used for is an "out" parameter, than the value object of the instance will be the data returned by the COM object. Otherwise, the value object is that set by the ooRexx programmer.

manager = .oleObject~new("com.sun.star.ServiceManager", "WITHEVENTS")
cf = manager~createInstance("com.sun.star.reflection.CoreReflection")
...
classSize = .cf~forName("com.sun.star.awt.Size")

param = .OLEVariant~new(.nil, "VT_DISPATCH,VT_BYREF", "IN,OUT")

retVal = classSize~createObject(param)
size = param~!varValue_

!VARVALUE_=

>>-!VARVALUE_=-------------------------------------------------><

Sets the value object an instance of an OLEVariant contains.

!VARTYPE_

>>-!VARTYPE_---------------------------------------------------><

Returns the variant type specification of the OLEVariant instance.

!VARTYPE_=

>>-!VARTYPE_=--------------------------------------------------><

Sets the variant type specification of an OLEVariant instance. This serves the same purpose as the second argument to the new method and follows the same rules as specified in the documentation of the new method. I.e., the value must be a valid variant type used in OLE Automation, or .nil. If not a syntax error is raised.

!PARAMFLAGS_

>>-!PARAMFLAGS_------------------------------------------------><

Returns the parameter flags specification of the OLEVariant instance.

!PARAMFLAGS_=

>>-!PARAMFLAGS_=-----------------------------------------------><

Sets the flags specification of an OLEVariant instance. This serves the same purpose as the third argument to the new method and follows the same rules as specified in the documentation of the new method. I.e., the value must be a valid combination of PARAMFLAG types as documented for use in OLE Automation, or .nil. If not a syntax error is raised.

The WindowsClipboard Class

The WindowsClipboard class provides methods to access the data in the Windows clipboard.

The WindowsClipboard class is not a built-in class. It is defined in the WINSYSTM.CLS file. This means, you must use a ::requires statement to activate its functionality, as follows:

::requires "WINSYSTM.CLS"

Methods the WindowsClipboard Class Defines

copy

>>-copy--(--text--)--------------------------------------------><

Empties the clipboard and copies the specified text to it.

makeArray

>>-makeArray---------------------------------------------------><

If the content of the clipboard is a string with newline characters in it, makeArray can be used to split up the string into individual lines. An array is returned containing those lines.

paste

>>-paste-------------------------------------------------------><

Retrieves the text data stored on the clipboard.

empty

>>-empty-------------------------------------------------------><

Empties the clipboard.

isDataAvailable

>>-isDataAvailable---------------------------------------------><

Returns 1 if the text data is available on the clipboard. If no data is available, 0 is returned.

The WindowsEventLog Class

Object Rexx provides a class for interaction with the Windows NT event log. You can use this class to read, write, and clear event-log records. This class is specifically for Windows NT systems and might not be available on other systems.

The WindowsEventLog class is not a built-in class; it is defined in the file WINSYSTM.CLS. Use a ::requires statement to activate its function:

::requires "winsystm.cls"

A sample program EventLog.REX is provided in the ooRexx\SAMPLES directory.

Methods the WindowsEventLog Class Defines

init

>>-init--------------------------------------------------------><

Creates an instance of the WindowsEventLog class and loads the required function package.

open

>>-open-+---------------------------------+--------------------><
        +-(--+-----------------------+--)-+
             +-server--+-----------+-+
                       +-,--source-+

Opens the specified event log.

Arguments:

The arguments are:

server

The UNC (universal naming convention) name of the server on which the event log is to be opened. If this argument is not specified, the log is opened at the local machine.

source

The name of the source of the event log. It must be a subkey of a log file entry under the EventLog key in the registry. If, for example, the registry looks as follows:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
      EventLog
        Application
          WinApp1
        Security
          WinApp2
        System
"Application", "Security", "System", "WinApp1", and "WinApp2" are valid sources. If the source is not found, the "Application Log" is used.

Example:

The following example opens the Application log on the local machine:

rc = event_log1~open
rc = event_log~open(,"Application")

The following example opens the System log on SERVER01:

rc = event_log~open("\\SERVER01","System")

close

>>-close-------------------------------------------------------><

Closes an open event log.

read

>>-read--+---------------------------------------------------+-->
         |    +-FORWARDS--+                                  |
         +-(--+-----------+--,--+--------+--,--+--------+--,-+
              +-BACKWARDS-+     +-server-+     +-source-+

>--+--------------------------+--------------------------------><
   +-+-------+--,--+-----+--)-+
     +-start-+     +-num-+

Reads event log records. If the event log was not opened with the OPEN method, the event log specified by the server and source is opened and closed after processing.

Arguments:

The arguments are:

server

The UNC (universal naming convention) name of the server on which the event log is to be opened. If this argument is not specified, the log is opened at the local machine.

This argument is only used if the event log was not opened before.

source

The name of the source of the event log. It must be a subkey of a log file entry under the EventLog key in the registry. If, for example, the registry looks as follows:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
      EventLog
        Application
          WinApp1
        Security
          WinApp2
        System
"Application", "Security", "System", "WinApp1", and "WinApp2" are valid sources. If the source is not found, the "Application Log" is used.

This argument is only used if the event log was not opened before.

start

The record number of the event log record to be started. The oldest record is always the first record regardless of the direction specified.

num

The number of the event log record to be read.

Example:

evl = .WindowsEventLog~new

if evl~InitCode \= 0 then exit

say " reading complete System log forwards without opening it before "

events = evl~read("FORWARDS", ,"System")

if events \= .nil then
  call DisplayRecords
else
  say "==> Error reading complete System event log"

evl~deinstall

exit 0   /* leave program */

DisplayRecords:

say evl~Events~items "records read"

do i=1 to evl~Events~items
  say "============================================================="
  temp = evl~Events[i]
  parse var temp type date time "'" sourcename"'" id,
  userid computer "'" string "'" "'" data "'"
  say "Type	: "type
  say "Date	: "date
  say "Time	: "time
  say "Source	: "sourcename
  say "ID	: "id
  say "UserId	: "userid
  say "Computer : "computer
  say "Detail	: "string
  say "Data 	: "data
end
return

::requires "winsystm.cls"

write

>>-write--+-------------------------------------------------------------+-->
          |                                  +-1--+     +-0--------+    |
          +-(--+--------+--,--+--------+--,--+----+--,--+----------+--,-+
               +-server-+     +-source-+     +-0--+     +-category-+
                                             +-2--+
                                             +-4--+
                                             +-8--+
                                             +-10-+

>--+---------------------------------------+-------------------><
   | +-0--.                                |
   +-+----+--,--+------+--,--+--------+--)-+
     +-id-+     +-data-+     +-string-+

Reads event log records. If the event log was not opened with the Open method, the event log specified by the server and source is opened and closed after processing.

Arguments:

The arguments are:

server

The UNC (universal naming convention) name of the server on which the event log is to be opened. If this argument is not specified, the log is opened at the local machine.

source

The name of the source of the event log. It must be a subkey of a log file entry under the EventLog key in the registry. If, for example, the registry looks as follows:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
      EventLog
        Application
          WinApp1
        Security
          WinApp2
        System
"Application", "Security", "System", "WinApp1", and "WinApp2" are valid sources. If the source is not found, the "Application Log" is used.

type

The type of the events to be logged. It can be one of the numbers listed in the syntax diagram:

0

SUCCESS

1

ERROR, which is the default

2

WARNING

4

INFORMATION

8

AUDIT SUCCESS

10

AUDIT FAILURE

category

The event category. This is source-specific information that can have any value. The default is 0.

id

The event identifier specifying the message that, together with the event, is an entry in the message file associated with the event source. The default is 0.

data

The binary data. This is source-specific information and can be omitted.

string

The strings merged into the message.

Example:

The following example writes the strings and the data to the system log. "MyApplication" must be a subkey of a log file entry under the EventLog key in the registry. If the source name cannot be found, event logging uses the Application log file.

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
        EventLog
        Application
        Security
          System
            MyApplication
	    
evl~Write(,"MyApplication", , , ,"1A 1B 1C 0000 00"x, ,
"First String", "Second String")

See the EventLog.REX for more examples.

clear

>>-clear-+------------------------------------------------------------+-><
         +-(--+--------------------------------------------------+--)-+
              +-server--+--------------------------------------+-+
                        +-,--+--------+--+-------------------+-+
                             +-source-+  +-,--backupFileName-+

Clears the specified event log and, optionally, saves a copy of the current log file as a backup file. If the event log was not opened with the Open method, the event log specified by the server and source is opened. The event log is closed after it is cleared.

Arguments:

The arguments are:

server

The UNC (universal naming convention) name of the server on which the event log is to be opened. If this argument is not specified, the log is opened at the local machine.

This argument is only used if the event log was not opened before.

source

The name of the source of the event log. It must be a subkey of a log file entry under the EventLog key in the registry. If, for example, the registry looks as follows:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
      EventLog
        Application
          WinApp1
        Security
          WinApp2
        System
"Application", "Security", "System", "WinApp1", and "WinApp2" are valid sources. If the source is not found, the "Application Log" is used.

This argument is only used if the event log was not opened before.

backupFileName

The name of a file to which the copy of the current event log file is to be written. If this file already exists, the function fails. The file can reside on a remote server.

If you omit this argument, the current event log file is not backed up but cleared.

Example:

The following example creates a backup of the Application event log of the local machine and clears it:

event_log~CLEAR(, ,"e:\evlbackup\application.evt")

The following example creates a backup of the System event log on the server \\SERVER01 and clears it:

event_log~CLEAR("\\SERVER01","System","e:\evlbackup\system_server01.evt")

The following example clears the Application log on the local machine without a backup:

event_log~CLEAR

getNumber

>>-getNumber-+---------------------------------+---------------><
             +-(--+-----------------------+--)-+
                  +-server--+-----------+-+
                            +-,--source-+

Retrieves the number of records in the specified event log. If the event log was not opened with the Open method, the event log specified by the server and source is opened and closed after processing.

Arguments:

The arguments are:

server

The UNC (universal naming convention) name of the server on which the event log is to be opened. If this argument is not specified, the log is opened at the local machine.

This argument is only used if the event log was not opened before.

source

The name of the source of the event log. It must be a subkey of a log file entry under the EventLog key in the registry. If, for example, the registry looks as follows:

HKEY_LOCAL_MACHINE
  System
    CurrentControlSet
      Services
      EventLog
        Application
          WinApp1
        Security
          WinApp2
        System
"Application", "Security", "System", "WinApp1", and "WinApp2" are valid sources. If the source is not found, the "Application Log" is used.

This argument is only used if the event log was not opened before.

Example:

The following example returns the number of event log records in the Application log of the local machine:

num = event_log~getNumber

The WindowsManager Class

The WindowsManager class provides methods to query, manipulate, and interact with windows on your desktop. This class is specifically for Windows NT and Windows 2000 systems and might not be available on other systems.

The WindowsManager class is not a built-in class; it is defined in the file WINSYSTM.CLS. Use a ::requires statement to activate its function:

::requires "winsystm.cls"

Methods the WindowsManager Class Defines

find

>>-find--(--title--)-------------------------------------------><

Searches for a top-level window (not a child window) on your desktop with the specified title.

If this window already exists, an instance of the WindowObject class is returned. Otherwise, .Nil is returned.

foregroundWindow

>>-foregroundWindow--------------------------------------------><

Returns an instance of the WindowObject class that is associated with the current foreground window.

windowAtPosition

>>-windowAtPosition--(--x--,--y--)-----------------------------><

Returns an instance of the WindowObject class that is associated with the window at the specified position (x,y). The coordinates are specified in screen pixels. This method does not retrieve hidden or disabled windows. If you are interested in a particular child window, use method childAtPosition.

consoleTitle

>>-consoleTitle------------------------------------------------><

Returns the title of the current console.

consoleTitle=

>>-consoleTitle=title------------------------------------------><

Sets the title of the current console.

sendTextToWindow

>>-sendTextToWindow--(--title--,--text--)----------------------><

Sends a case-sensitive text to the window with the specified title..

pushButtonInWindow

>>-pushButtonInWindow--(--title--,--text--)--------------------><

Selects the button with label text in the window with the specified title. If the button's label contains a mnemonic (underscored letter), you must specify an ampersand (&) in front of it. You can also use this method to select radio buttons and to check or uncheck check boxes.

Example:

winmgr~pushButtonInWindow("Testwindow","List &Employees")

processMenuCommand

>>-processMenuCommand--(--+-------+--,--+-------+--,------------>
                          +-title-+     +-popup-+

   +-,-------+
   V         |
>----submenu-+--,--menuItem--)---------------------------------><

Selects an item of the menu or submenu of the specified window title. You can specify as many submenus as necessary to get to the required item.

broadcastSettingChanged

>>-broadcastSettingChanged--+-----------+----------------------><
                            +-(timeOut)-+

Causes the Windows operating system to send a message, (the WM_SETTINGCHANGE message,) to every top-level window on the Desktop informing them that a system-wide setting has changed. Well-written applications will then reload any system settings that they use.

An example of one use for this might be an installer program setting an environment variable, such as the PATH. Then a call to broadcastSettingChanged would cause all open applications to update their reference to the environment, without the necessity of a reboot.

There are two variations of calling this method. When called with no arguments, the message is broadcast and returns immediately. When called with the time out parameter, the message is broadcast and does not return until every window on the Desktop has acknowledged the message, or timed out.

The problem with using a time out and waiting for acknowledgment is that, if a window is not responding, or several windows are slow to respond, it may take a very long time to return. The problem with not using a time out and returning immediately is that the caller will have no way of knowing when every window has received the message. Generally this is not a problem, but it is up to the programmer to decide how she wants to use this method.

The time out value is specified in milliseconds. For each window, the operating system will wait up to the time out for a response before going on to the next window. Typically a time out value of 5000 (5 seconds) is used, and this is the default.

The single optional argument is:

timeOut

The time, in milliseconds, to wait for each window to acknowledge it received the setting changed message. Specifying 0 or a negative number will cause the default time out of 5000 to be used. (5000 is a typical value used by applications.)

Return value:

0

The setting changed message was broadcast successfully. If no time out argument was used, then this is all it means. If a time out value was used, then all top-level windows have acknowledged receiving the message.

-1

The setting changed message was broadcast, but one or more windows timed out. This return can only happen when the time out parameter is used.

-x

A number less than -1 indicates a system error occurred. This value is the negation of the system error code. I.e., if the return is -1400, the system error code was 1400. System error codes can be looked up in the MSDN library or the Windows Platform SDK. Microsoft makes these references available on the Internet.

+x

A number greater than 0 would be a window result of broadcasting the setting changed message and would not be an error. It is unlikely that this would occur.

Example:

ret = winmgr~broadcastSettingChanged(1000)

The WindowObject Class

The WindowObject class provides methods to query, manipulate, and interact with a particular window or one of its child windows.

Access to WindowObjects requires that the following directive appear in the Rexx program.

::requires 'winsystm.cls'

The WindowsObject class is designed to be primarily used in conjucture with the WindowsManager class. The WindowsManager class will obtain the handle of an actual window and instantiate a WindowObject instance. Because of this, the WindowObject does not regiser the C functions that are required for it to behave correctly. (The WindowsManager class has already registered the functions.) Therefore, if the programmer uses the WindowObject outside of the context of the WindowsManager, she needs to ensure that the C functions get registered before using an instance of the WindowObject.

There are a couple of approaches that could be used here. Perhaps the simplest is to instantiate a WindowsManager object prior to using a WindowObject instance. The WindowsManage instance does not have to be used, the act of creating a new object causes the C functions to be registered. The following code snippet comes from an ooDialog program. The following code does not work, because the C functions needed by a WindowObject will not have benn registered:


::method Cancel

   handle = self~get()
   winObj = .WindowObject~new(handle)
   state = winObj~state~translate

   -- Do not save the size/position if the dialog is Minimized or Maximized
   if state~wordPos('MINIMIZED') = 0 & state~wordPos('ZOOMED') = 0 then
   ...
return self~ok:super

The following is a simple way to fix this situation:


::method Cancel

   unusedObj = .WindowsManager~new

   handle = self~get()
   winObj = .WindowObject~new(handle)
   state = winObj~state~translate

   -- Do not save the size/position if the dialog is Minimized or Maximized
   if state~wordPos('MINIMIZED') = 0 & state~wordPos('ZOOMED') = 0 then
   ...
return self~ok:super

The programmer can also load the C functions herself to get the correct behavior from the WindowObject:


::method Cancel

   if RxFuncQuery("InstWinSysFuncs") \= 0 then do
      if RxFuncAdd("InstWinSysFuncs","RXWINSYS.DLL","InstWinSysFuncs") = 0 then
         InstWinSysFuncs()
      else
         return self~ok:super   -- Unexpected error, just quit
   end

   -- Okay, we have the needed C functions, continue.

   handle = self~get()
   winObj = .WindowObject~new(handle)
   state = winObj~state~translate

   -- Do not save the size/position if the dialog is Minimized or Maximized
   if state~wordPos('MINIMIZED') = 0 & state~wordPos('ZOOMED') = 0 then
   ...
return self~ok:super

Methods the WindowObject Class Defines

assocWindow

>>-assocWindow--(--handle--)-----------------------------------><

Assigns a new window handle to the WindowObject instance.

handle

>>-handle------------------------------------------------------><

Returns the handle of the associated window.

title

>>-title-------------------------------------------------------><

Returns the title of the window.

title=

>>-title=newTitle----------------------------------------------><

Sets a new title for the window.

wclass

>>-wclass------------------------------------------------------><

Returns the class of the window associated with the WindowObject instance.

id

>>-id----------------------------------------------------------><

Returns the numeric ID of the window.

coordinates

>>-coordinates-------------------------------------------------><

Returns the upper left and the lower right corner positions of the window in the format "left,top,right,bottom".

state

>>-state-------------------------------------------------------><

Returns information about the window state. The returned state can contain one or more of the following constants:

  • "Enabled" or "Disabled"

  • "Visible" or "Invisible"

  • "Zoomed" or "Minimized"

  • "Foreground"

restore

>>-restore-----------------------------------------------------><

Activates and displays the associated window. If the window is minimized or maximized, it is restored to its original size and position.

hide

>>-hide--------------------------------------------------------><

Hides the associated window and activates another window.

minimize

>>-minimize----------------------------------------------------><

Minimizes the associated window and activates the next higher-level window.

maximize

>>-maximize----------------------------------------------------><

Maximizes the associated window.

resize

>>-resize--(--width--,--height--)------------------------------><

Resizes the associated window to the specified width and height. The width and height are specified in screen coordinates.

enable

>>-enable------------------------------------------------------><

Enables the associated window if it was disabled.

disable

>>-disable-----------------------------------------------------><

Disables the associated window.

moveTo

>>-moveTo--(--x--,--y--)---------------------------------------><

Moves the associated window to the specified position (x,y). Specify the new position in screen pixels.

toForeground

>>-toForeground------------------------------------------------><

Makes the associated window the foreground window.

focusNextItem

>>-focusNextItem-----------------------------------------------><

Sets the input focus to the next child window of the associated window.

focusPreviousItem

>>-focusPreviousItem-------------------------------------------><

Sets the input focus to the previous child window of the associated window.

focusItem

>>-focusItem--(--wndObject--)----------------------------------><

Sets the input focus to the child window associated with the specified WindowObject instance wndObject.

Example:

The following example sets the input focus to the last child window:

 dlg = wndmgr~find("TestDialog")
    if dlg \= .Nil then do
        fChild = dlg~firstChild
        lChild = fChild~last
        dlg~focusItem(lChild)
    end

findChild

>>-findChild--(--label--)--------------------------------------><

Returns an instance of the WindowObject class associated with the child window with the specified label. If the associated window does not own such a window, the .Nil object is returned.

childAtPosition

>>-childAtPosition--(--x--,--y--)------------------------------><

Returns an instance of the WindowObject class associated with the child window at the specified client position (x,y). The coordinates that are relative to the upper left corner of the associated window must be specified in screen pixels. To retrieve top-level windows, use method windowAtPosition.

next

>>-next--------------------------------------------------------><

Returns an instance of the WindowObject class associated with the next window of the same level as the associated window. If the associated window is the last window of a level, the .Nil object is returned.

previous

>>-previous----------------------------------------------------><

Returns an instance of the WindowObject class associated with the previous window of the same level as the associated window. If the associated window is the first window of a level, the .Nil object is returned.

first

>>-first-------------------------------------------------------><

Returns an instance of the WindowObject class associated with the first window of the same level as the associated window.

last

>>-last--------------------------------------------------------><

Returns an instance of the WindowObject class associated with the last window of the same level as the associated window.

owner

>>-owner-------------------------------------------------------><

Returns an instance of the WindowObject class associated with the window that owns the associated window (parent). If the associated window is a top-level window, the .Nil object is returned.

firstChild

>>-firstChild--------------------------------------------------><

Returns an instance of the WindowObject class associated with the first child window of the associated window. If no child window exists, the .NIL object is returned.

enumerateChildren

>>-enumerateChildren-------------------------------------------><

Returns a stem that stores information about the child windows of the associated window. "Stem.0" contains the number of child windows. The returned stem contains as many records as child windows. The first record is stored at "Stem.1" continued by increments of 1. Each record contains the following entries, where each entry starts with an exclamation mark (!):

!Handle

The handle of the window.

!Title

!Class

The window class.

!State

!Coordinates

!Children

1 if the window has child windows, 0 if is has none.

!Id

Example:

      wo = winmgr~find("TestDialog")
        enum. = wo~enumerateChildren
        do i = 1 to enum.0   /* number of children */
           say "---"
           say "Handle:" enum.i.!Handle
           say "Title:" enum.i.!Title
           say "Class:" enum.i.!Class
           say "Id:" enum.i.!Id
           say "Children:" enum.i.!Children
           say "State:" enum.i.!State
           say "Rect:" enum.i.!Coordinates
        end

sendMessage

>>-sendMessage--(--message--,--wParam--,--lParam--)------------><

Sends a message to the associated window.

sendCommand

>>-sendCommand--(--command--)----------------------------------><

Sends a WM_COMMAND message to the associated window. WM_COMMAND is sent, for example, when a button is pressed, where command is the button ID.

sendMenuCommand

>>-sendMenuCommand--(--id--)-----------------------------------><

Selects the menu item id of the associated window. Method idOf returns the ID of a menu item.

sendMouseClick

                      +-"LEFT"---+     +-"DBLCLK"-+
>>-sendMouseClick--(--+-"RIGHT"--+--,--+-"UP"-----+----,--x--,--y-->
                      +-"MIDDLE"-+     +-"DOWN"---+

>--+-----------------------------+--)--------------------------><
   |       +----------------+    |
   |       V                |    |
   +-,--"----+-LEFTDOWN---+-+--"-+
             +-RIGHTDOWN--+
             +-MIDDLEDOWN-+
             +-SHIFT------+
             +-CONTROL----+

Simulates a mouse click event in the associated window.

Arguments:

The arguments are:

which

Specifies which mouse button is simulated. LEFT is the default.

kind

Selects the simulated mouse action. DBLCLK is the default.

x,y

Specifies the coordinates of the mouse click event, in screen coordinates, relative to the upper left corner of the window.

ext

Can be one or more of the following strings:

LEFTDOWN

Simulates the pressed left mouse button.

RIGHTDOWN

Simulates the pressed right mouse button.

MIDDLEDOWN

Simulates the pressed middle mouse button.

SHIFT

Simulates the pressed Shift key.

CONTROL

Simulates the pressed Control key.

sendSyscommand

>>-sendSyscommand--(--"--+-SIZE--------+--"--)-----------------><
                         +-MOVE--------+
                         +-MINIMIZE----+
                         +-MAXIMIZE----+
                         +-NEXTWINDOW--+
                         +-PREVWINDOW--+
                         +-CLOSE-------+
                         +-VSCROLL-----+
                         +-HSCROLL-----+
                         +-ARRANGE-----+
                         +-RESTORE-----+
                         +-TASKLIST----+
                         +-SCREENSAVE--+
                         +-CONTEXTHELP-+

Sends a WM_SYSCOMMAND message to the associated window. These messages are normally sent when the user selects a command in the Window menu.

Argument:

The only argument is:

command

One of the commands listed in the syntax diagram:

SIZE

Puts the window in size mode.

MOVE

Puts the window in move mode.

MINIMIZE

Minimizes the window.

MAXIMIZE

Maximizes the window.

NEXTWINDOW

Moves to the next window.

PREVWINDOW

Moves to the previous window.

CLOSE

Closes the window.

VSCROLL

Scrolls vertically.

HSCROLL

Scrolls horizontally.

ARRANGE

Arranges the window.

RESTORE

Restores the window to its normal position and size.

TASKLIST

Activates the Start menu.

SCREENSAVE

Executes the screen-saver application specified in the [boot] section of the SYSTEM.INI file.

CONTEXTHELP

Changes the cursor to a question mark with a pointer. If the user then clicks on a control in the dialog box, the control receives a WM_HELP message.

pushButton

>>-pushButton--(--label--)-------------------------------------><

Selects the button with the specified label within the associated window and sends the corresponding WM_COMMAND message. If the button's label contains a mnemonic (underscored letter), you must specify an ampersand (&) in front of it. You can also use this method to select radio buttons and check or uncheck check boxes.

sendKey

>>-sendKey--(--keyName--+------------------------+--)----------><
                        +-,--+-----+--+--------+-+
                             +-alt-+  +-,--ext-+

Sends all messages (CHAR, KEYDOWN, and KEYUP) that would be sent by pressing a specific key on the keyboard. Character keys (a to z) are not case-sensitive.

If the alt argument is 1, the Alt key flag is set, which is equal to pressing the specified key together with the Alt key.

The Ext argument must be 1 if the key is an extended key, such as a right Ctrl or a right Shift.

For a list of key names, refer to Symbolic Names for Virtual Keys.

sendChar

>>-sendChar--(--character--+--------+--)-----------------------><
                           +-,--alt-+

Sends a WM_CHAR message to the associated window. If the alt argument is 1, a pressed Alt key is simulated.

sendKeyDown

>>-sendKeyDown--(--keyName--+--------+--)----------------------><
                            +-,--ext-+

Sends a WM_KEYDOWN message to the associated window. The ext argument must be 1 if the key is an extended key, such as a right Ctrl or a right Shift.

For a list of key names, refer to Symbolic Names for Virtual Keys.

sendKeyUp

>>-sendKeyUp--(--keyName--+--------+--)------------------------><
                          +-,--ext-+

Sends a WM_KEYUP message to the associated window. The ext argument must be 1 if the key is an extended key, such as a right Ctrl or a right Shift.

For a list of key names, refer to Symbolic Names for Virtual Keys.

sendText

>>-sendText--(--text--)----------------------------------------><

Sends a (case-sensitive) text to the associated window by sending a sequence of WM_CHAR, WM_KEYDOWN, and WM_KEYUP messages.

menu

>>-menu--------------------------------------------------------><

Returns an instance of the MenuObject class that refers to the menu of the associated window.

systemMenu

>>-systemMenu--------------------------------------------------><

Returns an instance of the MenuObject class that refers to the system menu of the associated window.

isMenu

>>-isMenu------------------------------------------------------><

Returns 1 if the associated window is a menu, otherwise 0.

processMenuCommand

                                       +-,-------+
                                       V         |
>>-processMenuCommand--(--+------+--,----submenu-+--,--menuItem--)-><
                          +-menu-+

Selects an item of the menu or submenu of the associated window. You can specify as many submenus as necessary to get to the required item.

The WindowsProgramManager Class

Object Rexx provides a class for interaction with the Windows Program Manager. You can use this class to create program groups and shortcuts to access your programs. This class is specifically for Windows systems and may not be available on other systems.

The WindowsProgramManager class is defined in the file WINSYSTM.CLS. Use a ::requires statement to activate its function:

::requires "winsystm.cls"

A sample program DESKTOP.REX is provided in the ooRexx\SAMPLES directory.

Methods of the WindowsProgramManager class are:

Table 5-4. Methods Available to the WindowsProgramManager Class

Method......link
addDeskTopIconaddDesktopIcon
addGroupaddGroup
addItemaddItem
addShortCutaddShortCut
deleteDesktopIcondeleteDesktopIcon
deleteGroupdeleteGroup
deleteItemdeleteItem
initinit
showGroupshowGroup

addDesktopIcon

>>-addDesktopIcon--(--name--,--program--+--------------------------------+-->
                                        |                     +-0------+ |
                                        +-,--+----------+--,--+--------+-+
                                             +-iconfile-+     +-iconnr-+

>--+--------------------------------------------------------------------------+-)-><
   |                 +-"PERSONAL"-+                           +-"NORMAL"----+ |
   +-,-+---------+-,-+------------+-,-+------+-,-+--------+-,-+-------------+-+
       +-workdir-+   +-"COMMON"---+   +-args-+   +-hotkey-+   +-"MAXIMIZED"-+
                                                              +-"MINIMIZED"-+

Adds a shortcut to the Windows desktop. A sample program DESKICON.REX is provided in the ooRexx\SAMPLES directory.

Arguments:

The arguments are:

name

The name of the shortcut, displayed below the icon.

program

The program file launched by the shortcut.

iconfile

The name of the icon used for the shortcut. If not specified, the icon of program is used.

iconnr

The number of the icon within the iconfile. The default is 0.

workdir

The working directory of the shortcut.

location

Either of the following locations:

"PERSONAL"

The shortcut is personal and displayed only on the desktop of the user.

"COMMON"

The shortcut is common to all users and displayed on the desktop of all users.

args

The arguments passed to the program that the shortcut refers to.

hotkey

The virtual key to be used as a hotkey to open the shortcut. For a list of the key names, see Symbolic Names for Virtual Keys.

run

Specifies one of the options listed in the syntax diagram. The default is "NORMAL".

addShortCut

>>-addShortCut--(--name--,--program--------------------------------------->

>--+---------------------------------------------------------------------->
   |                  +-0------+
   +-,-+----------+-,-+--------+-,-+---------+-,-+------+-,-+--------+-,-->
       +-iconfile-+   +-iconnr-+   +-workdir-+   +-args-+   +-hotkey-+

>-------------------+--)-------------------------------------------------><
    +-"NORMAL"----+ |
>---+-------------+-+
    +-"MAXIMIZED"-+
    +-"MINIMIZED"-+

Creates a shortcut within the specified folder.

Arguments:

The arguments are:

name

The full name of the shortcut.

program

The program file launched by the shortcut.

iconfile

The name of the icon used for the shortcut. If not specified, the icon of program is used.

iconnr

The number of the icon within the iconfile. The default is 0.

workdir

The working directory of the shortcut.

args

The arguments passed to the program that the shortcut refers to.

hotkey

The virtual key to be used as a hotkey to open the shortcut. For a list of the key names, see Symbolic Names for Virtual Keys.

run

Specifies one of the options listed in the syntax diagram. The default is "NORMAL".

Example:

The following example creates a shortcut named "My NotePad" to the Notepad editor within the directory c:\temp:

pm = .WindowsProgramManager~new
	if pm~InitCode \= 0 then exit
	pm~addShortCut("c:\temp\My Notepad","%SystemRoot%\system32\notepad.exe")
	::requires "winsystm.cls"

addGroup

>>-addGroup(-group-)-------------------------------------------><

Adds a program group to the Programs group of the desktop. If the group already exists, it is opened. The group argument specifies the name of the program group to be added. Example:

addGroup("Object Rexx Redbook")

Note: The name that you specify for the group argument must not contain any brackets or parenthesis. Otherwise, this method fails.

Return value:

0

The method was successful.

1

The method failed.

addItem

>>-addItem--(--shortcut,program--------------------------------->

>--+------------------------------------------------------+----->
   +-,--+----------+--+---------------------------------+-+
        +-iconfile-+  +-,--+------------+--+----------+-+
                           +-iconnumber-+  +-,workdir-+

>--)-----------------------------------------------------------><

Adds a shortcut to a program group. The shortcut is placed into the last group used with either AddGroup or ShowGroup. Example:

AddItem("OODialog Samples", ,
"rexx oodialog\samples\sample.rex", ,
"oodialog\samples\oodialog.ico")

Note: The name that you specify for the group argument must not contain characters that are not valid, such as brackets or parenthesis. Otherwise, this method fails. Some characters are changed, for example / to _.

Return value:

0

The method was successful.

1

The method failed.

deleteDesktopIcon

                                   +-"PERSONAL"-+
>>-deleteDesktopIcon--(--name--,---+------------+-)------------><
                                   +-"COMMON"---+

Deletes a shortcut from the Windows desktop that was previously created with AddDesktopIcon.

The arguments are:

name

The name of the shortcut to be deleted.

location

Either of the following locations:

"PERSONAL"

The shortcut was previously created with AddDesktopIcon and the location option "PERSONAL". This is the default.

"COMMON"

The shortcut was previously created with AddDesktopIcon and the location option "COMMON".

Return codes:

0

Shortcut deleted successfully.

2

Shortcut not found.

3

Path to shortcut not found.

5

Access denied or busy.

26

Not a DOS disk.

32

Sharing violation.

36

Sharing buffer exceeded.

87

Does not exist.

206

Shortcut name exceeds range error.

Note:: Return code 2 is also returned when a "PERSONAL" should be deleted that was previously created with "COMMON" and vice versa.

Example:

pm = .WindowsProgramManager~new
if pm~InitCode \= 0 then exit

rc = pm~deleteDesktopIcon("MyNotepad1", ,
     "%SystemRoot%\system32\notepad.exe")
if rc \= 0 then do
  say "Error deleting shortcut: My Notepad 1"
  exit
end

exit

::requires "winsystm.cls"

deleteGroup

>>-deleteGroup(-group-)----------------------------------------><

Deletes a program group from the desktop. The group argument specifies the name of the program group to be deleted.

Return value:

0

The method was successful.

1

The method failed.

deleteItem

>>-deleteItem(shortcut)----------------------------------------><

Deletes a shortcut from a program group.

Return value:

0

The method was successful.

1

The method failed.

init

>>-init--------------------------------------------------------><

Creates an instance of the WindowsProgramManager class and loads the required function package.

showGroup

>>-showGroup(-group,-+-----+-)---------------------------------><
                     +-MIN-+
                     +-MAX-+

Opens a program group. The group argument specifies the name of the program group to be opened. If MIN or MAX is specified, the program group is opened minimized or maximized.

Return value:

0

The method was successful.

1

The method failed.

Symbolic Names for Virtual Keys

Table 3 shows the symbolic names and the keyboard equivalents for the virtual keys used by Object Rexx.

Table 5-5. Symbolic Names for Virtual Keys

Symbolic NameMouse or Keyboard Equivalent
LBUTTONLeft mouse button
RBUTTONRight mouse button
CANCELControl-break processing
MBUTTONMiddle mouse button (three-button mouse)
BACKBACKSPACE key
TABTAB key
CLEARCLEAR key
RETURNENTER key
SHIFTSHIFT key
CONTROLCRTL key
MENUALT key
PAUSEPAUSE key
CAPITALCAPS LOCK key
ESCAPEESC key
SPACESPACEBAR
PRIORPAGE UP key
NEXTPAGE DOWN key
ENDEND key
HOMEHOME key
LEFTLEFT ARROW key
UPUP ARROW key
RIGHTRIGHT ARROW key
DOWNDOWN ARROW key
SELECTSELECT key
EXECUTEEXECUTE key
SNAPSHOTPRINT SCREEN key
INSERTINS key
DELETEDEL key
HELPHELP key
00 key
11 key
22 key
33 key
44 key
55 key
66 key
77 key
88 key
99 key
AA key
BB key
CC key
DD key
EE key
FF key
GG key
HH key
II key
JJ key
KK key
LL key
MM key
NN key
OO key
QQ key
RR key
SS key
TT key
UU key
VV key
WW key
XX key
YY key
ZZ key
NUMPAD0Numeric keypad 0 key
NUMPAD1Numeric keypad 1 key
NUMPAD2Numeric keypad 2 key
NUMPAD3Numeric keypad 3 key
NUMPAD4Numeric keypad 4 key
NUMPAD5Numeric keypad 5 key
NUMPAD6Numeric keypad 6 key
NUMPAD7Numeric keypad 7 key
NUMPAD8Numeric keypad 8 key
NUMPAD9Numeric keypad 9 key
MULTIPLYMultiply key
ADDAdd key
SEPARATORSeparator key
SUBTRACTSubtract key
DECIMALDecimal key
DIVIDEDivide key
F1F1 key
F2F2 key
F3F3 key
F4F4 key
F5F5 key
F6F6 key
F7F7 key
F8F8 key
F9F9 key
F10F10 key
F11F11 key
F12F12 key
F13F13 key
F14F14 key
F15F15 key
F16F16 key
F17F17 key
F18F18 key
F19F19 key
F20F20 key
F21F21 key
F22F22 key
F23F23 key
F24F24 key
NUMLOCKNUM LOCK key
SCROLLSCROLL LOCK key

The WindowsRegistry Class

Object Rexx provides a class for interaction with the WindowsRegistry. You can use this class to query the registry and modify, add, and delete entries. This class is specifically for Windows systems and may not be available on other systems.

The WindowsRegistry class is not a built-in class; it is defined in the file WINSYSTM.CLS.

Use a ::requires statement to activate its function:

::requires "winsystm.cls"

A sample program, REGISTRY.REX, is provided in the ooRexx\SAMPLES directory

Methods the WindowsRegistry Class Defines

classes_root

>>-classes_root------------------------------------------------><

Returns the handle of the root key HKEY_CLASSES_ROOT.

classes_root=

>>-classes_root=-----------------------------------------------><

This method is used by INIT to set the attribute CLASSES_ROOT to HKEY_CLASSES_ROOT. Do not modify this attribute.

close

>>-close(-+------------+-)-------------------------------------><
          +-key_handle-+

Closes a previously opened key specified by its handle. Example:

rg~close(objectrexxkey)

It can take several seconds before all data is written to disk. You can use FLUSH to empty the cache.

If key_handle is omitted, CURRENT_KEY is closed.

connect

>>-connect(-key,computer-)-------------------------------------><

Opens a key on a remote computer. This is supported only for HKEY_LOCAL_MACHINE and HKEY_USERS.

create

>>-create(-+--------+-,subkey)---------------------------------><
           +-parent-+

Adds a new named subkey to the registry and returns its handle. The parent key handle parent can be a root key or a key retrieved using OPEN. If the parent key is omitted, CURRENT_KEY is used. Example:

newkey = rg~create(rg~local_machine,"MyOwnKey")

current_key

>>-current_key-------------------------------------------------><

Returns the handle of the current key. The current key is set by INIT, CREATE, and OPEN. It is used as a default value if the key is omitted in other methods.

current_key=

>>-current_key=------------------------------------------------><

Sets the handle of the current key.

current_user

>>-current_user------------------------------------------------><

Returns the handle of the root key HKEY_CURRENT_USER.

current_user=

>>-current_user=-----------------------------------------------><

This method is used by INIT to set the attribute CURRENT_USER to HKEY_CURRENT_USER. Do not modify this attribute.

delete

>>-delete(-+------------+-,subkeyname)-------------------------><
           +-key_handle-+

Deletes a given named subkey of an open key specified by its handle and all its subkeys and values. If key_handle is omitted, CURRENT_KEY is used.

deleteValue

>>-deleteValue(-+------------+-+--------+-)--------------------><
                +-key_handle-+ +-,value-+

Deletes the named value for a given key. If key_handle is omitted, CURRENT_KEY is used. If value is blank or omitted, the default value is deleted.

flush

>>-flush(-+------------+-)-------------------------------------><
          +-key_handle-+

Forces the system to write the cache buffer of a given key to disk. If key_handle is omitted, CURRENT_KEY is flushed.

getValue

>>-getValue(-+------------+-+--------+-)-----------------------><
             +-key_handle-+ +-,value-+

Retrieves the data and type for a named value of a given key. The result is a compound variable with suffixes data and type. If key_handle is omitted, CURRENT_KEY is used. If named value is blank or omitted, the default value is retrieved. Example:

myval. = rg~getvalue(,"filesystem")        /* current key */
say "Type is" myval.type
if myval.type = "NORMAL" then say "Value is" myval.data
myval. = rg~getvalue(mykey)
say "my default value is:" myval.data
myval. = rg~getvalue(mykey,"")
say "my default value is:" myval.data

Possible types: NORMAL, EXPAND, MULTI, NUMBER, BINARY, NONE, OTHER.

init

>>-init--------------------------------------------------------><

Creates an instance of the WindowsRegistry class and loads the required external function package. The current key is set to HKEY_LOCAL_MACHINE.

list

>>-list(-+------------+-,stem.)--------------------------------><
         +-key_handle-+

Retrieves the list of subkeys for a given key in a stem variable. The name of the stem variable must include the period. The keys are returned as stem.1, stem.2, and so on. Example:

rg~LIST(objectrexxkey,orexxkeys.)
do i over orexxkeys.
say orexxkeys.i
end

listValues

>>-listValues(-+------------+-,variable.)----------------------><
               +-key_handle-+

Retrieves all value entries of a given key into a compound variable. The name of the variable must include the period. The suffixes of the compound variable are numbered starting with 1, and for each number the three values are the name (var.i.name), the data (var.i.data), and the type (var.i.type). The type is NORMAL for alphabetic values, EXPAND for expandable strings such as a path, NONE for no specified type, MULTI for multiple strings, NUMBER for a 4-byte value, and BINARY for any data format.

If key_handle is omitted, the values of CURRENT_KEY are listed.

Example:

qstem. = rg~QUERY(objectrexxkey)
rg~LISTVALUES(objectrexxkey,lv.)
do i=1 to qstem.values
say "name of value:" lv.i.name "(type="lv.i.type")"
if lv.i.type = "NORMAL" then
say "data of value:" lv.i.data
end

load

>>-load(-+------------+-,subkeyname, filename)-----------------><
         +-key_handle-+

Load creates a named subkey under the open key key_handle and loads registry data from the file filename (created by SAVE) and stores the data under the newly created subkey.

key_handle can only be HKEY_USERS or HKEY_LOCAL_MACHINE. Registry information is stored in the form of a hive - a discrete body of keys, subkeys, and values that is rooted at the top of the registry hierarchy. A hive is backed by a single file.

If key_handle is omitted, the subkey is created under HKEY_LOCAL_MACHINE.

Use UNLOAD to delete the subkey and to unlock the registry data file filename.

local_machine

>>-local_machine-----------------------------------------------><

Returns the handle of the root key HKEY_LOCAL_MACHINE.

local_machine=

>>-local_machine=----------------------------------------------><

This method is used by INIT to set the attribute LOCAL_MACHINE to HKEY_LOCAL_MACHINE. Do not modify this attribute.

open

>>-open(-+---------------+-,subkey-+--------------+-)----------><
         +-parent_handle-+         +-,-| access |-+

access:

   +-ALL-+
|--+-----+------------------------------------------------------>

   +--------------------------------------------------------------+
   V                                                              |
>----+-------+-+------+-+-------+-+---------+-+--------+-+------+-+--|
     +-WRITE-+ +-READ-+ +-QUERY-+ +-EXECUTE-+ +-NOTIFY-+ +-LINK-+

Opens a named subkey and return its handle. See CREATE for more information about parent_handle. Possible values for access are:

ALL

Default

WRITE

Create subkeys, set values

READ

Query subkeys and values

QUERY

Values

EXECUTE

Key access, no subkey access

NOTIFY

Change notification

LINK

Create symbolic links

More than one value can be specified separated by blanks.

Notice that on Windows NT some keys require certain access rights and do not allow to open the key with all but only with certain access values.

query

>>-query--(--+------------+--)---------------------------------><
             +-key_handle-+

Retrieves information about a given key in a compound variable. The values returned are class (class name), subkeys (number of subkeys) values (number of value entries), date and time of last modification. If key_handle is omitted, CURRENT_KEY is queried. Example:

myquery. = rg~query(objectrexxkey)
say "class="myquery.class "at" myquery.date
say "subkeys="myquery.subkeys "values="myquery.values

replace

>>-replace(-+------------+-,-+------------+-,newfilename,oldfilename-)-><
            +-key_handle-+   +-subkeyname-+

Replaces the backup file of a key or subkey with a new file. Key must be an immediate descendant of HKEY_LOCAL_MACHINE or HKEY_USERS. If key_handle is omitted, the backup file of CURRENT_KEY is replaced. The values in the new file become active when the system is restarted. If subkeyname is omitted, the key and all its subkeys will be replaced.

restore

>>-restore(-+------------+-,filename-+-------------+-)---------><
            +-key_handle-+           +-,"VOLATILE"-+

Restores a key from a file. If key_handle is omitted, CURRENT_KEY is restored. Example:

rg~restore(objectrexxkey,"\objrexx\orexx")

The VOLATILE keyword creates a new memory-only set of registry information that is valid only until the system is restarted.

save

>>-save(-+------------+-,filename)-----------------------------><
         +-key_handle-+

Saves the entries of a given key into a file. If key_handle is omitted, CURRENT_KEY is saved. Example:

rg~SAVE(objectrexxkey,"\objrexx\orexx")

On a FAT system, do not use a file extension in filename.

setValue

>>-setValue(-+------------+-,-+------+-,value-+---------+-)----><
             +-key_handle-+   +-name-+        +-,NORMAL-+
                                              +-,EXPAND-+
                                              +-,MULTI--+
                                              +-,NUMBER-+
                                              +-,BINARY-+
                                              +-,NONE---+

Sets a named value of a given key. If name is blank or omitted, the default value is set. Examples:

rg~SETVALUE(objectrexxkey, ,"My default","NORMAL")
rg~SETVALUE(objectrexxkey,"Product_Name","Object Rexx")
rg~SETVALUE(objectrexxkey,"VERSION","1.0")

unload

>>-unload(-+------------+-,subkey)-----------------------------><
           +-key_handle-+

Removes a named subkey (created with LOAD) and its dependents from the registry, but does not modify the file containing the registry information. If key_handle is omitted, the subkey under CURRENT_KEY is unloaded. Unload also unlocks the registry information file.

users

>>-users-------------------------------------------------------><

Returns the handle of the root key HKEY_USERS.

users=

>>-users=------------------------------------------------------><

This method is used by INIT to set the attribute USERS to HKEY_USERS. Do not modify this attribute.