Skip to main content

SalContext

SalContext preserves the current SAL window context while a method executes. That context supplies variables such as Sys.hWndForm, Sys.hWndItem, and Sys.hWndMDI. Those variables describe the current SAL operation; they are not simply synonyms for the C# variable this.

Why the Scope Is Needed

A button, its containing form, and the object containing a called helper can be different objects. A global function has no form instance of its own, yet source SAL code may still use the current form or item. SQL binding can also depend on the active visual context.

Ice Porter therefore generates scopes around visual-class methods in the usual form:

using (new SalContext(this))
{
// Generated method body.
}

Retain these scopes when moving code between methods. Even if the immediate body does not read a window variable, a function called from it may do so.

Nested Calls Restore the Caller

Suppose Form A calls a method on Form B. The logical context changes as follows:

Enter A → current context A
Enter B → current context B; remember A
Leave B → restore A
Leave A → restore the context that preceded A

SalContext implements IDisposable. The using statement restores the previous context on normal exit, early return, and an exception that leaves the scope. The runtime can optimize repeated entry into the same context, so this logical stack need not imply a separate physical push for every call.

The interactive context walkthrough shows both normal return and exception unwinding together with SqlContext.

Context Is Not Ownership

Leaving a SalContext scope does not close the form, dispose its controls, or end a database transaction. The scope restores execution context. The form and database resources keep their own lifetimes.

Likewise, establishing a context does not validate an arbitrary stale handle or make an object safe to access from another thread. Determine which live form/control the operation belongs to before entering the scope.

New Code and Asynchronous Work

When a new native event or helper invokes SAL code outside the generated action path, establish the appropriate context for that operation. Do not automatically use the helper object's this if the helper is not the relevant visual object.

Keep context-dependent work within the supported synchronous UI/session execution path. An await can resume on a different execution context, and a worker thread or another web session does not inherit the meaning of the caller's SAL window variables merely because it received an object reference.

For background work, prefer explicit inputs that do not depend on window context, then use the target UI framework's supported mechanism to return the result. Test the context before entering a nested call, inside it, and after both normal and exceptional exits. See SqlContext for the separate local-variable and owner context used by SQL expressions.