Natural Studio Interfaces

#### Search Results

Search

# Natural Studio Interfaces

This document covers the following topics:

- Root Interface

- Interface Structure

- Working with Control Bars

- Working with Node Types

- Working with Selections

- Working with Natural Development Objects

- Working with Generic Text Documents

- Working with Generic Documents

- Working with Tree Views and List Views

- Working with Result Views

- Working with Environments

- Working with Applications

- Working with Plug-ins

- Working with Dialogs

## Root Interface

Plug-ins access Natural Studio functionality through an Automation interface. All individual interfaces that form the Natural Studio Automation interface can be reached from the root interface, `INatAutoStudio`. A handle to this interface is passed to each plug-in during activation and deactivation.

## Interface Structure

The following tree diagram shows the hierarchical structure of the Automation interface:

    INatAutoStudio
     |_INatAutoObjects
               |_INatAutoDataAreas
                   |_INatAutoDataArea
               |_INatAutoDialogs
                   |_INatAutoDialog
               |_INatAutoPrograms
                   |_INatAutoProgram
               |_INatAutoGenericDocuments
                   |_INatAutoGenericDocument
               |_INatAutoGenericTexts
                   |_INatAutoGenericText
               |_INatAutoObjectLists
                   |_INatAutoObjectList
               |_INatAutoObjectTrees
                   |_INatAutoObjectTree
                          |_INatAutoObjectTreeNode
               |_INatAutoSelectedObjects
                   |_INatAutoSelectedObject
               |_INatAutoRefreshObject
     |_INatAutoControlBars
               |_INatAutoImages
               |_INatAutoCommands
                   |_INatAutoCommand
               |_INatAutoToolBars
                   |_INatAutoToolBar
               |_INatAutoFrameMenus
                   |_INatAutoFrameMenu
                          |_INatAutoPopupMenu
               |_INatAutoContextMenus
                   |_INatAutoContextMenu
                          |_INatAutoPopupMenu
     |_INatAutoTypes
               |_INatAutoNodeTypes
                          |_INatAutoNodeType
               |_INatAutoNodeImages
     |_INatAutoPlugIns
               |_INatAutoPlugIn
     |_INatAutoResultViews
               |_INatAutoResultView
     |_INatAutoSystem
               |_INatAutoEnvironments
                          |_INatAutoEnvironment
                                 |_INatAutoNatparm
                                 |_INatAutoNatsvar
               |_INatAutoApplications
                          |_INatAutoApplication
                                 |_INatAutoLinkedApplications
                                 |_INatAutoEnvironment
               |_INatAutoSysmain
     |_INatAutoProgressIndicator

## Working with Control Bars

Natural Studio users access plug-in functionality by using commands. A plug-in identifies each command by a number. The number can be freely chosen, but must of course be unique per plug-in. A command can have a caption and an image assigned. Caption and image represent the command in menus and toolbars.

To provide a command to the user, a plug-in first creates an `INatAutoCommand` interface in the `INatAutoCommands` collection:

    send "Add" to #commands
    with 4711 "MyCommand" #myImage
    return #myCommand

While creating the command, in the above example the plug-in refers to an image `#myImage`. This image is used to represent the command visually in menus and toolbars. The plug-in may have loaded the image before, using the method `INatAutoImages::LoadImage`:

    send "LoadImage" to #images
    with "e:\images\myimage.bmp"
    return #myImage

This results in an `IPictureDisp` interface that can be passed to the method `INatAutoCommands::Add`. The `IPictureDisp` interface is a predefined interface in Windows. An `IPictureDisp` interface can be created in Natural using the method `INatAutoImages::LoadImage`.

Alternatively, the plug-in can pass the image file name directly to the method `INatAutoCommands::Add`:

    send "Add" to #commands
    with 4711 "MyCommand" "e:\images\myimage.bmp"
    return #myCommand

When the user later chooses the command in a menu or toolbar, the plug-in is notified by using the method `INaturalStudioPlugIn::OnCommand`.

