Global Items

Open Text Team Developer had many objects that are global and shared by all classes in the application. In .NET everything must be in a class, therefore the most natural translation of global items to convert them to static members contained into static classes. In the Table below you can see the location of global items in the ported code:

SAL Global ItemNew location in the .NET application

Int.cs or Internals.vb

Ext.cs or Externals.vb

Var.cs or Variables.vb

Const.cs or Constants.vb

Const.cs or Constants.vb

Res.cs or Resources.vb

App.cs or Application.vb

All global members, in any assembly that is part of the project, are automatically recognized at runtime by the PPJ Framework without the need to scope them. Basically, if a global item (a variable, constant, internal function, etc.) is used in a bind expression or in a SalCompileAndEvaluate expression, there is no need to scope it because it is recognized automatically.


The App class (or Application class for VB.NET) is also used as a global context for the application. It contains the translation for: SAM global messages, globally defined named menus, and the global references to forms.

In the App class you will find the following overloaded methods:

  • OnAppStartup

  • OnAppExit

  • OnAppCreateAutomaticForms

  • OnSqlError

  • OnUnhandledException

  • OnThreadException


Code from the SAM_AppStartup message is translated into this overloaded method.


Code from the SAM_AppExit message is translated into this overloaded method.


The form templates that are marked with the AutomaticallyCreate property in CTD are created in this method.


Code from the SAM_SqlError message is translated into this overloaded method.


This virtual function is called when there is a unhandled exception. It gives the ported application a chance to add customized exception handling code as a last resort.

Named Menus

The App class also contains a child class called NamedMenus which in turn contains the definition of the global named menus from the original application. It's possible that Ice Porter has generated duplicated classes that cause a compiler error. This happens when there are also duplicated named menus in Team Developer. The difference is that Team Developer ignores the duplicated menus and simply uses the first one in the outline.

Form Template References

The App class also defines a public and static reference for each form template that has been ported by Ice Porter. The global reference is assigned by the form template class when it's created and it's cleared when the form is disposed of. This global reference is the equivalent of SAL code referencing a form instance by simply using the name of the form template.


All internal functions are ported as public static methods in the Int class for C# or Internals class in VB.NET.


All system and user constants are ported as public const members in the Const class for C# and Constants class for VB.NET.

Data types that cannot be ported to const using .NET native types are ported as public static readonly members. The only case where this conversion is necessary is for decimal and Date/Time constants.


All global variables are ported as public static members of the Var class for C# and Variables class for VB.NET.


External functions are ported into the Ext class for C# or the Externals class for VB.NET. The functions are ported as wrapper functions which then in turn call the interop definition.

The actual interop definitions are grouped into inner classes named after the external library.

For example, the external definition of GetParent from user32.dll is ported as follows:

public abstract class Ext
  public static SalWindowHandle GetParent(SalWindowHandle Param1)
    SalWindowHandle retVal = 0;
    IntPtr param1 = (IntPtr)Param1;
    retVal = USER32.GetParent(param1);
    return retVal;
  private class USER32
    private const string LibraryFileName = "user32.dll";
    [DllImport(LibraryFileName, EntryPoint="GetParent")]
    internal static extern IntPtr GetParent(System.IntPtr Param1);

There are many advantage to this:

  • The wrapper allows the ported code to remain unchanged when there are complex structure parameters which are flattened in SAL.

  • External references can be eliminated by moving the implementation in the wrapper, the wrapper can be modified to add logging, debugging or other features that are impossible to implement in a direct interop call.

Structures (structPointer and struct in Team Developer) are generated as child classes of an internal child class named Structures. The structure declarations are named STRUCT_# and numbered incrementally.


The resources definition coming from the Resources section in the original SAL application are ported into the Res class for C# or the Resources class for VB.NET as static members.

Static Locals

.NET does not support static locals, just like Java. The static variables declared as locals in a function in SAL, are ported as private static members of the container class (the class that contains the method) and prefixed with the function name.

For example, if an internal function Test defines a static local variable nCount, the variable is ported as:

class Int
  private static SalNumber Test_nCount = 0;
  public static SalNumber Test()

Last updated