Tips   >   Tasks   >   Tasks (All Contents)

Tasks

When I started working with Omnis Studio tasks were a confusing to me because I couldn't picture what a task was nor what it did.

Windows, menus, toolbars, and reports are visual, so it is easy to see what they are and what they do. Object classes are non-visual, but it is doesn't take long for you to see that objects are a great place to write code where it can be neatly contained in a single class and then accessed by multiple classes.

Task classes look like object class, but what purpose do they serve?

In Omnis Studio when you instantiate a class (window, menu, toolbar, report) the instance is always contained within a task instance. You can find out an instance's task from inside the class instance with:

Calculate MyTaskName as $cinst.$task().$name

By default when a library is opened Omnis Studio opens the library's Startup_Task and names the task instance the same name as the library name. To look at the currently open task instances:

  1. F4 Notation Inspector
  2. Open the $itasks node in the treelist and you will see the currently open task instances.

When the Startup_Task instance is opened it receives a $construct message. You normally put code to open a logon window, install menus, and open the first window, in the $construct method of the Startup_Task.

The menu instances which you open are contained within the library's Startup_Task task instance. If you then use a menu line method to open a window, that window instance will be contained within the same task as the menu's task. Even if the menu line method opens a window class that is inside another library which has its own Startup_Task, the window instance will be contained within the same task as the menu's task, not the other library's task.

Task variables have task wide scope. This means that any instances contained within the task have direct access to the task variable values.

Multiple Libraries

When you create a new library Omnis Studio automatically adds a Startup_Task to the library. If you are writing a multi-library application (a good thing to do) by default you will have a Startup_Task in each library. There is no requirement to have a Startup_Task in each library. If your multi-library application is structured so that the user opens a main library who's Startup_Task then opens the other libraries, installs the menus, and opens a logon window, you could simply delete the Startup_Task classes in the other libraries.

There is one problem you will run into when you delete the Startup_Task. Each class has a $designtaskname property which defaults to Startup_Task. When you are writing code in class the task variables of the $designtaskname will be visible to you in the IDE. If the Startup_Task is deleted, you won't see any task variables.

Changing the $designtaskname in the classes of all other other libraries to the main library Startup_Task is a pain to do and not really a wise thing because it hard codes the $designtaskname of your classes to another library name which could be changed.

The solution which I have found that works well for me is to do the following:

  1. Copy the Startup_Task from the main library to the sub-library.
  2. Delete all the methods from the Startup_Task in the sub-library.
  3. Add a $construct method to the Startup_Task and add a single line of code to the method

    Do $cinst.$close()



    This immediately closes the sub-library Startup_Task when Omnis Studio tries open it.
  4. Copy the sub-library Startup_Task to the other sub-libraries.
The sub-library classes can leave their $designtaskname property set to Startup_Task, and you have a copy of all the main library Startup_Task variables handy to you in the IDE while you are writing code in the sub-library.

Multiple Tasks

You can instantiate multiple tasks and within each task instantiate menus, toolbars, and windows. Omnis Studio keeps track of an $activetask. Generally speaking the $activetask is the task who's window instance is the top window.

Clicking on a window from another task causes that window's task to become the $activetask.

Menus and toolbar instances have a $local property which defaults to kFalse. Using notation you can set the $local property to kTrue.

Do WinInstRef.$local.$assign(kTrue)

When $local is set to kTrue the menu or toolbar will be shown and hidden based on whether or not the task in which it is contained is the $activetask. This feature can be handy for automatically showing or hiding menus and toolbars that belong to a set of windows. To make this work you need to set up a task instance for each set of windows, menus, and toolbars that you wish to group together.

When you open the window, menu, and toolbar you need to do so through the task so that the instances will belong to the task. This can be accomplished by having the task's $construct method open the window and install the menu and set the menu's $local property to kTrue. Alternately could add an $initialize method to the task which will do this. You can then send the task a $initialize method at any time triggering opening the window and installing the menu.

As long as you ask the task to open the instance, the instances will be owned by the task.

Click the Run Demo button at the bottom of the StudioTips Browser window for a demonstration. The demo will install a Task Switcher menu. Use the Task Switcher menu to open Task 1 and then open Task 2. Each task installs a menu and opens a window. The menus are automatically shown and hidden for their respective window. A series of OK messages let you know the series of methods that are called in each task as it is opened and activated or deactivated.

You can shift+select any Task Switcher menu item to step through the code.