Tips_todo   >   Notation   >   Notation (All Contents)
This section is a bit of "catchall" for information about notation not covered in other areas of StudioTips.
Notation is very powerful. Once you get the hang of using notation you'll soon find you prefer notation over the Omnis commands. (At least that's been my experience)
It took me year to discover the full power of the Notation Inspector (F4) coupled with the Property Manager (F6). I wish I had discovered how they work together much sooner! They are an amazing team. Be sure to read more about the Notation Inspector in this section.
SKIPPING $root ... and other parts of the notation string.
You rarely need to include $root in your notation strings. Studio "always" assumes $root if not specified.
If you can avoid "$libs.LibName" in your notation using "$clib" in its place, do so. It will make your code independent of the library name.
Likewise, use $cinst, $cobj, $cfield whenever possible to make your notation less dependent on class or object names.
(See the Notation $c... for a complete list of all the "current" notation.)
Objects that are inside of any container field have an added property called $container.
$container gives you a reference to the container of the object
Examples of container objects are: Scrollbox, GroupBox, ComplexGrid, TabPane, PagedPane$desc has to be one of the handiest tricks I learned for doing notation.
If you want to $add something to a group but can't remember what all the possible parameters are, $decs can be used to figure them out.
Let's say you want to add a local variable to method using notation. You know variable are in the $lvardefs group of the method, but can't remember the parameters for $lvardefs.$add.
Add $desc to the end of the notation you know, and then return the result to #S1, then look at the value of #S1. If you right-click on #S1 you can copy the result to the clipboard and then paste it into a comment line in your code. Handy!
Click the "Run Demo" button to test try this out. The demo code will take you to a breakpoint. Step through the code.
NOTE: A method can't add an $lvar to itself. An instance can't add an $ivar to itself.$fullname gives the full notation path to any valid item reference.
If you have a reference to a class or object, adding "().$fullname" to the reference returns the name property.
You may ask, why did we include the open and close () parenthesis in front of $fullname?
Good question!
You can't always rely on using $fullname without the () prefix. In some cases it will return notation instead of the actual property name. To be safe, I've gotten into the habit of alway prefixing $fullname with ().
Click the "Run Demo" button to see and example.Omnis use $name for accessing the name property of a library, class, or object.
If you have a reference to a class or object, adding "().$name" to the reference returns the name property.
You may ask, why did we include the open and close () parenthesis in front of $name?
Good question!
You can't always rely on using $name without the () prefix. In some cases it will return notation instead of the actual property name. To be safe, I've gotten into the habit of alway prefixing $name with ().
Click the "Run Demo" button to see and example.Variables are part of the $?vardefs group. Class variables: $cvardefs, Instance variables: $ivardefs, Local Variables and parameters: $lvardefs. You can find the variable groups using the F4 Notation Inspector.
The syntax for adding a variable using notation is as follows:
Do VarDefsGroupRef.$add('VarName',pkDataType,pkDataSubType,pkDataSubLen,pbIsParamater) Returns VariableRef
You can check F9 > Constants > Data type and Data subtypes for the possible parameters.
Not all data types have a data subtype or data sublength. (See the sample list below.)
The pbIsParameter variable is only applicable to the $lvardefs group and is only needed if you want the variable to be a parameter. Sending 'kTrue' as pbIsParameter will make the variable to be the next parameter for the method. To the best of my knowledge you cannot insert a parameter before an existing parameter, it can only be added to the end of the existing parameters. If you are notationally copying parameters, you first need to make a list of the $lvardefs and sort the $lvardefs group by the $parmno property, then loop through the list of adding the local variables so that they will remain in the same order. Remember to include an extra comma(s) in the list of parameters when adding a parameter that doesn't have a data subtype or data sublength.
Set Reference LocalVarsGroupRef to $libs.LIBRARY.$classes.CLASS.$methods.METHOD.$lvardefs
Do LocalVarsGroupRef.$add('pLineNum',kInteger,kLongInt,,kTrue) Returns VarRef
Do LocalVarsGroupRef.$add('pIsInsert',kBoolean,,,kTrue) Returns VarRef
Note: You can not have a method add a local variable or parameter to itself. The variable must be added from outside of the method. You can not add an instance variable to an instance of a class, the variable must be added before the class is instantiated.
The following is a sample list of the variables and their subtypes. (Provided by Rudolf Bargholz)
$add('Col_Char',kCharacter,kSimplechar,100)
$add('Col_NatChar',kCharacter,kNatchar,100)
$add('Col_Longint',kInteger,kLongint)
$add('Col_Shortint',kInteger,kShortint)
$add('Col_Date',kDate,kDate2000)
$add('Col_Bool',kBoolean)
$add('Col_NumFloatdp',kNumber,kFloatdp)
$add('Col_Fieldref',kFieldreference)
$add('Col_Itemref',kItemref)
$add('Col_Binary',kBinary)
$add('Col_List',kList)
$add('Col_Object',kObject)
$add('Col_Picture',kPicture)
$add('Col_Row',kRow)
$add('Col_Sequence',kSequence)
Adding Date Time variable (Thanks to Terence Young)
$add('Col_DateTime',kDate,kDatetime,16)
Where the sublength of 16 is the 16th item in the $clib's #DFORMS system table's list. Typically, this list starts out with only eightDo $cinst.$ivars.$sendall($ref.$assign(''))
If you need to clear the instance variables for any instance you can use sendall to clear them.
Thanks to Fred Haislmaier for this tip.
NOTE: The above sendall will blow away your row and list definitions.You can copy any object and all it's attributes using notation.
1. Set a reference to the source object you want to copy.
2. Add the same object type to the target, returning a reference to it.
3. Step through the attributes group of the source object, setting the target object attributes to the same values.
Copying a class using notation is very easy. The same code below show you how to do it.
Thanks to Andreas Pfeiffer for this tip.rhJobs.If you use the return value for Quit method to indicate a true or false result the Omnis command "Do inherited" used to be a problem (pre v3.0), because it always returned kTrue. (This bug has been fixed!)
The notation alternative to "Do inherited Returns FlagOK" is:
Do $cinst.$inherited.[$cmethod().$name]() Returns FlagOK
But now that the bug is fixed, why bother using notation? :-)
Click the "Run Demo" button to prove the theory.Using the F4 Notation Inspector in conjunction with the F6 Property Manager can help you out big time with learning/using/writing notation. It took me over year to figure this out ... had I known it, I could have saved quite a bit of time learning and writing notation in Studio.
Click the 'Run Demo' button to learn how to use the Notation Inspector and Property Manager for writing notation. It will give you a step by step well commented walk through writing notation which actually adds a button and method to the demo window instance.
This demo was a lot of work to put together ... so be sure to try it out. :-)
The Notation Inspector and the Property Manager ... an amazing team!
Thanks to Bob Preston for his email on the list server which opened my eyes to the power of using the Notation Inspector and Property Manager for writing notation.
Thanks to engineering for setting this up so we can use them interactively while stepping through and writing code!While developing StudioTips I ran into snag with the "$destruct" method in my window. I was using a superclass $destruct method to save the last closed size and location of the subwindow class.
The method failed because the subclassed window's $top, $left, $height, $width properties were inherited from the superclass. To make the code work I had to manually overload these attributes for each subwindow.
Not wanting to do this manually, I asked Tech Support for some help. They pointed me to the "$isinherited" property.
Class properties that can be inherited from a superclass have an "$isinherited" property which you can assign using notation. You can override (or inherit) a property by setting the $isinherited property.
Sample code below shows the solution I used to override and then store the subclass window size and location.The notational equivalent of "Queue set current" field is :
Do $ctarget.$assign(rFieldObject)
Using "Do $ctarget.$assign" is more reliable than Queue set current field
You can not use "Queue set current field" for subwindow fields from outside the subwindow's window instance.
Thanks to Philippe Vanden Broeck for this tip.In the process of doing the demo windows for StudioTips I tripped across an interesting idea.
In the "Lists - $merge" demo I had 3 lists, each with their own $construct which created their own lists. After doing each merge demo I wanted to reset all the lists to their original state.
Behind the Reset button I added a single line of code:
Do $cinst.$objs.$sendall($ref.$construct())
It worked like a charm! You can check it out by clicking the Run Demo button.
Think about it, you could have a special method in all your window objects and with a single $sendall each object with that method could do something or return something. You could control the action take at the object level. There's some interesting possibilities...For years I thought if I was using [] square brackets in the 'Field name' of a Calculate everything had to be inside the square brackets. For example:
Calculate [con('Field',%N)] as 'Some value'
Much to my surprise, I noticed a posting on the Omnis list server from Wietse that looked like this:
Calculate Field[%N] as 'Some value'
It tested it, and it worked! Much simpler! Thanks Wietse Jacobs.
Now if we could only do the same thing in the 'as' side of the Calculate, dropping the con(), hmm...
Calculate Field[%N] as 'The current loop count value is ',[%N]This section covers current objects notation ($ctask, $clib, $cinst, $c...) and provides demos for each. Current notation is very helpful in shortening notation strings and making your code flexible and generic.
Current notation is a reference to the item. $clib is a reference to the library. A reference to an item lets you find out or assign properties of that item.
FROM THE OMNIS HELP NOTES
Under $root, Omnis contains a number of global state variables that tell you about how Omnis is currently executing, or what objects, instances, and methods are currently being used. These objects provide a shortcut to the current object or instance that is currently executing. Mostly their names begin with "$c".
You can use the current objects in place of the full notation for a specific object to make the object and its code reusable and portable between libraries. For example, you can use $cinst in a method within a window instance to refer to itself, rather than referring to it by name.
$cinst
rather than
$root.$iwindows.WindowInstanceName
You can refer to the current library using $clib. For example, to make the current library private using:
Do $clib.$isprivate.$assign(kTrue)
$cclass is the class which the method is located in.
Click the run demo button to see the $cclass of this method.The field where the current method is executing.
For some window objects I add a $construct method so that the field will set some of its own properties when the window is being instantiated. $cfield works great for those situations.
Do $cfield.$edgefloat.$assign(kEFposnClient)The current instance; usually the instance containing the currently executing method.
Almost everything you run in Omnis Studio is an instace of the actual class, not the class. Code classes, schema classes, and search classes are exceptions.
Think of an instance as a photocopy of the original. You can have as many photocopies as you want. Each photocopy has a $name property which is automatically assigned, or can be assigned using notation.
Click the run demo button to see the $cinst of this object class.$clib is the library the current class is located in.
Click the run demo button to see the $clib of this object class.The currently executing method.
Click the run demo button to see the $cmethod of this method.The current object that received a $event message.
$cobj is great for event handling methods. You could be 3 methods away from the pushbutton that was clicked and $cobj still gives you a direct reference to the pushbutton.
Click the run demo button to test $cobj of the run demo pushbutton.The current recipient of an event; if a custom method is being processed, $crecipient is the recipient of that method.
Methods inside of any "container" field can refer to their "container" using $crecipient
Calculate ContainerName as $crecipient().$name
Thanks to Wietse Jacobs for this tip.
The "container" that Wietse refers to is the "object" that the method belongs to. At first I thought he meant "container fields" like Page Pane, Group Box, Tab Pane.
After doing some testing (Run Demo) I realized that the $crecipient "container" is the object or class that the "method" is "contained" in.
If the method belongs to a window object, then $crecipient will be the object. If the method is a class method of a window, then $crecipient is the window class.
An interesting discovery while making the demo is that using:
Do method $_ClassMethodName does NOT change the $crecipient. Whereas:
Do method $cinst.$_ClassMethodName
or Do $cinst.$_ClassMethodName
DOES change the $crecipient.
I recall a discussion that "Do method $_ClassMethodName" does NOT add to the method stack (affecting max stacked methods), whereas, "Do method $cinst.$_ClassMethodName" and "Do $cinst.$_ClassMethodName" do add to the method stack.
The fact that "Do method" does not change the $crecipient might be related to the above discovery.
A reference to the target field, that is, the field which currently has the focus (shows the caret
and is sent keyboard events)
The notational equivalent of "Queue set current field" is:
Do $ctarget.$assign(rFieldObject)
Using "Do $ctarget.$assign" is more reliable than Queue set current field.
You can not use "Queue set current field" for subwindow fields from outside the subwindow's window instance, whereas you can use $ctarget.
GOTCAH: The window/pane must already be visible (in front) before you issue $ctarget. You can not use $ctarget.$assign during the $construct of a window instance. If you are changing tabs in a tab pane, make sure the "tab clicked event" has been processed before you attempt to use $ctarget. (This one had me stumped for a while!)In Omnis Studio when you open a window you open an instance of the window. Just about everything in Omnis runs in an instance of the actual class. The instances all run with a task instance.
Many applications just run under one task instance, the Startup_Task instance.
The Startup_Task instance name defaults to the same name as the library name which the Startup_Task task class is located in.
Click the run demo button to see the $ctask of this object class instance.The current window instance.
For subwindow window instances $cwind is the parent window. Don't use $cwind if $cinst will work for you. $cwind changes depending on which window is on tip, this could cause your code to break. Always think for minute before you use $cwind.
For window menus and toolbar, you would use $cwind to send a message from the menu or toolbar to the window. Each menu and toolbar has its own instance so from inside those intances $cinst would point to them, and $cwind would point to the window which "owns" the window menu orwindow toolbar. However, a "better" ways it to use the "observer" design pattern. See menus on-the-fly for more details and a demo.
TIP: If you need to find out whether or not a window is a subwindow, compare $cinst to $cwind.
If $cinst<>$cwind
; The $cinst is a subwindow.
End If
The topmost open window instance.
Click the run demo button to test $topwind.A reference is a variable of item reference type which is pointing to something in Omnis. A reference could be pointing to a window instance, window class, window object, object method, list variable...
If you are using notation, you will either write very long notation strings or use references and write much shorter notation strings. You can use references to make your code more stable and efficient.
REFERENCES EXPLAINED
I still get confused by references. When to include $ref, when not to, and a few other issues. The following was taken from a list server posting by Tim Stewart. It should help your understanding.
Tim wrote a quick overview of the various references. The posting is listed in the sample code below.There is a confirmed bug with trying to store objects or object instance references in a datalist. (<=v3.3)
The object references appears to work if you test them immediately but then as soon as you change the current line in the list and then come back to it, the object/reference is lost!
Myself and others have burned many hours figuring out this problem and attempting to work around this bug.
This problem hosed my "Observer Design Pattern" where I was trying to store references to object instances in the registered observers list. No matter how hard I tried, I couldn't send messages back to the object instances.
The best workaround that I've seen is Tim Stewart's. He discovered that you can use a row variable and dynamically add a column to the row variable for each object reference you wish to store.
But be warned, apparently if your are using this technique to store a smart datalists, the smartlist is lost.
Tech Support has confirmed the objects in datalist bug. It will be fixed in version 4.0 with the introduction of a new "Object Reference" variable.
Apparently there is another object instance bug where Studio sometimes generates a new instance of an object when send a message to the obejct. I haven't figured out exactly how to replicate this bug.You have a valid reference, now you want to find out what library it is in, what class it is in, etc. (Anything up the $fullname notation string of the item.
To find this information, you add the name of the parent after the reference, then (), then $name of any valid attribute.
Example:
Do $clib.$windows.wContextMenu.$objs.$findname("Field1") Returns rWinWindow objects inside container objects can be referenced notationally directly as window objects. You can leave the 'containers' out of the notation string, and the reference will still be valid. This also applies to subwindow window instance fields. The subwindow's fields become part of the parent window
All of the following references are valid and will work
Set reference rField to $cinst.$objs.SCROLLBOX.$objs.NESTEDSCROLLBOX.$objs.ENTRYFIELD
Do rField.$forecolor.$assign(kRed)
Set reference rField to $cinst.$objs.SCROLLBOX.$objs.ENTRYFIELD
Do rField.$forecolor.$assign(kGreen)
If you are going to use notation to manipulate the properties of any window object, an easy way to get a reference to that object is:
1. Add an item reference instance variable by the name of the field to the window class. (irFieldName)
2. Add a $construct method to the object, if one does not exist already.
3. As the first, and usually only, command in that $construct. "Set reference irFieldName to $cfield"
This will set the ivar reference to the correct field in a manner that is impervious to renaming of the object or even copying and pasting the object into another window.
Example: I often use a Tab bar to control the page of a paged pane that is displayed.
The $construct of the paged pane contains:
Set reference irMainPagedPane to $cfield
The $construct of the tab bar contains:
Set reference irMainTabBar to $cfield
Then the $event method of the tab bar contains:
On evClick
Do irMainPagedPane.$currentpage.$assign(irMainTabBar.$::currenttab)
Neat, huh? I wish that I could claim credit for this tip.
However, it comes from _my_ instructor, Brian O'Sullivan. It was a Studio Tip in late 1998, I think. Craig Lewis
Thanks Craig Lewis for this tip.
NOTE: I use this technique extensively! It works great! Look at all the "ir..." variables in wTips_Browser!There are several ways which you can get or set a reference to something.
1. Set reference - this is the standard Omnis Studio Omnis command for setting a reference.
2. Return a reference from a notational string which will do so.
Thanks to Mark Phillips I rarely use the "Set reference" Omnis command anymore.
Mark taught me about $findname() Return Ref and then testing for null. I've been using it ever since.
Once advantage of using $findname is that it doesn't get messed up by "$" characters in a public method name.
The following "Set reference" will fail.
Set refererence $cclass.$methods.$construct to rMethod
This is maybe an obscure situation but having solved the problem once I thought I may has well add it to StudioTips in case another developer had a similar problem.
Let's say you have an Object A, and create an instance of it. The instance could be in a task instance, or a window instance, or even another object instance. Object A's instance has some values in it. For this discussion we'll assume you want to share the Object A's single instance between 2 different windows. These windows might even be part of separate task instances.
Window A opens an instance of Object A. Window A now wants Window B to share that instance of Object A. You don't want to create additional instances of Object A, you want to share the single instance of Object A.
The trick is to set up an item reference variable in Window B and pass a reference of Object A from Window A to Window B. You must include ".$ref" appended to the end of the Object A instance when passing it to Window B.
Click the Run Demo button to try this out.There is a confirmed bug in Omnis Studio 3x that won't be fixed until version 4.0
I lost more than a few hours tracking it down and eventually reporting it to Tech Support. Hopefully, this note can will save some tips users the same grief.
If you have an item reference instance variable in a superclass this bug can affect you.
Attempting to set or use the superclass item reference instance variable with the prefix "$cinst." will not work.
In my particular case I was using the superclass item reference variable "irMainList" to point to a data list in another object.
This line of code resulted in NULL. It did not work.
Calculate #S3 as $cinst.irMainList.[iFKColName]
This line of code did work.
Calculate #S1 as irMainList.[iFKColName]
Tech support has confirmed the bug, but said it would not be fixed till version 4.0. ST/NT/442
I use the "$cinst." prefix to avoid accidentally overriding superclass instance variables when I copy and paste the superclass code to a subclass method. This nastyn "feature" is supposed to be fixed in version 4.0. That will negate the need for prefixing instance variables with "$cinst.". Boy, I am looking forward to version 4.0!