But in order to make the command accessible to users in the first place, the plug-in must insert it into a menu or toolbar. We show this with a toolbar as example. Here the plug-in first locates the Tools toolbar. Then it inserts the previously created command into the toolbar.

    send "Item" to #toolbars
    with "Tools"
    return #toolsToolbar
    send "InsertCommand" to #toolsToolbar
    with #myCommand

The plug-in needs to create the command only once and can then assign it to different toolbars or menus.

The plug-in might as well create its own toolbar and add the command to this toolbar:

    send "Add" to #toolbars
    with "MyToolbar"
    return #myToolbar
    send "InsertCommand" to #myToolbar
    with #myCommand

We saw the plug-in use the interfaces `INatAutoCommands`, `INatAutoImages` and other interfaces. But how does the plug-in get access to these interfaces in the first place? The plug-in accesses them by querying properties of the root interface, `INatAutoStudio`. A handle to this interface is passed to each plug-in during activation and deactivation. From this interface the plug-in can navigate to any other section of the Natural Studio Automation interface.

To work with control bars, a plug-in uses the interfaces described in the following sections:

`INatAutoControlBars`
`INatAutoImages`
`INatAutoCommands`
`INatAutoCommand`
`INatAutoToolBars`
`INatAutoToolBar`
`INatAutoContextMenus`
`INatAutoContextMenu`
`INatAutoFrameMenus`
`INatAutoFrameMenu`
`INatAutoPopupMenu`

## Working with Node Types

Natural Studio frequently uses tree views and list views to display development objects and to navigate through them. Each node in a tree view or list view is characterized by a node type. The node type defines how nodes of a given type are represented in the user interface.

Each node type is identified by an integer number. A development object belonging to a given node type is identified by the number of that node type and by an alphanumeric key. The format of the key varies from node type to node type.

Plug-ins that wish to create their own tree views and list views in Natural Studio can refer to the predefined node types. In addition, plug-ins can define their own node types and can then refer to these user-defined node types.

The following topics are covered below:

- Predefined Node Types

- User-defined Node Types

### Predefined Node Types

The built-in Natural Studio development objects such as program, dialog, class, library or application have a predefined node type and key format. Many interfaces and methods in the Natural Studio Automation interface refer to the predefined node types. The full list of available predefined node types and the format of their keys is defined in the following tables.

#### Predefined Node Types

Node Type Number | Node Type Name | Key Format
--- | --- | ---
1001 | Parameter data area | NATID
1002 | Copycode | NATID
1003 | DDM | NATID
1004 | Global data area | NATID
1005 | Helproutine | NATID
1006 | Local data area | NATID
1007 | Map | NATID
1008 | Subprogram | NATID
1009 | Program | NATID
1010 | Subroutine | NATID
1011 | Text | NATID
1012 | View | NATID
1013 | Dialog | NATID
1014 | Class | NATID
1015 | Command processor | NATID
1017 | Mainframe DDM | DDMID
1018 | Function | NATID
1019 | Shared resource | RESID
1020 | Error message file | NATID
1021 | Adapter | NATID
1051 | Parameter data area (in application) | NATID
1052 | Copycode (in application) | NATID
1053 | DDM (in application) | NATID
1054 | Global data area (in application) | NATID
1055 | Helproutine (in application) | NATID
1056 | Local data area (in application) | NATID
1057 | Map (in application) | NATID
1058 | Subprogram (in application) | NATID
1059 | Program (in application) | NATID
1060 | Subroutine (in application) | NATID
1061 | Text (in application) | NATID
1062 | View (in application) | NATID
1063 | Dialog (in application) | NATID
1064 | Class (in application) | NATID
1065 | Command processor (in application) | NATID
1067 | Mainframe DDM (in application) | DDMID
1068 | Function (in application) | NATID
1069 | Shared resource (in application) | RESID
1070 | Error message file (in application) | NATID
1071 | Adapter (in application) | NATID
1101 | System file | FILEID
1102 | Natural system file | FILEID
1103 | User system file | FILEID
1104 | DDM system file | FILEID
1111 | Library | LIBID
1112 | Library (in application) | LIBID
1121 | Environment | BSTR
1131 | Base application | BSTR
1132 | Compound application | BSTR
1141 | Application server | BSTR

