Getting Started With Embedded Windows and WinKit LE

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 59

Getting started with Embedded

Windows:
An introduction into WinKit.LE

Date:
Release:

June 4, 2011
1.0.17561

Experts in OpenEdge and .NET!


1

Copyright (C) 2006-2010 by Consultingwerk Ltd. ("CW") www.consultingwerk.de and other


contributors as below. All Rights Reserved. Software and documentation is distributed on an "AS IS",
WITHOUT WARRANTY OF ANY KIND, either express or implied.
Contributors:
Brynjar Hasle, www.chemistry.no
For the ResizeLib that we have successfully used in some of our projects.

Contents

Contents .................................................................................................................................................. 3
Introduction .............................................................................................................................................. 4
Progress.Windows.MDIChildForm ...................................................................................................... 4
Progress.Windows.WindowContainer ................................................................................................. 4
Running .NET Forms from ABL menus (Lab 1) ...................................................................................... 5
Getting started with Embedded Windows ............................................................................................... 9
Run an ABL window from a .NET Form (Lab 2.1) ............................................................................... 9
Embedding ABL windows using the Progress.Windows.MDIChildForm (Lab 2.2) ........................... 11
Run a .NET Dialog from an ABL window (Lab 2.3) ........................................................................... 14
Troubleshooting ................................................................................................................................. 17
Getting started with WinKit.LE ............................................................................................................... 18
Embedding of an ABL window using the WinKit (Lab 3) ................................................................... 18
Add an icon to the Form (Lab 4) ........................................................................................................ 24
Rendering of Toolbars (Lab 5) .......................................................................................................... 25
Refreshing Toolbars (Lab 6) .............................................................................................................. 28
Color customization (Lab 7)............................................................................................................... 29
Rendering of Browsers (Lab 8) ......................................................................................................... 31
Feature comparison table of WinKit and WinKitLE ............................................................................... 35
GUI for .NET adoption and migration strategies ................................................................................... 36
The OpenEdge GUI for .NET ............................................................................................................ 36
Adoption Challenges ......................................................................................................................... 36
Parallel use of ABL GUI and GUI for .NET ........................................................................................ 37
Embedding ABL Windows into .NET (and vice versa) ...................................................................... 40
Understanding Embedded Windows ................................................................................................. 48
Real world example I: Update Texware / Germany .......................................................................... 50
Real world example II: Shuttleworth Business System / UK ............................................................. 56
Conclusion ......................................................................................................................................... 59

Introduction
With OpenEdge 10.2A the GUI for .NET was introduced to the OpenEdge GUI clients. That includes
two controls (Progress.Windows.MDIChildForm and Progress.Windows.WindowContainer) that have
been provided to enable embedding of ABL windows into .NET Forms. The exact description of those
controls is added at the end of the Introduction.
Note that when you embed an ABL window in a .NET form only the client area of the window is
embedded. ABL ignores all other components of the ABL window, including border controls, menu
bar, message area and status area. For more informationsee the reference entries in the Progress
ABL Reference for the Progress.Windows.MDIChildForm class and
Progress.Windows.WindowContainer class.
In the labs contained in this document we will use both controls (direct or indirect) showing you how
easy embedding of ABL windows can be.

Progress.Windows.MDIChildForm
A .NET form designed for use as an MDIChildForm that allows you to embed the client area of an ABL
window for display in the client area of the form. This allows the widgets in the ABL client area to be
displayed in the .NET MDIChildForm, but also allows you to interact with these widgets as if they were
still displayed in the original ABL window.

Progress.Windows.WindowContainer
A control container that allows you to embed the client area of an ABL window for display in a .NET
Form. When added to a .NET Form, this container allows the embedded ABL client area to appear as
though it is added directly to the client area of the .NET Form. This allows the widgets in the ABL client
area to be displayed in the .NET Form, but also allows you to interact with these widgets as if they
were still displayed in the original ABL window.

Running .NET Forms from ABL menus (Lab 1)

In this section you will see that it is possible to keep an existing ABL menu when using the WinKit. The
Menu window will stay unchanged except of some changes needed in order to be able to show .NET
Forms. Having those changes applied to the ABL window, the full functionality of the WinKit will be
usable and thus an ABL window can be displayed embedded in a .NET Form.
To recognize the changes when running the application after activating the usage of the WinKit you
should now run the unchanged menu window (src/labs/abl-menu/menu.w) using the run
configuration start.
At first a Login Dialog appears where a random User Name can be entered and hit OK.

Next the ABL Menu window is shown. Please choose the menu Entry Programm -> Order.

The result will be an ABL window for Order.

Now we change the code following steps 1 to 3 to enable the usage of the WinKit.
1. The first step to reach the goal is to replace the WAIT-FOR statement with a .NET enabled version
(WAIT-FOR System.Windows.Forms.Application:RUN ()). This is required to enable the Progress
client to handle user interface events of both ABL widgets and .NET Controls.
In the following code block you can see what has changed in the MAIN-BLOCK.
MAIN-BLOCK:
DO ON ERROR
UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
RUN enable_UI.
IF NOT THIS-PROCEDURE:PERSISTENT THEN
WAIT-FOR System.Windows.Forms.Application:Run () .
/*
WAIT-FOR CLOSE OF THIS-PROCEDURE.*/
END.
Note that there is no main form passed to the Run () method. In this case the application main
event handling loop would not be terminated be any event (when a Form reference would be
passed as a parameter the event handling loop would terminate when the user closes the
Form).Therefore we need to call the Exit () method to end the session.
2. Like mentioned before we need to call the Exit () method of the
System.Windows.Forms.Application static class to end the client session.
ON CLOSE OF THIS-PROCEDURE DO:
RUN disable_UI.
System.Windows.Forms.Application:Exit () .
END.

3. To activate the usage of WinKit functionality in the session the static property WinKitActive of the
class Consultingwerk.WindowIntegrationKit.WinKitSettings has to be set to TRUE. This property is
the runtime check whether the WinKit functionality shall be activated. Add the following lines of
code just before the MAIN-BLOCK begins.
/* Mike Fechner, Consultingwerk Ltd. 16.11.2010
Flag that we want to use the WinKit */
Consultingwerk.WindowIntegrationKit.WinKitSettings:WinKitActive = TRUE .

After changing the code like this run the ABL window src/labs/abl-menu/menu.w again. Use the run
configuration start and open the Order window to see the results of your changes.
The Login Dialog and the ABL Menu window havent changed at all.

But when running the Order window it gets embedded into a .NET Form with an UltraToolbar on top
and the Browsers are overlaid by RenderedBrowseControls (UltraGrid). We havent changed the code
of the Order window. But the code to embed the window using the WinKit had previously been
implemented. You see that the same .w file can be used with and without the WinKit.

Getting started with Embedded Windows


Run an ABL window from a .NET Form (Lab 2.1)

To get started, we want to demonstrate that ABL windows and .NET Forms can be used side by side
in a single Application.

