Try OpenEdge Now
skip to main content
GUI for .NET Programming
Using .NET Forms with ABL Windows : Embedding ABL windows in .NET forms : Embedding one or more windows in a .NET form
 

Embedding one or more windows in a .NET form

Progress.Windows.WindowContainer is a control container class designed to embed the client area of one ABL window in any .NET form. You can do this in one of two basic ways:
*You can first embed a window in a WindowContainer, then add the WindowContainer to the control collection of any .NET form.
*You can add a WindowContainer to the control collection of any .NET form, then embed a window in the WindowContainer.
In this way, you can embed the client area of one or more windows in any single .NET form.
Note: If you attempt to add a WindowContainer to a Progress.Windows.MDIChildForm, the behavior of the MDI child form and its controls becomes unpredictable because an MDIChildForm object is designed to embed only the single window for which you create and initialize the form.
The following general steps describe how to use a WindowContainer to embed ABL windows in .NET forms.
To embed one or more ABL windows in any .NET form:
1. Ensure that any window object you want to embed has not been visualized or otherwise realized.
2. Instantiate the .NET form where you want to embed an ABL window. For example:
DEFINE VARIABLE MainForm AS Progress.Windows.Form NO-UNDO.
. . .
MainForm = NEW Progress.Windows.Form( ).
3. Instantiate a Progress.Windows.WindowContainer. For example:
DEFINE VARIABLE WinContainer AS Progress.Windows.WindowContainer
  NO-UNDO.
. . .
WinContainer = NEW Progress.Windows.WindowContainer( ).
4. Set WindowContainer properties to fit the contents of the embedded window in the container (Size) and to position the WindowContainer in the client area of its parent form (Location). (Note that the default Location property setting for a control within a form is Point( 0, 0 ), which you can also use to position the WindowContainer.) Then, set its EmbeddedWindow property to the handle of the window you want to embed (hWin in the following example) and set its Parent property to the object reference of its parent form in order to add the container to the form's control collection. For example:
WinContainer:Location = NEW Point( 10, 10 ).
WinContainer:Size = NEW Size( hWin:WIDTH-PIXELS, hWin:HEIGHT-PIXELS ).
WinContainer:EmbeddedWindow = hWin.
WinContainer:Parent = MainForm.
5. Repeat Step 3 and Step 4 appropriately for each additional ABL window you want to embed in the form.
6. Make both the .NET form and its embedded ABL windows visible and do any other initialization required, then block on the form using an appropriate .NET WAIT-FOR statement. For example:
WinContainer:Show( ).
hWin:VISIBLE = YES.
. . .
WAIT-FOR Application:Run( MainForm ).
Note that when you embed the client area of an ABL window in a form, the ABL window and its widgets do not interact directly with any other .NET controls that may be added to the form. This means, for example, the embedded client area does not participate in the tab order of the form. Thus, there is no way to tab into the embedded client area from another .NET control or another WindowContainer, and there is no way to tab out of the embedded client area into another .NET control or other WindowContainer. All tabbing within an embedded client area stays within the WindowContainer where it is embedded.
The following procedure fragment embeds a single ABL window in a .NET form using a WindowContainer. The bold elements indicate the most critical and recommended code for making this work:
USING System.Windows.Forms.* FROM ASSEMBLY.
USING System.Drawing.* FROM ASSEMBLY.
USING Progress.Windows.* FROM ASSEMBLY.
USING Progress.Util.* FROM ASSEMBLY.

DEFINE VARIABLE hWin AS HANDLE NO-UNDO.
DEFINE VARIABLE MainForm AS Progress.Windows.Form NO-UNDO.
DEFINE VARIABLE WinContainer AS Progress.Windows.WindowContainer NO-UNDO.

/* Create main menu for the form (not shown for brevity). */
DEFINE VARIABLE MainMenu AS System.Windows.Forms.MainMenu NO-UNDO.
. . .

/* Define a frame with a button. */
DEFINE BUTTON b1 LABEL "Button 1" SIZE 18 BY 1.14.
DEFINE FRAME f1 b1 AT ROW 2 COL 22 WITH SIDE-LABELS THREE-D SIZE 60 BY 6.

/* Create the window. It will not be realized at this point. */
CREATE WINDOW hWin ASSIGN WIDTH = 60 HEIGHT = 6.
FRAME f1:PARENT = hWin.

/* A trigger to prove that clicking the button works. */
ON 'CHOOSE':U OF b1
DO:
MESSAGE "Click of Button 1".
RETURN.
END.

/* Create the form. */
MainForm = NEW Progress.Windows.Form( ).
MainForm:Text = "Embedded Window Sample".
MainForm:Menu = MainMenu.
MainForm:ClientSize = NEW Size(hwin:WIDTH-PIXELS, hwin:HEIGHT-PIXELS).
MainForm:FormClosed:Subscribe( "Window_FormClosed" ).
MainForm:Show( ).

/* Create the WindowContainer, embedding the window into it. */
WinContainer = NEW Progress.Windows.WindowContainer( ).
WinContainer:Size = NEW Size( hWin:WIDTH-PIXELS, hWin:HEIGHT-PIXELS ).
WinContainer:EmbeddedWindow = hWin.WinContainer:Parent = MainForm.
WinContainer:Show( ).

/* Now make the window visible.
It will be realized inside the WindowContainer. */
hWin:VISIBLE = YES.
ENABLE ALL WITH FRAME f1.

WAIT-FOR Application:Run(MainForm).

/* Delete the embedded window after the main form closes. */
PROCEDURE Window_FormClosed:

  DEFINE INPUT PARAMETER sender AS System.Object.
  DEFINE INPUT PARAMETER e      AS System.EventArgs.

  DELETE WIDGET hWin.

END PROCEDURE.
Recommended code in this example includes:
*Sizing the client area of the form object (MainForm) and the area of the WindowContainer object (WinContainer) to the client area of the ABL embedded window (hWin)
*Handling the FormClosed event on the main form in order to delete the embedded window when it closes
The WindowContainer, in this case, also relies on the default setting for its Location property.