Creating and processing composite windows

The composite window routines and methods enable you to create and process composite windows, which are windows that consist of a parent window and child windows and/or lists. For example, you could create a composite window with input fields at the top for header information, a table in the middle for line item entry, a multi‑line “notes” field that supports rich text editing through an ActiveX control, buttons, and so forth. A composite window functions and appears to the user as a single window.

The parent window in a composite window is the composite container window. Windows or lists within a composite container window are child windows or child lists. A child window or list can be any type of UI Toolkit window or list, including ActiveX windows, tab set windows, ActiveX Toolkit lists, .NET form windows, and other composite windows. (A composite window can have a maximum of 2047 children.) Note the following:

A composite window not only appears to users as a single, unified window, it is also treated in many ways as a single window by the application. Calls you make that affect the container affect the composite window as a whole:

To create a composite window,

1. Create the composite container window with the DC_CREATE subfunction for %C_CONTAINER. See DC_CREATE.
2. Add child windows or lists or both to the container window. As you do this you can set properties for the child windows and lists, including placement, tabbing position, a menu column to be loaded when the child is processed, and the name of a routine to be used in place of the default method for the child. See DC_ADD.

Placing, removing, and deleting windows

When you place a child, the child remains invisible until the composite container window is placed. When you place a composite window (by placing its container), only child windows and lists that have already been placed will appear on the window. Note that a container and its child windows and lists don’t have to be logged in the same environment. When a container is placed, placed windows and lists will be displayed, even if they are logged in different environments.

To instruct Toolkit to remove a child from the screen, use the D_REMOVE operation for U_WINDOW or use L_REMOVE. Note the following:

To remove a composite window from the screen, pass the composite container window ID to the D_REMOVE operation for U_WINDOW. Removing the composite container window makes all child windows and lists invisible, no matter which environments they are logged in.

To delete a composite window, delete its composite container window. To delete a composite container window or a child, leave the environment in which it was logged or use the D_DELETE operation for U_WINDOW. Note, however, that deleting the container removes all child windows and lists but does not delete them.

Processing composite windows

Once you have created and placed a composite window, you can process it by calling C_PROCESS, which in turn calls methods that process the child windows and lists. Toolkit includes default processing methods, but you can instruct C_PROCESS to call your own custom methods instead. See C_PROCESS and The composite window processing methods.

Controlling tabbing, focus, and input context

When a composite window is being processed, tabbing moves through placed child windows and lists according to the composite window’s tabbing order, which by default is the order they were added to the composite window. Then, after child windows and lists, tabbing moves through any enabled buttons added to the composite container window.

Note

Every child window and list for a composite window has a tabbing index. This number specifies the child’s position in the tabbing order. Tabbing indices are base 1, so the first child for a composite window has a tabbing index of 1. To get the tabbing index of a child, use the DC_CHILDINDEX subfunction for %C_CONTAINER. (Note that buttons on the composite container window also have tabbing indices, which are also base 1.)

You can do the following to control the tabbing order or activate a specific child or button:

Tabbing within child windows and lists

When processing a child window or list with L_INPUT, L_INPFLD, S_SELECT, T_EDIT, T_VIEW, or U_CHR, pressing tab (or otherwise signaling the C_NEXT menu entry) moves focus to the first button for the window. Subsequent tabbing advances through any remaining buttons for the window and then, if the window is on a tab, advances through buttons on the tab set. Finally, tabbing causes the input routine to return with g_select set to true and g_entnam set to “C_NEXT”, which instructs C_PROCESS to move focus to the next child window. shift+tab works the same way, but in reverse. It returns g_select set to true, but it sets g_entnam to “C_PREV” to move to the preceding child.

The above also applies to I_INPUT and I_INPFLD, except that

In any case, users won’t be able to tab out of a window or list if the child processing method changes the value of g_entnamtab or g_entnamstab (defined in tkctl.def), if the ActiveX control for a child ActiveX window processes tab and shift+tab as an accelerator without returning it as a keystroke (see ActiveX controls and tabbing below).

Additionally, Toolkit includes several routines that enable you to control the context of a child window or list. All the following except I_NEXT and L_NEXT determine context based on the reason the child received focus. This enables child processing methods (the default methods and any methods you create) to provide an interface where users can smoothly tab through and click into composite windows.