1. Having a look at the source code of the SampleMDIContainer.cls you will see that starting an
ABL window has not changed in any way. The code is located in the LaunchWindow Method
which is invoked by the ToolClick Eventhandler method of the UltraExplorerBar.
/* Mike Fechner, Consultingwerk Ltd. 08.11.2010
Embedded Window Workshop */
WHEN "custenq-lab" THEN
RUN src/labs/simple-embedded/w-customer.w PERSISTENT.
WHEN "custenq-embedded" THEN
RUN src/solution/simple-embedded/w-customer.w PERSISTENT.
It is recommended to use the PERSISTENT option for running the ABL windows to avoid
running multiple WAIT-FOR statements at a time (one world, one wait-for).
When a WAIT-FOR statement is required during the execution of a window then we do
recommend to use an ABL dialog Form instead of an MDIChildForm (or an ABL Window
embedded in a .NET Dialog).
2. The ABL window is started by the statement:
RUN src/labs/simple-embedded/w-customer.w PERSISTENT.
3. Start the SampleMDIContainer
(Consultingwerk/WindowIntegrationKit/Samples/SmapleMDIContainer.cls) by using launch
configuration Sample .NET MDI Container (WinKit.LE)

The sample Application will start and you will see an OutlookBar on the left side. Please open
the Simple embedding group (highlighted at the left bottom).

4. Now launch the Simple Customer Enquiry by clicking the Customer Enquiry (Lab) Icon.

As you can see it is possible running an ABL window from a .NET Form. Instantiating a .NET
Form and run it from an ABL window is also possible.
10

Embedding ABL windows using the Progress.Windows.MDIChildForm (Lab 2.2)


The goal of this section is to visualize the Customer Enquiry ABL window as an MDI child inside of
the SampleMDIContainer Form as you can see in the screenshot below.

1. To be able to embed an ABL window into a .NET container like the


Progress.Windows.MDIChildForm or the Progress.Windows.WindowContainer, the ABL
window has to be created but must not yet be realized.
In AppBuilder created windows this condition is typically only met in the method library include
file.
For this approach we will implement an include file named makeEmbedded.i. This file is then
used as a method library inside of the ABL window code. Follow the steps needed for
embedding:
a. First create a new ABL include file:
src/labs/simple-embedded/makeEmbedded.i
Now the code explained in the steps b to g should get added to the now existing file
src/labs/simple-embedded/makeEmbedded.i.
b. The next step is to create the .NET Container where the ABL window runs in. An
instance of the Progress.Windows.MDIChildForm gets created and as the parameters
the MDIParent and the HANDLE of the ABL window gets passed to the
CONSTRUCTOR. When using the WinKit the MDIParent is stored in
Consultingwerk.Framework.FrameworkSettings:MdiContainer.
11

DEFINE
AS
DEFINE
AS

VARIABLE oMdiChild
Progress.Windows.MDIChildForm NO-UNDO.
VARIABLE oMdiParent
Progress.Windows.Form
NO-UNDO.

/* Marko Rterbories, Consultingwerk Ltd. 10.11.2010


Get the MdiContainer from the FrameworkSettings */
ASSIGN oMdiParent = CAST
(Consultingwerk.Framework.FrameworkSettings:MdiContainer,
Progress.Windows.Form).
oMdiChild = NEW Progress.Windows.MDIChildForm
(oMdiParent,
{&WINDOW-NAME}:HANDLE).
c.

Assign the title of the .NET Form by setting the property to the ABL window title:
oMdiChild:Text = {&WINDOW-NAME}:TITLE.

d. Load an image displayed as the .NET Form icon


/* Marko Rterbories, Consultingwerk Ltd. 10.11.2010
Load an Icon for the Form */
FILE-INFO:FILE-NAME = "src/images/progress.ico":U.
IF FILE-INFO:FULL-PATHNAME NE ? THEN
oMdiChild:Icon = NEW System.Drawing.Icon
(FILE-INFO:FULL-PATHNAME).
e. Implement an internal procedure as the EventHandler for the FormClosing Event.
PROCEDURE FormClosingHandler:
/*--------------------------------------------------------Purpose: Eventhandler for the FormClosing Event of the
MdiChildForm. This procedure ensures that the
ABL window gets closed whenever the containing
Form gets closed.
Notes:
---------------------------------------------------------*/
DEFINE INPUT PARAMETER sender
AS System.Object
NO-UNDO.
DEFINE INPUT PARAMETER e
AS System.Windows.Forms.FormClosingEventArgs NO-UNDO.
APPLY "WINDOW-CLOSE":U TO THIS-PROCEDURE.
END PROCEDURE.
f.

Subscribe the FormClosing Event for closing the ABL window if the .NET Form gets
closed.
/* Marko Rterbories, Consultingwerk Ltd. 10.11.2010
Subscribe the FormClosing Event to ensure that the ABL
Window gets closed if the .NET Form gets closed */
oMdiChild:FormClosing:Subscribe ("FormClosingHandler").

g. Make the .NET Form visible


oMdiChild:Show ().
2. The only way to embed an ABL window after it has been completely created but before it gets
realized is to add the code needed as a Method Library to the ABL window. In our example we
12

now add the previously created include file to the w-customer.w using the Progress
AppBuilder.
a. Open the file src/labs/simple-embedded/w-customer.w in the AppBuilder and then
open the Procedure Settings of the window.

b. Open the Method Libraries dialog.

c.

Add the include file makeEmbedded.i which we created before. Click the Add
button.

13

d. Type in the path and filename src/labs/simple-embedded/makeEmbedded.i or select


the file from the file system.

e. Click the OK button to close all dialogs.

Now we can again launch the SampleMDIContainer and run the Customer Enquiry (Lab) which will
now be displayed embedded like shown at the beginning of this section.

Run a .NET Dialog from an ABL window (Lab 2.3)

14

At the moment the default action (double click) of the customer browser opens an ABL dialog
Customer Detail showing detailed information of the selected customer.

As an example of how to mix and match .NET Forms and ABL windows, we have reimplemented the
dialog above a .NET Form using Infragistics Controls like shown below.

15

In order to display the .NET Form with Customer Details instead of the ABL window we need to
change the trigger code for the DEFAULT-ACTION of BROWSE-3. First we make sure that a valid
Customer is available in the default buffer of the Customer Table (data source of the browser). If that
is true an instance of the .NET Form will be created and as the parameter the current buffer handle is
passed to the form which is then used to bind to the .NET Controls to the buffer.

Change the trigger code in w-customer.w as follows:


ON DEFAULT-ACTION OF BROWSE-3 IN FRAME DEFAULT-FRAME
DO:
DEFINE VARIABLE oDetailForm
AS src.solution.simple-embedded.CustomerDetailForm NO-UNDO.

IF AVAILABLE Customer THEN DO:


16

oDetailForm = NEW src.solution.simple-embedded.CustomerDetailForm


(BUFFER Customer:HANDLE).

WAIT-FOR oDetailForm:ShowDialog ().


END.

FINALLY:
IF VALID-OBJECT (oDetailForm) THEN DO:
oDetailForm:Dispose ().
DELETE OBJECT oDetailForm.
END.
END FINALLY.
END.

This example displays the .NET Form as a dialog like the original ABL dialog, which is achieved using
the WAIT-FOR statement (WAIT-FOR oDetailForm:ShowDialog ()). The current buffer gets
passed to the form as the parameter of the CONSTRUCTOR when creating a new instance of the
form. It would although be possible to display the .NET Form in non modal mode by using the Show
method. In that case no additional WAIT-FOR statement would be necessary but we would have to
implement a refresh method to follow the current row of the browser (using the Refresh() method of
the Progress.Data.BindingSource class).

Troubleshooting

As described in the error message the embedding of the ABL window into the .NET
Progress.Windows.WindowContainer or Progress.Windows.MDIChildWindow is not possible because
the ABL window has already been realized. This is typically the case when executing the LOAD-ICON
method or accessing properties like VISIBLE or HIDDEN had been accessed before assigning the
handle of the ABL window widget to the EmbeddedWindow property of the .NET Control.

17