#### Format NATID

Syntax | Description
--- | ---
name library fnr dbnr | Identifies the Natural development object with the given name in the given library in the given system file. The individual parts of the identifier are separated by spaces.
name library | Identifies the Natural object with the given name in the given library. The system file is then determined from the library according to the usual Natural logic, depending on the library name. The individual parts of the identifier are separated by spaces.
name | Identifies the Natural object with the given name in the current logon library.

#### Format RESID

Syntax | Description
--- | ---
name/library/fnr/dbnr | Identifies the shared resource with the given name in the given library in the given system file. The individual parts of the identifier are separated by slashes.
name/library | Identifies the shared resource with the given name in the given library. The system file is then determined from the library according to the usual Natural logic, depending on the library name. The individual parts of the identifier are separated by slashes.
name | Identifies the shared resource with the given name in the current logon library.

#### Format DDMID

Syntax | Description
--- | ---
name fnr dbnr | Identifies the mainframe DDM with the given name in the given `FDIC` system file. The individual parts of the identifier are separated by spaces.
name | Identifies the mainframe DDM with the given name in the current `FDIC` system file.

#### Format LIBID

Syntax | Description
--- | ---
name fnr dbnr | Identifies the Natural library with the given name in the given system file. The individual parts of the identifier are separated by spaces.
name | Identifies the Natural library with the given name. The system file is then determined from the library according to the usual Natural logic, depending on the library name.

#### Format FILEID

Syntax | Description
--- | ---
fnr dbnr | Identifies the Natural system file with the given numbers. The individual parts of the identifier are separated by spaces.

#### Example

Assume that in a certain development environment, we have a system file with the database number "101" and the file number "99", containing a library `MYLIB` with a program `MYPROG`.

In the given environment

- the program is identified by the node type 1009 and the key "MYPROG MYLIB 99 101",

- the library is identified by the node type 1111 and the key "MYLIB 99 101",

- the system file is identified by the node type 1103 and the key "99 101".

### User-defined Node Types

Plug-ins can define their own node types. This is useful if a plug-in wants to display tree views or list views of development objects not belonging to the predefined set of Natural Studio objects. An example is the Object Description plug-in. It is also useful for plug-ins that want to display certain aspects of Natural Studio objects not covered by built-in Natural Studio functionality. An example is the XRef Evaluation plug-in.

When defining its own node type, a plug-in is free to choose an arbitrary positive integer value starting with "20000". Values below "20000" are reserved for predefined node types. It does not matter if different plug-ins chose the same integer value for a node type. Internally, Natural Studio distinguishes the node types by their numbers and by the plug-in that defined the node type.

The plug-in is free to define the key format for each user-defined node type. Natural Studio does not interpret the keys of user-defined node types, but treats them as opaque strings.

To define new node types and their visual representations, a plug-in uses the interfaces described in the following sections:

`INatAutoTypes`
`INatAutoNodeImages`
`INatAutoNodeTypes`
`INatAutoNodeType`

## Working with Selections

Through the interfaces described in this section, plug-ins can access the set of objects the user has currently selected in Natural Studio. A plug-in might need this information to decide if a specific menu or toolbar command is applicable to the current selection and must hence be enabled in the user interface. If the user then executes the command, the plug-in again needs to know the set of selected objects in order to apply the command to each of them. A plug-in has access to the current selection through the interfaces described in this section.