Note that when processing tab sets, ctrl+tab and ctrl+shift+tab apply to the innermost tab set. For example, if a tab set contains a composite window, and that composite window in turn contains a tab set, these key combinations apply to the inner tab set when the inner tab is being processed. When Toolkit is processing any other window in the composite window on the tab, they apply to the outer tab set. See %TS_TABSET for more information on navigating tab sets.

For Windows, note the following:

ActiveX controls and tabbing

There are a couple of situations in which tabbing may not automatically work seamlessly when a composite window includes an ActiveX control. The mechanisms for working around these issues are illustrated in ActivexChildTabbing.zip, available from Synergy CodeExchange in the Resource Center on the Synergex web site.

Buttons in composite windows

To add buttons to a composite window, you can use B_BUTTON to add buttons to the container, and you can use B_BUTTON or L_BUTTON to add buttons to a child window or list. Note the following:

The default button

The following rules determine which button is the default for a composite window as a whole. Note that for usability and aesthetics, we recommend that you specify only one default button anywhere within a composite window—in other words, only one child window or list should have a default button (unless a default button is set for the composite container window). This prevents Toolkit from switching the default as context changes.

1. If the window being processed specifies a default button, and that button is enabled, that button becomes the default button for the composite window.
2. Otherwise, if the container for the active window specifies an enabled default button, that button becomes the default. If the container doesn’t specify an enabled default button, but is itself contained, the default button for its container shall be the default, and so forth.
3. If no default button can be determined by the above, the default for another descendant window of a common container may become the default for the composite window. This, of course, will only come into play if there are several layers of containment (composite windows within composite windows). In this case, Toolkit starts with the innermost child and, if it is unable to establish a default from that, moves to its container, its container’s container, and so forth.
4. If none of the above results in a default (i.e., if no default button is specified on any window with a common ancestor), the first button for the composite window becomes the default. The first button is determined according to the same hierarchy discussed in the previous rules. If the active window has a button, the first button on that window will be the default. If the active window doesn’t have a button, the first button on the active window’s container will be the default. If the parent has no button, the first button on the grandparent becomes the default, and so on. If none of these have buttons, the first button on a window that shares a common ancestor to the current window will be the default.

See the BUTTON_SET Discussion for more information on default buttons.

alt+key button activation

The following rules determine which button, if any, will be activated by an alt+key combination.

Tip

For usability and aesthetics, we recommend that only one button for each alt+key combination be specified anywhere within a container. This prevents Toolkit from switching key associations as context changes.

1. If the window being processed contains an enabled button that specifies the entered key combination, Toolkit activates that button.
2. Otherwise, if the container for the active window has an enabled button that specifies the entered combination, Toolkit activates that button. If the container doesn’t have an enabled button for the key combination, but is itself contained, Toolkit uses the enabled button for the key combination on the container’s container, and so forth.
3. If no button is activated as a result of the above, Toolkit may activate a button that specifies the key combination in another descendant window of a common container. In this case, Toolkit starts with the innermost child and, if no button specifies the key combination in that window, moves to its container, its container’s container, and so forth.

Positioning composite windows, child windows, and lists

To position a composite window (as a whole), position the composite container window by using one of the following:

To control the placement of a child window or list, use one of the following. In all cases, settings are relative to the client area of the immediate parent.

Getting composite window information

The %C_CONTAINER function includes several subfunctions that enable you to get child and composite container window information. With %C_CONTAINER you can

Additionally, you can

Event methods

When a window or list is added to a composite window (even if it’s part of tab set), its %UWNDEVENTS_METHOD set is replaced by one that handles mouse clicks in composite windows. The previously registered method set, however, is registered as a set of extensions to the new method set if there is a difference between the two. You can use the DC_EVENT subfunction for %C_CONTAINER to replace these extensions. (See the DC_EVENT Discussion for information on the default behavior and how to replace it.)

To determine if a method set has been registered for a UI Toolkit window and, if it has, what the ID for the method is, use the D_GETEVENTS subfunction for %U_WNDEVENTS.

To retrieve the address of a method routine for the specified event in the specified method set, use the DC_GETEVENT subfunction for %U_WNDEVENTS.

When a child is removed from its container, the %UWNDEVENTS_METHOD set for the child will remain as it was before the DC_REMOVE call, but the click event will no longer alter the container’s context.