Getting started with WinKit.LE


Embedding of an ABL window using the WinKit (Lab 3)
The process of embedding ABL windows into .NET Forms using the WinKit is always done by adding
three steps include files to central locations during the initialization of the ABL program. In this section
we will take a deep look into what is done in those files and how and where they have to be added to
the existing code. Those files are located in the folder src/winkit and the names are embedwindow.i,
embedfinalize.i and closewindow.i.
The prepared code of the ABL windows orderwin.w and ordersearchdlg.w are located at
src/labs/ordermaint/....

1. The embedwindow include file sets the beginning of everything when using the WinKit with an
existing ABL window. In this step you will learn what happens when you add the include file to
the code of an existing ABL window.
Lets start by adding the include file src/winkit/embedwindow.i to the code of
src/labs/ordermaint/orderwin.w as a Method Library. This is intended to be done by using the
AppBuilder.
Open the dialog for Procedure Settings.

Open the Method Libraries dialog

18

Click the Add button and type in or select the file src/winkit/embedwindow.i

Hit OK and close the dialogs when done.

In the source code of the ABL program that results in the following code that has been added
shortly after the CREATE WINDOW statement.
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _CUSTOM _INCLUDED-LIB C-Win
/* ******************* Included-Libraries ***************** */
{src/winkit/embedwindow.i}
/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
19

The full version of the WinKit comes with the WinKit migration utility which supports
developers inserting this and other required or used include files into the existing code of the
ABL window.
At the very beginning of the include file the check of the preprocessor directive PROVERSION
is done to ensure that the WinKit code will only run if minimum OpenEdge Version 10.2A and
actually as the maximum Version 4x.y is used. This is the compile time check for compatibility
of the code with older Progress or OpenEdge Versions (V8, V9, V10.0, V10.1). Due to this all
source code can still be compiled with Progress and OpenEdge Versions released before
Version 10.2A. If the minimum requirement is reached the preprocessor variable
{&winkitactive} gets defined and is then used as a shortened version of this test.
The next step is to define two variables that will point to the same object instance at runtime
(the .NET Form that is used to embed the ABL window). Those variables are required to lift
the requirement for too frequent CAST. oForm is defined from the main WinKit Interface type
IEmbeddedWindowForm and oFormControl is defined as the standard .NET Form type
System.Windows.Forms.Form and can be used to access Form related functionality like the
window title bar, the Icon property or bringing the Form in front of other Forms (Activate).
DEFINE VARIABLE oForm AS
Consultingwerk.WindowIntegrationKit.Forms.IEmbeddedWindowForm NOUNDO.
DEFINE VARIABLE oFormControl AS System.Windows.Forms.Form NO-UNDO.
When implementing a Container for embedding the ABL windows (in this example the
Consultingwerk/WindowIntegrationKit/Samples/SampleMDIContainer) we have to set the
static property Consultingwerk.WindowIntegrationKit.WinKitSettings:WinKitActive to true. That
indicates for the whole session that ABL windows should be embedded into .NET Forms. The
Property may get set in the CONSTRUCTOR like you can see in the SmapleMDIContainer
class. This switch is used as a runtime check and can in a real world scenario be set
according to user preferences, user settings or a Licensed module (customer to pay extra for
.NET functionality).
Consultingwerk.WindowIntegrationKit.WinKitSettings:WinKitActive =
TRUE.
The new instance of the container for the ABL window gets instantiated in the PROCEDURE
file embedwindow.p which is invoked from embedwindow.i. The ability to pass a class name of
a Container Form where it is possible to implement a special or even more complex design is
implemented. The custom FormType gets defined by setting the preprocessor variable
&WinKitFormType to the character value of the desired FormType with full Namespace and is
passed to the PROCEDURE embedwindow.p as the input parameter pcFormType. The new
instance of the Container Form is then created using the DYNAMIC-NEW statement.
Otherwise if the parameter pcFormType is left blank, a new instance of the default class
(Consultingwerk.WindowIntegrationKit.EmbeddedWindowForm) gets created.
Due to the preprocessor switch {&winkitactive} users of Progress/OpenEdge versions prior to
OpenEdge 10.2A will not be affected by any changes to the code (any attempt to compile
code accessing ABL or .NET classes on Progress Version 9 and early versions of OpenEdge
will fail). For all other users who have entirely switched to versions of OpenEdge that can
compile code accessing .NET functionality this switch is not important.

20

We do consider the file embedwindow.i seen as part of the actual customer project (not
necessary a part of the WinKit standard code) and therefore we would make modifications
directly in this file. In example you might want to limit the usage of the new UI only for a list of
users or a group which might depending on your framework architecture be realized in this
include file.
At this point now the ABL window can be launched and a .NET Form which is used as the
container of the ABL window will be created but the Form wont be visualized because the
Show () method will not yet get invoked.
2. All base functionality like rendering Toolbars and displaying the Container form as a MDIChild
or a dialog is implemented in the include file src/winkit/embedfinalize.i.
This is the second include file which we will add to the code of our ABL window. The include
embedfinalize.i has to be added to the end of the MAIN-BLOCK just before the WAIT-FOR
statement, which in our case wont be executed because the PROCEDURE is started with the
PERSISTENT option.
/* Now enable the interface and wait for the exit condition. */
/* (NOTE: handle ERROR and END-KEY so cleanup code will
*/
/* always fire.)
*/
MAIN-BLOCK:
DO ON ERROR
UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK
ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK:
RUN enable_UI.
RUN
RUN
RUN
RUN

GET-FIRST .
disableFields.
toggleView.
sensitizeButtons.

/* This is the very last statement before the window


is ready for the end user - this is typically
before the non-executed WAIT-FOR statement*/
{src/winkit/embedfinalize.i}
IF NOT THIS-PROCEDURE:PERSISTENT THEN
WAIT-FOR CLOSE OF THIS-PROCEDURE.
END.
/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
For ABL windows created using the normal AppBuilder template this position is usually
correct, but when using other templates like from the ADM1 or ADM2 the place to add the
include file may be different (i.e. inside the ADM include files like src/adm/windowmn.i).
Like the file src/winkit/embedwindow.i, the file src/winkit/embedfinalize.i is considered a part of
the actual project implementation and may differ from the shipped WinKit standard. We
typically make changes and add extensions to these files directly in the src/winkit folder.

21

Important advices:
a. The construction of the ABL menu-bar has to be done before the code in
src/winkit/embedfinalize.i gets executed. Because of the fact that the include file
should be added just before the WAIT-FOR statement in the MAIN-BLOCK, all user
interface widgets should already exist and be ready to be used at this point as
originally at this point the window was ready for the user.
Dynamically created menus have to get assigned to the oForm:MENU-BAR property
before the code in src/winkit/embedfinalize.i gets executed.
b. The ABL window may be displayed as a MDIChild or a Dialog. The decision can be
made per window by setting the oForm:MakeMdiChild property.
c.

There are two callbacks (optional internal procedures finalizeEmbedding and


finalizeEmbeddingEnd) that can be used in the ABL window code to customize
rendering of the window or to implement specials. If those internal procedures do not
exist they are simply not executed.
If you want to change the default behavior of the WinKit we suggest to implement
changes directly in the include file src/winkit/embedfinalize.i. Use the above named
internal procedures when you want to make adjustments on a window by window
basis.

