All functions generated as members of visual classes are wrapped inside a SalContext instance using the following code construct:

using (new SalContext(this))

The reason for this construct is that hWndForm, hWndItem and hWndMDI system variables must be kept updated with the current context dynamically.

It would not be enough to simply declare instance members in the PPJ visual classes, and it would be wrong to always convert to this.

Additionally, the context must be stacked. When a function inside Form1 calls a function in Form2, the context is switched when entering the code in Form2 and restored when returning.

The following list contains the most important reasons for this technique and why any other approach would fall short:

  • Internal functions use the hWnd* variables.

  • Functions in non visual classes also use hWnd* variables.

  • hWndItem has a different meaning depending on the origin of the call, therefore in many cases it cannot be optimized to this.

  • SQL binding uses the current hWnd context to resolve symbols.

The SalContext class implements IDisposable so that it is disposed automatically when the using block is exited. The constructor of the class pushes the instance onto a stack and the Dispose method pops the last instance. However, the code is optimized for performance and the last instance of SalContext is cached to avoid multiple push/pop operations when the code executes within the same context.

This kind of technique to track context switching is also widely used in the Microsoft Foundation Classes library (MFC). A similar technique is used to keep track of SQL context switching. See SqlContext.

It is not necessary to enclose the code in the using block unless the code uses hWnd variables and it is called by outside of the class, or it calls outside of the class into another function using a hWnd variable.

Since it's impossible to determine safely when not to use this construct, and since the performance hit is negligible, Ice Porter always generates the using block when translating functions in visual classes.

Last updated