In order to work with the current selection, a plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoObjects` interface and then the `INatAutoSelectedObjects` interface. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #objs := #studio.Objects
    #selobjs := #objs.SelectedObjects

The returned `INatAutoSelectedObjects` interface gives access to the set of objects the user has currently selected. Using this interface, the plug-in can, for instance, iterate across the selected objects and inspect them. The method `Item` returns an `INatAutoSelectedObject` interface to a specific selected object.

    #iCount := #selobjs.Count
    for #i := 1 to #iCount
      send "Item" to #selobjs
      with #i return #selobj
      #iType := #selobj.Type
      #aKey := #selobj.Key
    end-for

The property `FocusObject` returns the index of the specific selected object that currently has the focus. This index can be used to retrieve the `INatAutoSelectedObject` interface of the focus object.

    #iFocus := #selobjs.FocusObject
    send "Item" to #selobjs
    with #iFocus return #focus

The method `ContainsObjectType` can be used for a quick check if the current selected set contains objects of a specific type. This might be sometimes sufficient to decide if a specific command shall be enabled or not.

    send "ContainsObjectType" to #selobjs
    with 1009 return #bContainsPrograms

For specific checks the plug-in can also retrieve and process the current selection as an XML document.

    #aSelectedObjectsXML := #selobjs.SelectedObjects

To work with selections, a plug-in uses the interfaces described in the following sections:

`INatAutoObjects`
`INatAutoSelectedObjects`
`INatAutoSelectedObject`

## Working with Natural Development Objects

Through the interfaces described in this section, plug-ins can create and edit Natural development objects. Being able to create new development objects, load existing objects into an editor, manipulate their contents and to save and stow them, enables plug-ins to provide generation functions and thus to help automating the development process. An example is the Program Generation plug-in.

To open a program in the program editor, for instance, a plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoObjects` interface and then the `INatAutoPrograms` interface. Now it uses the method `INatAutoPrograms::Open` to load the program into the editor.

We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #objects := #studio.Objects
    #programs := #objects.Programs
    send "Open" to #programs
    with 1009 "MYPGM" "MYLIB" return #program

The resulting `INatAutoProgram` interface can now be used to operate on the program, for instance, to stow it and then to close the editor.

    send "Stow" to #program
    send "Close" to #program

A new program source is created by using the method `Add`.

    send "Add" to #programs
    with 1009 return #program

Source code is added to the program either as a whole by using the property `Source`:

    #program.Source := "WRITE ""HELLO, WORLD!"" END

Or incrementally by using the method `InsertLines`.

    send "InsertLines" to #program
    with "WRITE ""HELLO, WORLD!" #return #next
    send "InsertLines" to #program
    with "END" #next return #next

The interface `INatAutoProgram` provides also search and replace methods and other methods to modify the source code.

    send "Search" to #program
    with "HELLO" return #found
    send "ReplaceLines" to #program
    with "WRITE ""Good morning" #found

Dialogs and data areas are accessed in a similar way by using the interfaces `INatAutoDialog` and `INatAutoDataArea`. But there is one particularity with these objects: Even though there is a graphical or structured editor in the user interface for these objects, they are edited textually through the Automation interface. Applied to data areas this means: If a plug-in wants to generate a data area, it actually has to generate a `DEFINE DATA` statement.

    #objects := #studio.Objects
    #dataareas := #objects.DataAreas
    send "Add" to #dataareas
    with 1006 return #lda
    *
    send "StartEdit" to #lda
    send "InsertLines" to #lda
    with "DEFINE DATA LOCAL" return #next
    send "InsertLines" to #lda
    with "1 MYSTRING(A10)" #next return #next
    send "InsertLines" to #lda
    with "1 MYNUMBER(I4)" #next return #next
    send "InsertLines" to #lda
    with "END-DEFINE" #next return #next
    send "EndEdit" to #lda
    *
    send "Stow" to #lda
    send "Close" to #lda

The calls to the methods `INatAutoDataArea::StartEdit` and `INatAutoDataArea::EndEdit` are used to mark the beginning and end of a series of editing operations.

To work with Natural development objects, a plug-in uses the interfaces described in the following sections:

`INatAutoObjects`
`INatAutoPrograms`
`INatAutoProgram`
`INatAutoDialogs`
`INatAutoDialog`
`INatAutoDataAreas`
`INatAutoDataArea`

## Working with Generic Text Documents

Through the interfaces described in this section, plug-ins can use the Natural Studio program editor as editor for arbitrary text objects. A plug-in can open a program editor session, pass a buffer with text data to it, let the user edit the data and then retrieve the modified data back. The plug-in itself is responsible for providing and storing the data to be edited. The program editor provides the usual editing functions, as far as they are appropriate for generic text objects.