3. A third include file is required to cleanup the .NET Form while the ABL window is getting
closed. Add the include src/winkit/closewindow.i at the end of the ON CLOSE OF THIS
PROCEDURE trigger which acts as a pseudo destructor for ABL procedures like shown in the
following lines of code.
/* The CLOSE event can be used from inside or outside */
/* the procedure to terminate it.
*/
ON CLOSE OF THIS-PROCEDURE DO:
{src/winkit/closewindow.i}
RUN disable_UI.
END.

To show what happens in case the user closes the Form which is the container of an ABL window
embedded using the WinKit, take a look at the next image.
1. The actor tries to close the Form. The FormClosing Event gets fired.
2. The FormClosingHandler of the
Consultingwerk.WindowIntegrationKit.Forms.EmbeddedWindowForm gets invoked by the
FormClosing Event
a. The property Canceled of the System.Windows.Forms.FormClosingEventArgs class
gets set to TRUE (e:Canceled = TRUE)
b. APPLY WINDOW-CLOSE TO EmbeddedWindow
3. WINDOW-CLOSE TRIGGER controls whether the ABL window may get closed or not
a. If not OK - RETURN NO-APPLY
b. If OK - APPLY CLOSE TO THIS-PROCEDURE
4. CLOSE TRIGGER runs thru the code of the include file closewindow.i which closes and
destroys the .NET Form and runs the disable_ui PROCEDURE of the ABL window.
22

act FormClosing

EmbeddedWindow Form :FormClosingHandler


(.NET Form::FormClosingHandler)

FormClosing Ev ent is fired before the


Form is closed. At first the closing of
the Form gets canceled (e:Canceled =
TRUE).

Close of ContainerForm
flow

User

APPLY WINDOW-CLOSE TO EmbeddedWindow


flow

WINDOW-CLOSE TRIGGER
ABL w indow

RETURN NO-APPLY
flow

OK to close ABL window

APPLY CLOSE TO THIS-PROCEDURE


flow

CLOSE TRIGGER
closew indow .i
The .NET Form gets closed in this include file.
RUN disable_ui
Run clean-up code of the ABL w indow

At this point the standard procedure of embedding an ABL window into a .NET Form by using the
WinKit functionality is completed. Lets start the SampleMDIContainer and have a look at what we
changed at all.

23

From now on there are many opportunities to extend user experience and to add functionality using
.NET Controls. Follow the next steps to get started with that.

Add an icon to the Form (Lab 4)


Important: The ABL window which shall be embedded may not have an icon. The LOAD-ICON
statement would cause the window to be realized before it would get embedded. Therefore you have
to remove icons from the existing ABL windows using the AppBuilder for instance (customers of the
WinKit can remove the icons form the windows using the WinKit migration utility).
Now we add an icon to the Form which acts as the container for the ABL window by using the callback
procedure finalizeEmbedding which we have to create for this purpose.
Add the following code to the code of the orderwin.w.
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE finalizeEmbedding C-Win
PROCEDURE finalizeEmbedding :
/*------------------------------------------------------------------Purpose:
Notes:
-------------------------------------------------------------------*/
/* Mike Fechner, Consultingwerk Ltd. 11.11.2010
Load an Icon for the .NET Form */
FILE-INFO:FILE-NAME = "images\window2.ico" .
IF FILE-INFO:FULL-PATHNAME > "" THEN
oFormControl:ICON = NEW System.Drawing.Icon
(FILE-INFO:FULL-PATHNAME) .
24

END PROCEDURE.
/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME
Start the SampleMDIContainer and the Labs App. As you will see the code in the finalizeEmbedding
internal procedure gets automatically executed and the icon gets loaded (shown on the MDI tab).

Rendering of Toolbars (Lab 5)


Inside of the Consultingwerk.Util Namespace a class named UltraToolbarsHelper exists, which is used
to create a Toolbar from existing Tools (Button widgets).

25

In this lab we will use the BuildToolbarFromFrame (phFrame, phWindow, pdeLinitRow,


poToolbarsManager) method like shown below. The parameters passed to the method are:

1. phFrame AS widget-handle (FRAME {&frame-name}:HANDLE)


Reference of the frame which gets analyzed to build the Toolbar
2. phWindow AS widget-handle ({&window-name}:HANDLE)
Handle of the ABL window
3. pdeLimitRow AS decimal
Number of rows where button tools are expected and should get added to a Toolbar
4. poToolbarsManager AS Infragistics.Win.UltraWinToolbars.UltraToolbarsManager
Reference to the instance of the Infragistics Toolbar where the Tools get created in

/* Mike Fechner, Consultingwerk Ltd. 11.11.2010


Render all Buttons in the default frame as Infragistics
Toolbar Buttons.
The Window-Handle is use for a Toolbar caption attribute.
Only Buttons of the ABL frame with ROW <= 1.5 will be rendered. */
Consultingwerk.Util.UltraToolbarsHelper:BuildToolbarFromFrame
(FRAME {&frame-name}:HANDLE,
{&window-name}:HANDLE,
1.5,
oForm:ToolbarsManager).
When you start the program now you will see that the Button widgets found in the first 1.5 rows of the
default frame have been rendered to .NET ButtonTool objects in the Infragistics Toolbar.

26

To fade out the buttons of the ABL window we do set the property oForm:WindowContainerRowOffset
to the value of 27 inside the finalizeEmbedding internal procedure. Add the following line of code to
the procedure and rerun the window.

/* Mike Fechner, Consultingwerk Ltd. 11.11.2010


Move the WindowContainer (Progress .NET Control that parents
the ABL Window to negative dimensions to hide the ABL Toolbar
Buttons) */
oForm:WindowContainerRowOffset = 27 .
The Offset of 27 pixels is a well known value which is the default button height in the ABL. You might
also need to set the property oForm:WindowContainerColOffset in order to fade out left aligned
buttons which get rendered into the Toolbar.
When setting for WindowContainerRowOffset or WindowContainerColOffset properties the
WindowContainer hosting the ABL window will be set a little bit higher than the visible area of the
.NET Forms client area. This is the safest way to remove the ABL Button widgets at the borders of the
embedded ABL window.
Experiences from customer projects:

1. Moving all Widgets up by 30 pixels takes longer and has an impact on the geometry of the
window. So it may interfere with existing framework resizing code (possible references on
Buttons for alignment of other widgets)
2. Hiding of the buttons may have an impact on other logic of the application like for instance
checking user rights/abilities where in some applications the state (enabled, disabled) of a

27

button was used to check rights for the user.

Refreshing Toolbars (Lab 6)


When during the execution of the ABL Window the original Toolbar buttons or menu items change
their state (enable/disable), label-text or image changes the rendered .NET Controls need to reflect
this change. This task can be solved with ease when there is a central point (structured approach) in
the code where this can be implemented but often changes are applied in many places inside the
code (chaotic approach to menu and toolbar management). There are three different possibilities
where code that manipulates the button state may be implemented.

1. Central procedure or Toolbar Object (similar to ADM1 or ADM2 Toolbar)


The entire refreshing is done in one place and with only one statement the synchronization
with the forms Toolbar can be done.
2. Event-Handler
If button state manipulation is only done in Event-Handlers (Trigger code) contained in the
ABL program we only need to add a line of code at the end of each (relevant) Trigger.
3. Internal procedures
In cases where the modification of the state of rendered buttons or menu items is executed
form other (persistent procedures) by invoking internal procedures of the current .w file the
synchronisition to the Forms Toolbar has to take place at the end of those internal procedures.
That is what we call the chaotic approach.

