MSM-Workstation
Building a Non-Trivial Application

Ed de Moel
September 1997

MSM Workstation offers the ability to build applications using windows-based tools. Although the tool-set is based upon the MWAPI (M[UMPS] Windowing Application Programmers Interface), it is also possible to include external objects and "components" into the applications that may be created.

Below follows a number of hints and descriptions of pitfalls that may help reduce the amount of stress that is inevitable while learning to use a new tool.

Table of Contents

Glossary

Every new tool-set brings its own collection of new terminology, or adds new meanings to familiar words. Appendix A contains a glossary for applications that use window-based or event-driven software.

Getting Started

Getting started will typically involve:

PDQweb, an easier alternative?

Components

In windows-terminology, any object that can be part of the make-up of a window is called a "component" (or sometimes "control" or "gadget"). Components that are available directly from MSM-Workstation, and the icons that are shown for these components in the tool-box, are:

As Displayed
in Window
In Alphabetical
Order
Button
Check Box
Combo Box
Date
Document
Drop Combo Box
Drop Down List
Generic Box
Group Box
Label
List Box
Lock
Long List
Picture
Radio Button
Scroll Bar
Spin Button
SQL Data
Tabbed Group
Text Box
Timer
Window

Additional components can be made available to the extent that a license is available to use or provide these components. See the chapter on Active X for details.

Interaction with the Window-Objects

In order for software to work, variables need to be initialized and redefined. This is no different in a windows-based environment than it is in a traditional procedure-oriented environment.

In a traditional environment, variables can be local to a procedure or shared by several procedures. In a windows-based environment, multiple instances of a window can co-exist at any give time, and some more effort is needed to keep track of exactly which instance of each variable is being accessed.

In order to facilitate this effort, MSM-Workstation offers a number of macros that generate code to access the various entities, be they traditional variables, or windows-related objects like the windows themselves, the components therein, or the various properties of these components.

In a number of cases, the macros generate code that manipulates the windows through the conventions defined in MWAPI, the ANSI standard for referencing windows from M[UMPS].

Since MSM-Workstation is based on the MWAPI, the developer can use these built-in macro calls, as well as direct references to the MWAPI itself.

The MSM-specific macro-calls:

The MWAPI syntax:

Most MSM-specific macros expand to direct MWAPI calls, in a number of cases, the MSM-specific macros offer access to features that are not yet standardized in the MWAPI.

Examples

Give a window a variable title and header

A window is invoked by either of the macros %%DoWin or %%OpenWin. Both macros allow parameters to be passed to the window to be created. These parameters are passed in an array that is accessible from the window through the macro %%IOVar.

Assume that the window is intended to display information about a person, and that it is desired to show the name of that person in the window's title. In order to achieve this, the action logic for the "create event" of the window itself should contain a command like:

%%Set(Title,"Information about "_%%IOVar("Person")
which expands to
Set ^$Window(%%CurrWin,"TITLE")= "Information about "_%%IOVar("Person")

If a similar parameter value is to be inserted as the constant value of a displayed text (label) in the window, the "title" property of the "component" in question has to be defined:
%%Set(Label1.Title,"Information about "_%%IOVar("Person")
which expands to
Set ^$Window(%%CurrWin,"G","Label1","TITLE")="Information about "_%%IOVar("Person")

If a similar parameter value is to be inserted as the variable value of a displayed text (Text Box) in the window, the "value" property of the "component" in question has to be defined:
%%Set(TextBox1.Value,"Information about "_%%IOVar("Person")
which expands to
Set ^$Window(%%CurrWin,"G","TextBox1","VALUE")="Information about "_%%IOVar("Person")

Populate a List Box

Assume that for a certain entity, the database contains a list of possible values, and that it is necessary to initialize a drop down list with these possible values. This initialization can be achieved by including code in the create action logic for the drop down list component that corresponds to:

merge ^$W(%%CurrWin,"G","DropDown1","CHOICE")=^global("fixed")
or new x
set x="" for  set x=$order(^global("fixed",x)) quit:x=""  do
. set ^$W(%%CurrWin,"G","DropDown1","CHOICE",x)=^global("fixed",x)

or new x
set x="" for  set x=$order(^global("fixed",x)) quit:x=""  do
. %%Set(DropDown1.Choice.x,^global("fixed",x))

If an initial display value is also desired, this could be followed by:

set ^$W(%%CurrWin,"G","DropDown1","VALUE")=value

Note: the value to be assigned in the latter case corresponds to one of the values that the loop-variable x received while establishing the list of possible values. The text that will be displayed in the text box will be the value of the corresponding ^global("fixed",x).

Where Does Which Action Logic Go?

The number of events that may happen while the interaction between an end-user and a window takes place is quite large, and for each event, there are different actions that make sense to undertake.

The list below describes all events, and the actions that are intended to be taken when these events occur.

Some events are labeled "high level" and some "low level". Attaching action logic to the low level events will allow for a greater level of control, attaching action logic to the higher level events will, in general, cause less overhead. Of course, it will remain a matter of judgement, which events are to be preferred for which actions, depending on the needs of the software.

High level events are: Check, Choose, Close, CommonCode, Create, Destroy, Enter, Error, Exit, Modified, MoveFirst, MoveLast, MoveNext, MovePrevious, Push, Scroll, UpdateControls and UpdateRecord.

Low level events are: change, char, click, close, dblClick, deselect, drop, fKeyDown, fKeyUp, goBottom, goDown, goDownBig, goTop, goUp, goUpBig, gotFocus, help, keyDown, keyUp, lostFocus, maximize, minimize, move, ptrDown, ptrDrag, ptrMove, ptrUp, resize, restore, select and timer.