To let the user edit a given text in the program editor, a plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoObjects` interface and then the `INatAutoGenericTexts` interface. Now it uses the method `INatAutoGenericTexts::Open` to load the text buffer into the editor.

We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`. Also we assume that the text to be edited is contained in the alphanumeric variable `#buffer`.

    #objects := #studio.Objects
    #texts := #objects.GenericTexts
    send "Open" to #texts
    with "Curriculum Vitae" "Dana Scully" #buffer
    return #text

The editor is then opened and the user can edit the text interactively.

The plug-in can use the resulting `INatAutoGenericText` interface to operate on the text, for instance, to insert lines:

    send "InsertLines" to #text
    with "Taught for two years at Quantico Medical School"

If the user chooses the Save button in the editor, the plug-in receives the notification `PLUGIN-NOTIFY-SAVE`. In response to this notification, it will usually retrieve the edited text from the editor and save it.

    #buffer := #text.Source
    * Now save the text in a plug-in specific way.

To work with generic text documents, a plug-in uses the interfaces described in the following sections:

`INatAutoGenericTexts`
`INatAutoGenericText`
`INatAutoObjects`

## Working with Generic Documents

A plug-in that maintains own development objects might want to provide its own editors for each of its development object types. Editors in Natural Studio typically maintain development objects in MDI (Multiple Document Interface) windows. In the following, we call them document windows. Natural Studio has a number of built-in editors, for instance, the program editor and the dialog editor. A plug-in can implement its own editor with a so-called generic document window.

Implementing such an editor as a generic document window makes the editor behave like the built-in editors in Natural Studio. Essentially this means: Several editor windows on different objects can be opened in parallel and the user can switch between them.

In order to implement a generic document window, you first create a Natural dialog of type "Plug-in MDI window". In your plug-in code, you can then open this dialog with the `OPEN DIALOG` statement and let Natural Studio display the dialog as a document window. Normally you will do this in the command handler of your plug-in, that is in the method `INaturalStudioPlugIn::OnCommand`:

    open dialog "mydlg" null-handle giving #dialogid
    #objects := #studio.Objects
    #genericdocs := #objects.GenericDocuments
    send "Add" to #genericdocs with #dialogid return #doc

The resulting `INatAutoGenericDocument` interface can now be used to operate on the document window.

The plug-in has several other means to communicate with the Natural dialog contained in the generic document window:

- The plug-in can send events to the dialog with the `SEND EVENT` statement and using the dialog ID.

- The dialog can send method calls to the plug-in. To achieve this, the plug-in should pass its own `*THIS-OBJECT` handle to the dialog in the `OPEN DIALOG` statement.

- The dialog can call the Natural Studio Automation interface. To achieve this, the plug-in should pass the `INatAutoStudio` interface pointer to the dialog in the `OPEN DIALOG` statement.

Whenever the user activates a document window, Natural Studio automatically switches the frame menu to a menu that contains the commands applicable to the active document. In the case of built-in document windows, these frame menus are predefined. In the case of a generic document window, the plug-in itself can provide an appropriate frame menu.

The plug-in can create a frame menu of its own by cloning an existing frame menu using the method `INatAutoFrameMenus::Clone` and adding new commands to the clone as necessary using the method `INatAutoFrameMenu::InsertCommand`.

Afterwards it passes the resulting `INatAutoFrameMenu` interface to Natural Studio when calling the method `INatAutoGenericDocuments::Add`.

To work with generic documents, a plug-in uses the interfaces described in the following sections:

`INatAutoGenericDocuments`
`INatAutoGenericDocument`
`INatAutoObjects`

## Working with Tree Views and List Views

Through the interfaces described in this section, a plug-in can display its own tree views and list views in Natural Studio. Tree views and list views are frequently used in Natural Studio to display development objects and to navigate through them.

In order to display objects in tree views and list views, the plug-in must first register the types of the tree or list view nodes that it is going to display. This procedure is described in Working with Node Types.

A plug-in that displays objects in tree views and list views must also implement the methods of the interface `INaturalStudioPlugInTree` appropriately. Natural Studio calls the methods of this interface when expanding or refreshing the tree.