Inside of the ToolbarsHelper a method called RefreshTools () is implemented which can update the
state of each Tool mapped to one of the ABL window buttons. In the lab source code a central
procedure (sensitizeButtons) handels the update of button states. Add the following line to the end of
the procedure.
FINALLY:
Consultingwerk.Util.UltratoolbarsHelper:RefreshTools
(oForm:ToolbarsManager) .
END FINALLY.
Rerun the application and watch what happens with the buttons when you navigate through the orders
or perform updates in the window.

28

The commercial version of the WinKit is shipped with the WinKitMigrationTool which is among other
things able to automatically add an include file to every required trigger, function- and internal
procedure block.

Color customization (Lab 7)


Another improvement in the look of the existing ABL window can be achieved by setting a new color to
the ABL window and frames background. We have defined the color to 33 in the winkit.in file which
matches the Form Background color of Office 2007 Applications.

29

The Consultingwerk.Util.WidgetHelper class contains a method named SetFrameBackgroundColor


with the following parameters:

1. phParent AS widget-handle
The window which is the parent of the frames where to set the background color ({&windowname})
2. piColor AS integer
The number of the color defined in the ini file for the session (color33=227,239,255)
3. piBrowseColor AS integer
The number of the color defined in the ini file for the session (color15=255,255,255)
4. piTextboxColor AS integer
The number of the color defined in the ini file for the session (color15=255,255,255)

This sets the Background color of all frames inside the ABL window but still the window background
stays grey. The background color of the ABL window has to be set by assigning the BGCOLOR
property of the window widget.
Add the following code to the finalizeEmbedding procedure of the ABL window.
/* Mike Fechner, Consultingwerk Ltd. 11.11.2010
Set FRAME BGCOLOR to 33, which matches the Form Background color
of Office 2007 applications, color33=227,239,255 */
Consultingwerk.Util.WidgetHelper:SetFrameBackgroundColor
({&window-name}, 33, 15, 15).
{&window-name}:BGCOLOR = 33.

30

Rendering of Browsers (Lab 8)


The user experience can be greatly enhanced by replacing ABL Browse Widgets with Infragistics
UltraGrid Controls. For this effect we have implemented a Control named RenderedBrowseControl.
This control has to get instantiated by for instance passing the following parameters to the constructor:

1. phBrowse AS widget-handle
Handle of the Browser to be overlayed
2. poEmbeddedWindowForm AS
Consultingwerk.WindowIntegrationKit.Forms.IEmbeddedWindowForm
The Form which is the container of the ABL window
3. poParent AS System.Windows.Forms.Control
.NET Control the will be the Parent of the RenderedBrowseControl (usually oForm:ClientArea)
4. plUseBatching AS logical
Use Batching for the Browse
5. phCallBackProcedure AS widget-handle
procedure-handle of the window for CallBacks

Please note that this should be done after the properties WindowContainerRowOffset and
WindowContainerColOffset have been set because those parameters get considered when positioning
the control on the Form.
If batching is turned off (batching parameter= false), the MAX-DATA-GUESS functionality is not used,
the MAX-DATA-GUESS property is set to 0. If batching is turned on, the value of MAX-DATA-GUESS

31

is set to 100, resulting in the fact that the ProBindingSource will read data from the database in chunks
of 100 records.
Please consult the OpenEdge GUI for .NET documentation for further description of the
ProBindingSource properties.
Advices:
1. The RenderedBrowseControl overlays the ABL browser widget but is not part of the Tab Order
inside the ABL window. That means that focusing and defocusing via tab key has to be
implemented using Event-Handlers when the Tab Order is critical.
2. The RenderedBrowseControl is part of the .NET Form and therefore not associated to an ABL
frame. That means that switching an ABL frame or TabFolder page will not automatically view
or hide the RenderedBrowseControl. This has also to be coded.

In the Definition Section add a reference variable for the .NET Control of type
RenderedBrowseControl.
&IF NOT PROVERSION GE "4" AND PROVERSION GE "10.2A" &THEN
DEFINE VARIABLE oGrid AS
Consultingwerk.WindowIntegrationKit.Controls.RenderedBrowseControl NO-UNDO
.
&ENDIF
The next block of code has to be added to the finalizeEmbedding procedure. This code creates the
instance of the RenderedBrowseControl and places the Control on the Form on top of the browser
which should be replaced.
/* Mike Fechner, Consultingwerk Ltd. 11.11.2010
Overlay the Browse with a .NET Grid Control.
The .NET Grid Control (a custom ABL class will duplicate the
layout) of the browser: geometry, columns, ...
The Grid control will be connected to a ProBindingSource. The
ProBindingSource will be connected to the QUERY which was
intended for the actual browse widget. As the QUERY cannot be
navigated by the browse and a ProBindingSource at the same
time, the browse will be connected (assigned to its QUERY
property) to a QUERY on additional buffers on original
queries tables.
This replacement query will NOT be opened. This is required,
as a browse which is disconnected from a QUERY will not have
columns anymore and that might interfere with existing code. */
oGrid = NEW
Consultingwerk.WindowIntegrationKit.Controls.RenderedBrowseControl
(BROWSE {&browse-name}:HANDLE,
oForm,
oForm:ClientArea,
FALSE,
THIS-PROCEDURE).
To make sure switching the frame hides the RenderedBrowseControl we need to add code for that to
32

the internal toggleView procedure which handles the switching of the frames on the ABL window.
&ANALYZE-SUSPEND _UIB-CODE-BLOCK _PROCEDURE toggleView C-Win
PROCEDURE toggleView :
/*------------------------------------------------------------------Purpose:
Parameters: <none>
Notes:
-------------------------------------------------------------------*/
ASSIGN FRAME {&FRAME-NAME} rs-show .
IF rs-show = 1 THEN DO:
VIEW FRAME frame-a .
HIDE FRAME frame-b .
&IF DEFINED (winkitactive) NE 0 &THEN
IF VALID-OBJECT (oGrid) THEN
oGrid:VISIBLE = TRUE .
&ENDIF
END.
ELSE DO:
HIDE FRAME frame-a .
VIEW FRAME frame-b .
&IF DEFINED (winkitactive) NE 0 &THEN
IF VALID-OBJECT (oGrid) THEN
oGrid:VISIBLE = FALSE .
&ENDIF
END.
END PROCEDURE.
/* _UIB-CODE-BLOCK-END */
&ANALYZE-RESUME

33

34

Feature comparison table of WinKit and WinKitLE


Start out of the MDI Container
Embedding including menu
Toolbar rendering
Toolbar refresh
Browser rendering
Colorcustomization
Toolbar and Ribbon Designer
Date Popups
Button overlaying
Tabfolder / SplitContainer
Consulting and Support
Google Forum
ADM2 Customizations

WinKit
X
X
X
X
(Tool)
X
(Sourcecode)
X
X
X
X
X
X
X
X

WinKit LE
X
X
X
X (manual)
X
(X-Code)
X

Additional information can be found at http://groups.google.com/group/winkitdevelopers.

35

GUI for .NET adoption and migration strategies


The OpenEdge GUI for .NET
The OpenEdge GUI for .NET is an integrated feature since OpenEdge Version 10.2A. The purpose of
this feature is to offer the ability to build state of the art user interfaces for the Windows desktop. The
largest portion of all OpenEdge end users is working on windows desktops and .NET is the de-facto
standard to build up to date user interfaces. The GUI for .NET offers seamless access to this feature
from the ABL and has been designed by Progress Software with a number of migration possibilities.
Some of them have been outlined in my Exchange Online 2010 presentation.
The OpenEdge GUI for .NET is supported by both OpenEdge GUI clients: The fat-client
(prowin32.exe) and the thin WebClient (prowc.exe) allowing automated installation and updates of
OpenEdge applications on the end users desktops.
Both for development and deployment there are no additional license requirements: As soon as you
are on a current OpenEdge Release this feature is available to you and your users.
Although Progress has a preference for Infragistics as a Control vendor (and is offering their award
winning NetAdvantage for .NET Controls) the GUI for .NET is designed to work with any required
.NET Control.

