Using UI Toolkit with the .NET Framework
There are three ways you can use UI Toolkit code with the Microsoft .NET Framework:
- Use the Toolkit .NET routines to embed .NET forms in Toolkit windows. With this method, you compile the application with the traditional Synergy compiler and then run the application with the traditional Synergy runtime. See .NET Routines for information.
- Include Toolkit code in Synergy routines called from xfNetLink .NET. For information, see Creating Synergy .NET Assemblies and UI Toolkit routines.
- Build and run the Toolkit application as a Synergy .NET application with a cell-based appearance. This is an unsupported option. See Using Toolkit code with Synergy .NET (Windows) below.
UI Toolkit includes the Synergex.SynergyDE.tklib.dll library for building and running Toolkit code as a .NET application. Although this is available on Windows, it is not supported. (It is not available for Mono or .NET Core development.) On Windows, most Toolkit routines and Script commands are available, though they result in applications with cell-based rather than Windows-like appearance and functionality. For example, the mouse won’t work in most instances. Note the following:
- Toolkit routines generally function as they do on UNIX (e.g., %U_SAVESETTINGS always returns false). But there are exceptions. Some of these are listed below; others are documented with the routines they apply to.
- Code with calls to the following routines won’t compile: %AX_TKCALL, AX_TKGET, %AX_GETINT, AX_TKSET, %TB_BUTTON, %TB_INFO, %TB_TOOLBAR, and the Script compiler routines (%SCR_ routines).
- Native .NET status bars are used for the information line and footer.
- Native .NET controls are used for menus, but note that automatic menu drop down is not supported, the input string passed to M_PROCESS is not used, and the only alignment settings supported for %M_POPUP are D_POPUP_LEFT and D_POPUP_RIGHT.
- Arguments with the “any” type cannot take objects. For example, you cannot pass an object as one of the method data arguments for C_PROCESS.
- Bounds checking is automatically provided by the Synergy .NET compiler, but for more complete bounds checking, you can use g_dtkbounds (or DTK_BOUNDS) and DTK_BOUNDS_LOG. See Bounds checking.
- If you want the font to be scaled when the application is resized, maximized, or restored, set the SYN_RESIZE_SCALE environment variable to 1.
- By default, Toolkit uses cell-based-style message boxes for U_MESSAGE, %U_MSGBOX, and U_WAIT. However, if g_netnativemsgbox is set to true, Toolkit uses native Windows message boxes for these routines. See g_netnativemsgbox.
- There are some restrictions on the ways you can use global fields in tkctl.def and tools.def. See Restrictions for global fields below.
The following is a summary of the process you’ll follow to use Toolkit code with the .NET Framework on Windows. See Debugging Synergy Programs.
|1.||Create a Synergy project in Visual Studio.|
|2.||Add a reference to Synergex.SynergyDE.tklib.dll in your project. This is installed in a CLR directory under Program Files\Common Files\Synergex.|
|3.||Use supported Synergy DBL and Toolkit routines to create the program. You can also define your Toolkit windows in windows script files and then compile the script files with Proto or Script. (See step 1 through step 3 of Getting started with UI Toolkit.) Script and Proto run only in traditional Synergy, but the libraries they create are compatible with Toolkit applications for .NET.|
|4.||Build your application in Visual Studio. This creates an .exe or a .dll assembly.|
When using Toolkit code with .NET, there are some limitations to the ways you can use global fields defined in tools.def and tkctl.def. The following are not supported:
- Ranging when assigning a value—for example, “g_entnam(7:4) = number”. Instead, you can assign the value of the global field to a temporary field, and then use ranging with that field.
- Assigning a value from a different type (implicit conversion). Instead, use explicit conversion.
- Assigning a value and then using the result of the assignment in the same statement—for example, “if (g_select = value)”. Instead, separate the assignment and the use of the assignment into two statements:
- Modifying through a cast—for example, “clear ^i(g_entnam)”. Instead, use a temporary field:
clear ^i(temp_var) g_entnam=temp_var
- Accessing groups or record names.
- Passing global fields as modifiable parameters to subroutines, functions, or methods. Instead, you can pass a temporary field and then assign its value to a global field.