In order to open a tree view, the plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoObjects` interface and then the `INatAutoObjectTrees` interface. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #objs := #studio.Objects
    #trees := #objs.ObjectTrees

The resulting `INatAutoObjectTrees` interface gives access to the currently open tree view document windows. Through this interface the plug-in can open a new tree view with a given root object.

    send "Open" to #trees
    with #type #key #caption
    return #tree

The node type specified in the method `Open` must have been registered before, as described in Working with Node Types. The `INatAutoObjectTree` interface returned from the method `Open` gives access to the tree view document window just opened. Through this interface the plug-in can, for instance, later close the document window.

    send "Close" to #tree

When opening a tree view, the plug-in specifies at least the type and key of the root object and a caption to be displayed on the tree view document window. Natural Studio will retrieve additional information needed to expand the tree view by using the interface `INaturalStudioPlugInTree` that must be implemented by the plug-in.

The nodes of a tree view can be accessed through the interface `INatAutoObjectTreeNode`. The root node of a tree view is retrieved with the method `INatAutoObjectTree::GetRootNode`, which returns an interface `INatAutoObjectTreeNode`. This interface can then be used, for instance, to expand the node and to access the child nodes. In the same way, the currently selected node of a tree view can be retrieved.

    send "GetRootNode" to #tree
    return #rootnode
    send "Expand" to #rootnode
    send "GetChild" to #rootnode
    return #firstchildnode
    send "GetNext" to #firstchildnode
    return #nextchildnode
    send "Expand" to #nextchildnode
    send "GetSelectedNode" to #tree
    return #selectednode
    send "Expand" to #selectednode

The interface `INatAutoObjectTreeNode` controls only the visual appearance of an individual tree view, not the underlying object structure, which is possibly represented differently in several views at a time. The object structure itself is under the control of the plug-in that defines and provides it through its `INaturalStudioPlugInTree` interface.

List view document windows are created in a similar way as tree view document windows, except that the interface `INatAutoObjectLists` is used instead of `INatAutoObjectTrees`.

To work with tree views and list views, a plug-in uses the interfaces described in the following sections:

`INatAutoObjects`
`INatAutoObjectTrees`
`INatAutoObjectTree`
`INatAutoObjectTreeNode`
`INatAutoObjectLists`
`INatAutoObjectList`
`INatAutoRefreshObject`

## Working with Result Views

Through the interfaces described in this section, a plug-in can display the results of its work in the Natural Studio result view. Objects displayed in a result view can be target of commands and can be used as starting point for navigation. Examples of built-in functions that use result views are the Cat All command and the Find command.

In order to display objects in result views, the plug-in must first register the types of nodes that it is going to display. This procedure is described in the section Working with Node Types.

In order to work with result views, the plug-in starts with the root interface `INatAutoStudio` and retrieves the `INatAutoResultViews` interface. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #resultviews := #studio.ResultViews

The resulting `INatAutoResultViews` interface gives access to the result view control bar and the currently open result views. The plug-in can use this interface, for instance, to show or hide the result view control bar.

    send "Show" to #resultviews

Through the interface `INatAutoResultViews` the plug-in can open a new result view.

    send "Open" to #resultviews
    with #caption #image #headers
    return #resultview

When opening a result view, the plug-in specifies a caption and an image to be displayed on the result view tab and (if needed) column headers for the result view.

The `INatAutoResultView` interface returned from the method `Open` gives access to the result view just opened. Through this interface the plug-in can activate the result view, insert rows into it and update the display. The method `SetVisible` scrolls a specific row into view.

    #resultview.Active := true
    send "InsertRows" to #resultview
    with #rows return #last
    send "Update" to #resultview
    send "SetVisible" to #resultview
    with #last

Finally the plug-in can close its result view.

    send "Close" to #resultview

To work with result views, a plug-in uses the interfaces described in the following sections:

`INatAutoResultViews`
`INatAutoResultView`

## Working with Environments

Through the interfaces described in this section, plug-ins can inspect the available local and remote development environments, map environments, connect to and disconnect from a remote environment and activate an environment.

In order to work with environments, a plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoSystem` interface and then the `INatAutoEnvironments` interface. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #system := #studio.System
    #envs := #system.Environments

