Skip to main content

Global Items

SAL application globals need explicit containers in the generated .NET code. The table below shows the conventional desktop C#/VB.NET locations. PPJ Web must also preserve session ownership; read the Web Session State section before copying a desktop static-field pattern into a server application.

SAL Global ItemNew location in the .NET application
Internal FunctionsInt.cs or Internals.vb
External FunctionsExt.cs or Externals.vb
Global VariablesVar.cs or Variables.vb
User ConstantsConst.cs or Constants.vb
System ConstantsConst.cs or Constants.vb
ResourcesRes.cs or Resources.vb
Global Named MenusApp.cs or Application.vb

Generated global containers follow PPJ conventions that allow runtime expressions to resolve supported application globals without spelling out their C# container names. This is distinct from C# name lookup. Preserve generated registration and metadata when reorganizing assemblies; adding an arbitrary public member to another class does not necessarily make it an unqualified scripting global.

Application​

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 overridden methods:

  • OnAppStartup
  • OnAppExit
  • OnAppCreateAutomaticForms
  • OnSqlError
  • OnUnhandledException
  • OnThreadException

OnAppStartup

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

OnAppExit

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

OnAppCreateAutomaticForms

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

OnSqlError

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

OnUnhandledException

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.

Internals​

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

Constants​

Generated application constants are grouped in the Const class for C# or Constants class for VB.NET. PPJ system constants are available through Sys. The actual declaration is const or static readonly according to the required type and value.

Data types that cannot be ported to const using .NET native types are ported as public static readonly members. C# supports decimal constants, but DateTime values cannot be declared const. The generated choice also depends on the source value and PPJ type required.

Variables​

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

Externals​

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);
}
}

The wrapper separates application calls from the native ABI:

  • 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.

Resources​

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​

C# does not support static local variables; VB.NET does. 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()
{
...
}
}

Web Session State​

The static-container examples describe the desktop generation pattern. Ordinary .NET static fields and static events are shared within the server process. Do not use them for one user's credentials, current form, transaction, or report data. Review the session-aware code generated for PPJ Web and test concurrent sessions. See Wisej.NET statics.

When replacing a native external call, also verify pointer sizes, calling convention, string encoding, and DLL architecture. A declaration copied from a 32-bit application is not automatically valid in a 64-bit process.