Adoption Challenges
In our Consulting projects we have faced customers with many different and repeating adoption
challenges. Traditionally Progress and OpenEdge customers are used to a very high level of version
compatibility and many Progress partners have been very hesitant to roll out new features especially
those just working under the covers like ProDatasets or the AppServer. With the OpenEdge GUI for
.NET it is obvious that there are reasons for partners to change this strategy but still there may be
end customers that for various reasons (like hardware, operating system or licensing restrictions) do
not want to move away from Progress Version 9.1E (or before).
OpenEdge is typically not used to build small applications and a clean separation between the user
interface and the business logic has been advised since a very long time, but the reality is that it is not
a widely spread design pattern for ABL applications. So it is obvious that any modification on the user
interface may become a huge take for applications with 1000s of screens.
The OpenEdge GUI for .NET comes with quite a load of training requirements: Object-oriented basics
as a new programming paradigm, .NET fundamentals and the OpenEdge Architect are the basics.
Depending on your user interface demands you may have to take a deep dive into a powerful and
complex .NET Control suite like Infragistics. Certainly when the new user interface comes with a
rearchitecture of your application it is worth to give ProDatasets a chance which also may require
some training.
Other challenges come from the design of the user interface as well as the architecture. Which
architecture does an OpenEdge application need today? How much of OERA is good for me?
Progress does not provide a production quality example of an application and the OpenEdge Architect
does not come with an evolution of the ADM2 for GUI for .NET. So probably every team starting with
the GUI for .NET will have to build functional design templates based on examples like AutoEdge or
similar available on PSDN on their own, or look at tools from independent vendors like our
SmartComponent Library which will provide a supported OERA implementation with development tool
enhancements.

36

Last but not least the design of the user interface can be a challenge as well. The possibilities of the
classical ABL GUI have been limited. It took me personally more than one year to get used to the
Ribbon of the Microsoft Office 2007. I know from developers that have had a harder start or didnt
even upgrade to a latest Microsoft Office release because of the new UI style. How can sales reps and
end users expect a productive use of the Infragistics Ribbon or features like Dockable Panes, Explorer
bars, Outlook navigation panes, drag & drop, , when the developer isnt an experienced user with
these UI elements himself?! With a multitude of functionality on the user interface it may even become
easier to build the worlds worst user interface. Designing user interfaces that are increasing the end
users productivity is not necessarily a task for an experience business logic developer.
Finally the user interface is a moving target: When your goal is the Microsoft Office or Windows 7, look
and feel you should be advised that Microsoft is already cooking something new. About a year ago I
was visiting a customer that wanted to add the Ribbon to his existing OpenEdge Application and the
product manager was very proud that he resized and manipulated the company logo so that it fits the
orb the application button of the Ribbon. Until I have presented a screenshot of Office 2010, where
the Ribbon became flat and the orb has become user interface history

Parallel use of ABL GUI and GUI for .NET


The most basic adoption strategy is the parallel usage of the classic and the modern GUI in a single
application. The GUI for .NET is part of normal functionally the two well known OpenEdge GUI clients.
This means there is no extra client for the classical and the modern GUI. The OpenEdge client
supports now (starting OpenEdge 10.2A) ABL widgets and .NET Controls at the same time and in the
same application with almost no restrictions. In the same flexible way procedures and classes (the
preferred way to build GUI for .NET screens) can interact with each other:

Procedures may instantiate and interact with classes


Classes may run procedures and persistent procedures internal procedures
Procedures may create .NET Controls and subscribe to events

If you have built your first .NET Form and want to integrate it to your existing application menu, there
is a single change that you will have to make and that change is related to the event handling. The
Progress client will have to be prepared to properly handle .NET events. Therefore the first (and very
often only) WAIT-FOR statement needs to be initiating a message loop in the .NET framework as well.
In an event driven Progress application this one (and only) WAIT-FOR statement is typically part of the
main menu screen. When the application has been built using AppBuilder templates, this is typically a
WAIT-FOR CLOSE OF THIS-PROCEDURE.
Youll have to replace this with a
WAIT-FOR System.Windows.Forms.Application:Run ().
which will state the message loop in the .NET Framework. Where like in this case there is no
parameter passed to the Run method of the Application object, the message look requires the ExitCall. So youll have to add this at the end of your WINDOW-CLOSE or CLOSE OF THISPROCEDURE trigger in the ABL main menu program:
System.Windows.Forms.Application:Exit ().
Youll notice that this is typically a very simple modification. Youll probably have to enhance your
(dynamic) menu as well as youll have to NEW or DYNAMIC-NEW your first .NET Form because the
RUN statement cant launch a class instance. Certanly doable.

37

The result is the same old menu, all existing windows still running with the addition of your first .NET
Form. See the screenshots in my Exchange Online 2010 presentation for an impression.
At this point it may be wise to consider rewriting your main menu as the .NET first screen youll roll out
to your users. Why? Because the main menu typically does not contain that much business logic that
might be impacted and the effect may be very huge. I assume that the new user interface will also be
for sales enablement. And how are you going to demo your application to a prospect without the main
menu? It is very often the first impression that is important. Also for existing uses this is a screen they
use day in, day out. So a little more flexibility on the UI may have a huge effect to them: Think of a
dashboard, gauges, charts, a message board, treeview menus, drag and drop menu favorites and so
on. For the developer the main menu may be a nice training field for a large number of inviting .NET
Controls.

38

39

Embedding ABL Windows into .NET (and vice versa)


The OpenEdge GUI for .NET has been equipped with the ability to integrate ABL Windows into .NET
Forms. This core feature of OpenEdge 10.2A and 10.2B was originally added to support mixed and
matched MDI scenarios. MDI has been for a long time a requested UI feature for the Progress GUI
and is not finally possible with .NET Controls. With embedded windows the client area of an ABL
window widget will be embedded into a special .NET Container Control developed by Progress
Software.
This functionality is really a killer feature of the GUI for .NET. Besides its original intended use of MDI
enabling the classical Progress GUI it allows radical UI improvements ABL GUI applications by the
integration of .NET Controls around or inside Progress windows. Possibilities include the
replacements of menu-bar widgets and ABL toolbars (collections of button widgets) with modern
Infragisitics toolbars or Ribbons. You may use container layout controls like dockable panes, modern
tab folders, explorer bars etc. with your classic ABL application when you are using this feature with
some creativity. Embedded windows are the gateway to a seamless step-by-step introduction of
additional .NET Controls to increase the look and feel as well as the end users productivity without a
major rewrite of your application. Depending on how youve build your application, most of these
changes can be made in your framework or template files without modifications to every individual
screen. Depending on how you work with browsers it may be very simple to replace all browsers in
your application with Infargistics UltraGrid Controls.
The screenshots used in my presentation are mostly based on our WinKit. The WinKit is our toolkit to
simplify the use of Embedded Windows with existing Progress applications.
The first screenshot shows our sample MDI container with typical .NET Controls: An Infragistics
UltraToolbar in an Office 2007 style, the Outlook nagivation pane in a dockable pane on the left,
40