The returned `INatAutoEnvironments` interface gives access to the local environment and all remote environments that have once been connected during the current Natural Studio session.

Through this interface the plug-in can, for instance, map a new remote environment, specifying host name, port number, user ID, password and other arguments.

    send "Add" to #envs
    with "IBM2" "4712" "SCULLY" "secret" "STACK=(LOGON XFILES)"
    return #env

The returned interface `INatAutoEnvironment` gives access to attributes of the environment.

    #bIsActive := #env.Active
    #bIsConnected := #env.Connected

The property `Parameters` gives access to the interface `INatAutoNatparm`. This interface contains properties that represent the Natural parameters under which the environment is running. Only a subset of the Natural parameters is available through this interface.

    #natparm := #env.Parameters
    #fuserDBnr := #natparm.FuserDBnr
    #fuserFnr := #natparm.FuserFnr

The property `SystemVariables` gives access to the interface `INatAutoNatsvar`. This interface contains properties that represent the system variables currently set in the environment. Only a subset of the system variables is available through this interface.

    #natsvar := #env.SystemVariables
    #language := #natsvar.Language

The plug-in uses the method `Disconnect` to disconnect from the remote environment.

    send "Disconnect" to #env

To work with environments, a plug-in uses the interfaces described in the following sections:

`INatAutoEnvironments`
`INatAutoEnvironment`
`INatAutoSystem`
`INatAutoNatparm`
`INatAutoNatsvar`

## Working with Applications

Through the interfaces described in this section, plug-ins can inspect the applications available on the application server, map applications into the Natural Studio session, connect to and disconnect from an application, activate an application and create and modify applications. An example of a plug-in that uses this section of the interface is the Application Wizard.

In order to work with applications, the plug-in starts with the root interface `INatAutoStudio`, retrieves the `INatAutoSystem` interface and then the `INatAutoApplications` interface. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #system := #studio.System
    #apps := #system.Applications

The resulting `INatAutoApplications` interface gives access to the currently active application server and the applications it contains. Through this interface the plug-in can, for instance, ask for the currently active application.

    #app := #apps.ActiveApplication

The plug-in can also create a new application and map it into the Natural Studio session.

    send "Add" to #apps
    with "MYAPPLICATION" return #app

The resulting `INatAutoApplication` interface gives access to attributes of the application.

    #bIsActive := #app.Active
    #bIsConnected := #app.Connected

For a compound application, the property `LinkedApplications` returns the interface `INatAutoLinkedApplications`. This interface allows accessing the base applications that are linked to the compound application.

    #linkedapps:= #app.LinkedApplications
    #iCount := #linkedapps.Count

For a base application, the property `LinkedObjects` returns an XML document containing the list of objects linked to the application.

    #aObjects:= #app.LinkedObjects

The plug-in can also link and unlink objects to and from the application.

    send "UnlinkObject" to #app
    with 1009 "OLDPROG" "MYLIB"
    send "LinkObject" to #app
    with 1009 "NEWPROG" "MYLIB"

Finally the plug-in can disconnect and unmap the application.

    send "Disconnect" to #app
    send "Unmap" to #app

To work with applications, a plug-in uses the interfaces described in the following sections:

`INatAutoApplications`
`INatAutoApplication`
`INatAutoLinkedApplications`

## Working with Plug-ins

Through the interfaces described in this section, a plug-in can inspect the currently installed plug-ins, read their properties and activate or deactivate a plug-in. This includes the possibility that a plug-in deactivates itself. An example for a plug-in that uses this section of the interface is the Plug-in Manager.

In order to work with plug-ins, the plug-in starts with the root interface `INatAutoStudio` and retrieves the interface `INatAutoPlugIns`. We assume here that the plug-in has kept a handle to the interface `INatAutoStudio` in a variable named `#studio`. This handle was passed to the plug-in during activation, in the method `INaturalStudioPlugIn::OnActivate`.

    #plugins := #studio.PlugIns