tabbed MDI manager, a chart control, a gauge and a web browser. On the right there is a calendar
that might be used to visualize reminders for follow-up items.
From this MDI container the user can launch very basic ABL windows. The window contains typical
ABL widgets like a browser, a button and a set of fill-ins. Using our WinKit we just have added three
include files to this .w file to achieve this effect. Please note that the ABL menu-bar widget has been
automatically replaced by bands in the Infragistics UltraToolbar. We do typically also change colors
and sometimes fonts in the ABL windows to match the appearance of the .NET Controls. A white
background in the embedded ABL window makes a huge impression. An alternative background color
might be a light blue like used in Outlook 2007 as a background to contact of appointment form (RGB
227-239-255). We do also care much about resizing. Cause all .NET elements out of the box are able
to resize and an ABL window integrated into this environment would look like a real stranger when it
wouldnt be resizable. We either integrate existing resizing functionality from our clients or work with
the open-source resizing library from Brynjar Hasle available at http://www.chemistry.no/
The next sample screen is a migrated version of a screen using an ADM2 tab folder and toolbar: The
toolbar has been replaced with an Infragistics UltraToolbar and the tab folder with their
UltraDockManager component and two dockable panes. Dockable panes allow the user to be much
more flexible with the screen real-estate than just resizing. The user is in full control about the layout
of the screen the contents in the window may be split into individual tabs or can be dragged out of
the window. An important functionality when your screen has been designed 10 years ago for a hires of 1024*768 and now your users are working on screens of 1920*1200.
The last example shows a Progress browse widget that is overlaid with an Infragistics Grid. The Grid
is stealing the query from the browser and simulating events on the browser. In most ABL
applications the interaction between the browser and the code is actually an interaction between the
query and the browser (OPEN QUERY) or event of the browser (like VALUE-CHANGED or
DEFAULT-ACTION). We can publish these events from the grid and the existing trigger code on the
browse will still execute; even when the browse is no longer attached to a query.
Note that all these demo screens are based on standard components that weve used in a few
customer projects based on the WinKit already.

41

42

43

44

45

46

47

Understanding Embedded Windows


Progress ships two .NET Controls since OpenEdge Version 10.2A to support Embedded Windows.
The Progress.Windows.WindowContainer is a .NET Control that can be used in any .NET design
(static or dynamic) and can host an ABL window widget.
The Progress.Window.MDIChildForm is actually a .NET Form (.NET window) that contains a
WindowContainer Control. The MDIChildForm simplifies embedding an ABL window as a MDI Child in
a .NET Container. At the first sight this sounds like a nice and simple feature. But in real we have
never used the MDIChildForm. We typically build a similar Form ourselves. The advantage then is that
we can add additional components like the UltraToolbarsManager and a tab folder to this Form to
enhance the UI of the Embedded Window. There is no chance to design a MDIChildForm in the Visual
Designer.
Embedding ABL windows does only embed the client area of an ABL window. The concept of the
client area has never really been important for an ABL developer. The client area does not contain any
of the parts of an ABL window widget that are related to the window border. So the ABL menu-bar, the
status bar and the message area will not be embedded into the .NET Form. Im thankful that I dont
have to remove the menu-bar by myself. I wouldnt want to see the old-fashioned gray menu bar in a
.NET Form anyhow and with the WinKit we have developed general purpose APIs that will
dynamically render the menu-bar to .NET Controls. When your application relies on the message area
or makes use of the status bar well have to code a replacement based on .NET Controls as well. But
this is not very common.

48

49

Basically it is very easy to embed an ABL window into a .NET WindowContainer control. You just have
to create an instance of the WindowContainer and assign the handle of the ABL window widget to the
EmbeddedWindow property of the WindowContainer instance:
ASSIGN oContainer = NEW WindowContainer ()
oContainer:EmbeddedWindow = hWindow .
There is one basic restriction when doing so: The Window may not yet be REALIZED (i.e., HIDDEN
and VISIBLE not yet set, no LOAD-ICON) at the time of embedding it in the WindowContainer control.
When using AppBuilder generated code, this is only possible by using the Method-Library and include
files.
The WindowContainer itself is a .NET Control that can also be used in the Visual Designer. The
WindowContainer is resizable and will always apply its size exactly to the Embedded Window.

Real world example I: Update Texware / Germany


Update Texware, a German Progress partner, is building an ERP system for the textile industry. Their
screens are designed in the AppBuilder based on their own framework developed around Progress
Version 7 and 8. Together with the adoption of the new user interface we have changed the
application from a single window interface to a multi window, partial MDI application.
In this process weve had to find a clever solution for their pessimistic locking approach that seemed
like a major blocker when moving away from the single window / modal user interface. We were able
to solve the problems of uncontrollable nested transactions by using an enhanced version of the
Infragistics UltraToolbarsManager. Without changing the actual business and transaction logic the
50

toolbars are now communicating with each other (using strong typed events) so that actually only a
single window can be in an update mode at a time.
For more information on Update Texware, please read the case study:
http://www.consultingwerk.de/update-texware/

51

52

53

54

55

Real world example II: Shuttleworth Business System / UK


Shuttleworth is a Progress Partner from the UK. They are developing and maintaining a huge ERP
system for the printing industry. They have developed their own V8 style framework (ADM1) based
heavily on include files. Theyve had a clear vision of an Outlook look-and-feel for their application:
Browse windows docked in the main window as MDI Children and multiple data windows (detail views)
opened as separate windows and a Ribbon toolbar on top of all of their screens. This clear vision was
a great plus when adopting the new user interface as we could completely focus on the code and not
so much on trying out different options for the look and feel.
Ultimately in 10 days of research and customization of their framework and our WinKit we were able to
complete the first prototype of their new user interface with the majority of changes done in their
existing framework and only very, very few modifications that would require changes to every
individual screen.
Feedback on Embedded Windows:
With the WinKit we do recommend the following practices when making modifications to the source
code of the windows you will be embedding:

Use include files for modifications on the existing .w files: Thats a legitimate vehicle for
modifications to procedural code, consider compile-time checks to achieve backwards
compatibility with users that are not able (or willing) to upgrade to OpenEdge 10.2B.
Render .NET Controls dynamically from existing ABL widgets (start with menu-bar and
toolbar).
56

Identify additional ABL widgets that are widely used and may be easily replaced (or overlaid)
with .NET Controls. Aim for low hanging fruits first, like browsers or tab folders.
Leverage your existing framework structures. Rewrite reusable code first.
Design specialized components or .NET Controls in the Visual Designer. There is no sense in
hurting your fingers writing dynamic .NET code without need. Use the ability to integrate OO
code with procedural code.

We tend to keep most of the control logic in the Embedded Windows and the .w files (or .p files when
the AppBuilder has not been used). In practice this means that the .NET Event-Handlers should
APPLY the matching ABL events to execute their triggers, two examples:

When closing the Embedded Window, the user will actually close the .NET Form, not the ABL
window (because the red X as part of the window border is not embedded and no longer
visible and not accessible). When the existing .w file contains a WINDOW-CLOSE trigger that
might stop the window from closing (because the user is prompted or the window is in a
logical state that disallows this) the FormClosing Event-Handler should APPLY the WINDOWCLOSE event and check if the event has been stopped using RETURN NO-APPLY.
The ToolClick event or the UltraToolbarsManager should apply the CHOOSE event to the
matching ABL widget (button or menu-item). We store the CHARACTER converted handle of
the ABL widget in the Tag property (similar to private data) of the Tool object.

When working with Progress application partners on UI modernization projects based on Embedded
Windows I typically receive the feedback that this technique takes away a huge amount of timepressure from the ISV. Existing users and prospect can see recognizable improvements of the user
interfaces look and feel and productivity with a minimal effort and cost to the development team. This
certainly does also reduce the implementation risk. The business logic remains mostly untouched, so
there is almost no risk that new (or old) bugs are introduced. End users, supporters and developers
require much less training than typically for completely rewritten user interface. A customer of mine
has heard from an end user that when the new release of their software would look like a completely
new application they might as well look for a competitors offering. The need not to train all users for a
new release is seen a major tie-in aspect in a positive way by the end customer.
It is absolutely achievable using preprocessor checks that the same source code remains usable on
any Progress and OpenEdge version prior to OpenEdge 10.2A. Many OpenEdge developers do not
use any SCM tool at all that would allow them to maintain two separate code lines in an effective
manner.
Developers can still use the AppBuilder to maintain the existing screens. In a team of a size of 10
developers it may be enough for a certain transition period that only one or two developers have
in-depths .NET skills. All the others maintain and enhance the existing screens. In the well know
Progress ADE.
The whole process of embedding ABL windows and leveraging all the compatibility features of
OpenEdge 10.2A and 10.2B means that development teams may adopt the new UI at their own pace
and not a pace dictated by a technology.
Enhancing the ABL GUIs appearance
The purpose of embedding ABL windows is to enhance the appearance of existing ABL applications.
With .NET Controls this primarily happens around the ABL windows contents. But you can as well
achieve a lot inside the ABL window widget.
You should never underestimate the power and the effect of new icons. You should get your hands on
a new set of icons before showing the first prototype of an ABL GUI for .NET application to your
manager or customers decision makers or key users. A typical general purpose icon library with
57

10.000s of icons usually costs around 250,- $. Thats worth the demo effect even when you may have
to replace them later because they only have 90% of the domain specific images you need.
Dont even try to use those images that youve captured from the AppBuilder 15 years ago in the
Visual Designer
Try to review colors and fonts of the ABL GUI, try using blue colors, or different shades of yellow and
orange. Try different font faces like Segoe UI and Verdana known from standard applications.
Rumors say that a large part of what sells new Microsoft Office releases is just a fresh look.
New development using GUI for .NET
Most Progress partners tend to use the GUI for .NET to improve the user interface of an existing
Progress or OpenEdge application. After migrating the existing application to the GUI for .NET with the
approaches described earlier or right from the start, there will certainly be the desire to use the GUI for
.NET to build new screens.
It may be that individual screens shall be integrated into the existing application. An commonly seen
example for this strategy could be a scheduler or resource planning interface build on the Infragistics
UltraWinSchedule components giving a true Outlook planning look and feel. Another alternative could
be a flexible enquiry screen leveraging the drill down capabilities of the Infragistics UltraGrid Control.
Ultimatively these first steps with the GUI for .NET may lead to a complete rewrite of the whole client
interface. Typically this new development goes along with a revision of the application architecture.
This may be the stage when the principles of the OpenEdge Reference Architecture (OERA) and new
language elements like the ProDataset become important. Be aware that this is optional but highly
recommended. From a 4GL/ABL point of view there is now need to change the application
architecture. Even with grown client server architectures the new user interface can be used. But as
described in this post http://blog.consultingwerk.de/consultingwerkblog/2010/08/user-interfacechoices-a-demand-for-rich-desktop-applications/ it is a general observation that user interface design
choices made today may last only for a much shorter duration than those decisions made 10 years
ago. So the current shift in the UI technology might and should be a driver for modernizing the
application architecture to be ready for another UI change in the future.
Certainly at the point when starting a complete rewrite of an existing OpenEdge client it is time to dive
deeper into object-oriented design principles. For the GUI for .NET object-orientation is simply the way
to achieve a good reusability of code and components. Developers really need to understand basic
OO concepts like types, classes, interfaces, CAST and so on. For a procedural Progress programmer
that is used to a loosely coupling of procedures at runtime the concept of strong-typing can be a
blessing and a curse at the same time. Certainly it requires some fresh thoughts about ways to
achieve a dynamics program flow or if that dynamic flow is required.
From building the SmartComponent Library we have made the experience that building a UI
framework or at least good reusable GUI components it is required to build much more OO
understanding than just the basic concepts. One point that you may completely miss in the OpenEdge
documentation is how to customize the behavior of your own classes in the Visual Designer. The
place to look for this information is Microsofts MSDN website and Google.
Extending .NET Controls by inheritance is the key to achieve reusable components that can be put
together in the Visual Designer. Key to the success is the extension of some key classes. Weve made
the experience that extending the UltraToolbarsManager, UltraGrid and the basic classes like the
UserControl and the Form are the key to productive application development by developers that then
dont need such a deep understanding of the .NET Controls in their routine work.

58

But weve also learned that there is no use in inheriting from any .NET Control just because you can.
Inheriting from .NET Controls creates so-called hybrid classes. These classes are actually creating
two object instances (one on the .NET side of the fence and one on the ABL side). This is a great
concept but has certainly a performance penalty and should only be used when required. I have never
seen a real use case for extending a .NET Button or a TextBox Control. Ive found it a better way to
add additional standard behavior to these standard controls from their container, typically a
UserControl in our architecture. This will create a much higher independence from the actual .NET
Control used. And you wont be stopped by the limits of using custom classes. When using your own
TextBox it would be a logical consequence to also use your own Grid Coloumn. But the UltraGrid
wont allow you to do so. So you have to customize the behavior on the Grid level.
When starting writing new screens completely based on GUI for .NET you need to understand that
you are actually becoming a .NET UI developer. As such a developer you should get used to new
resources available to you. You will be overwhelmed by the amount of information, references,
forums, blogs and sites with sample code youll find in the internet. Every .NET developer will find his
favorite .NET community sites where he finds help and code samples. My favorites are the
Codeproject site (English) and MyCSharp.de (German), Google and the MSDN and of course
PSDN.
To leverage the information found on this site you should get used to translating C# or VB.NET code
to the ABL. The Progress documentation offers some help in this field and the PSDN Communities
forums are a great place to find support.
For larger teams it may be wise to hire an experienced .NET developer or mentor to the UI. But dont
be surprised that these folks may actually have a hard time to understand the capabilities of the
OpenEdge database and AppServer. The may keep talking about stored procedures on the
AppServer for ever

Conclusion
The OpenEdge GUI for .NET is well integrated in todays ABL and client products. It is fully compatible
to the classic ABL GUI. Even when many features of the .NET UI are very attractive to the developer
and the end user, nobody forces you to rewrite everything at once. Rewrite those parts of the
application first that have a high return on this effort: The main menu which is central part of the
application for end users and probably every demo and those key screens where the capabilities of
the classic ABL GUI are really a limitation. Less frequently used screens your users will need just
every now and then, like the VAT master, might be a good training field because they are simple but
have little outcome in a demo or for existing users.
We have made very good experience with the users acceptance of Embedded Windows. Start with
integrating the existing application into the GUI for .NET is an excellent way to get first experience with
GUI for .NET during development, deployment and what your users really like.
When making major modifications to the user interface, consider adopting a new architecture for your
application (OERA). There tools available to support you during the way. Certainly our WinKit and the
SmartComponent Library are proven to be successful with a growing number of clients already.
Even when your GUI for .NET project will start in distant future, start using OpenEdge Architect and
the object-orientation in the ABL today! That is the best starting point for GUI for .NET as youll reduce
the training requirements then.

59

You might also like