The resulting `INatAutoPlugIns` interface gives access to the currently installed plug-ins. Using this interface, the plug-in can, for instance, iterate across the installed plug-ins and inspect their attributes. The method `Item` returns an `INatAutoPlugIn` interface to a specific plug-in.

    #iCount := #plugins.Count
    for #i := 1 to #iCount
      send "Item" to #plugins
      with #i return #plugin
      #aName := #plugin.Name
      #aProgID := #plugin.ProgID
      #bIsActive := #plugin.Active
    end-for

Through the interface `INatAutoPlugIn` the plug-in can also activate or deactivate a specific plug-in by modifying the property `Active`. The following sample toggles the activation state of a plug-in.

    #bIsActive := #plugin.Active
    if #bIsActive
      #plugin.Active := false
    else
      #plugin.Active := true
    end-if

The interface `INatAutoPlugIn` can be used to send a command to the plug-in. The following sample checks whether the plug-in command with the ID "200" is currently enabled and if so, lets the plug-in execute the command. Of course this requires that we know that the plug-in implements a command with the ID "200" and what this command does.

    #bEnabled = false
    #bChecked := false
    send "OnCommandStatus" to #plugin
    with 200 #bEnabled #bChecked
    if #bEnabled
      send "OnCommand" to #plugin with 200
    end-if

Through the interface `INatAutoPlugIn`, the plug-in can get access to arbitrary services that another plug-in provides with a so-called custom interface. The following sample retrieves the custom interface of a plug-in and calls one of its services. Of course this requires that the plug-in has documented the services it provides with its custom interface.

    #icustom := null-handle
    send "GetCustomInterface"
    to #plugin return #icustom
    if #icustom ne null-handle
      #result := 0
      send "GetMaritalStatus" to #icustom
      with "Anderson, Gillian" return #result
    end-if

In order to provide a custom interface, a plug-in must implement an additional interface beside the two predefined interfaces `INaturalStudioPlugIn` and `INaturalStudioPlugInTree` and make this interface the default dispatch interface. For a plug-in implemented in Natural this means placing this interface at the first position in the `DEFINE CLASS` statement.

    define class ...
      object using ...
      id "..."
      interface icustom
        id "..."
        method GetMaritalStatus id 1 is gstat-n
          parameter using gstat-a
        end-method
      end-interface
      interface using nstplg-i
      interface using nstplt-i
    end-class
    end

To work with plug-ins, a plug-in uses the interfaces described in the following sections:

`INatAutoPlugIns`
`INatAutoPlugIn`

## Working with Dialogs

If a plug-in wants to open dialog boxes in Natural Studio, some special considerations have to be taken. The support of dialog boxes in plug-ins depends mainly on the condition if the plug-in is running in as an in-process ActiveX component or if it is running in a separate process.

The following topics are covered below:

- Plug-ins Running in a Separate Process

- Plug-ins Running In-process

### Plug-ins Running in a Separate Process

In general, an ActiveX component running in a separate process cannot open a dialog box in the client process. This restriction of the Windows system itself is overcome in the special case that a plug-in is written in Natural.

If a plug-in is written in Natural, it can open modal dialog boxes in Natural Studio. Precisely this means: Natural dialogs that are defined in the dialog editor with the Type attribute set to "Standard window" and the Style attribute set to "Dialog box". Other styles of the dialog type "Standard window" cannot be used in plug-ins.

To open a dialog box, a plug-in uses the usual `OPEN DIALOG` statement.

### Plug-ins Running In-process

If a plug-in is implemented as an in-process ActiveX component (this means: as a DLL), it can open modal and non-modal dialogs in Natural Studio. To open a dialog, the plug-in uses the statements usual in the programming language it is written in. Plug-ins written in Natural always run in a separate process, so this applies only to plug-ins written in programming languages that support implementing in-process ActiveX components.

For details on how to implement plug-ins in programming languages other than Natural, see Developing Plug-ins in Other Programming Languages.

### On this page

- Root Interface
- Interface Structure
- Working with Control Bars
- Working with Node Types
- Working with Selections
- Working with Natural Development Objects
- Working with Generic Text Documents
- Working with Generic Documents
- Working with Tree Views and List Views
- Working with Result Views
- Working with Environments
- Working with Applications
- Working with Plug-ins
- Working with Dialogs