You are on page 1of 61

Rich Internet Application Tutorial

Rich Internet
Application Tutorial


The information in this manual/document is subject to change without prior notice and does not represent a commitment on the part of
Magic Software Enterprises Ltd.
Magic Software Enterprises Ltd. makes no representations or warranties with respect to the contents hereof and specifically disclaims
any implied warranties of merchantability or fitness for any particular purpose.
The software described in this document is furnished under a license agreement. The software may be used or copied only in
accordance with the terms and conditions of the license agreement. It is against the law to copy the software on any medium except as
specifically allowed in the license agreement.
No part of this manual and/or databases may be reproduced or transmitted in any form or by any means, electronic or mechanical,
including photocopying, recording or information recording and retrieval systems, for any purpose other than the purchasers personal
use, without the prior express written permission of Magic Software Enterprises Ltd.
All references made to third-party trademarks are for informational purposes only regarding compatibility with the products of Magic
Software Enterprises Ltd.
Unless otherwise noted, all names of companies, products, street addresses, and persons contained herein are part of a completely
fictitious scenario or scenarios and are designed solely to document the use of Magic xpa.
Magicis a registered trademark of Magic Software Enterprises Ltd.
Btrieveand Pervasive.SQLare registered trademarks of Pervasive Software, Inc.
IBM, Topview, iSeries, pSeries, xSeries, RISC System/6000, DB2, and WebSphereare trademarks or registered
trademarks of IBM Corporation.
Microsoft, FrontPage, Windows, WindowsNT, and ActiveX are trademarks or registered trademarks of Microsoft Corporation.
Oracleand OC4J are registered trademarks of the Oracle Corporation and/or its affiliates.
Linuxis a registered trademark of Linus Torvalds.
UNIXis a registered trademark of UNIX System Laboratories.
GLOBEtrotterand FLEXlmare registered trademarks of Macrovision Corporation.
Solaris and Sun ONE are trademarks of Sun Microsystems, Inc.
HP-UXis a registered trademark of the Hewlett-Packard Company.
Red Hatis a registered trademark of Red Hat, Inc.
WebLogicis a registered trademark of BEA Systems.
Interstageis a registered trademark of the Fujitsu Software Corporation.
J Boss is a trademark of J Boss Inc.
Systinet is a trademark of Systinet Corporation.
Android is a trademark of Google Inc.
BlackBerryis a registered trademark of Research in Motion Limited.
iPod, iPad, iPhone, iTunes, and Mac are registered trademarks of Apple Inc.
Portions Copyright 2002 J ames W. Newkirk, Michael C. Two, Alexei A. Vorontsov or Copyright 2000-2002 Philip A. Craig
Clip art images copyright by Presentation Task Force, a registered trademark of New Vision Technologies Inc.
This product uses the FreeImage open source image library. See for details.
This product includes software developed by the Apache Software Foundation (
This product includes software developed by Computing Services at Carnegie Mellon University (
Copyright 1989, 1991, 1992, 2001 Carnegie Mellon University. All rights reserved.
This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (
This product includes software that is Copyright 1998, 1999, 2000 of the Thai Open Source Software Center Ltd. and Clark Cooper.
This product includes software that is Copyright 2001-2002 of Networks Associates Technology, Inc All rights reserved.
This product includes software that is Copyright 2001-2002 of Cambridge Broadband Ltd. All rights reserved.
This product includes software that is Copyright 1999-2001 of The OpenLDAP Foundation, Redwood City, California, USA. All Rights

All other product names are trademarks or registered trademarks of their respective holders.

Rich Internet Application Tutorial

Copyright 2013 by Magic Software Enterprises Ltd. All rights reserved.


Chapter 1: Introduction
Ever since the first release of Magic, the Magic toolkit has always been one of the most
productive and robust available. One of the reasons for this is built into the design of the
product, the "Code once, use many ways" paradigm. You can see this in the way Models
work, where you can create one Model and then use it to create many different kinds of data
sources and programs. You can also see it in how data sources work; a data source can be
used the same way by a program whether it is ISAM, SQL, Memory Table, or XML.
Being able to work like this allows the developer to work without knowing the details of the
implementation, which makes the code reusable for different circumstances, and also makes
a shorter learning curve for the developer. Programs can survive many different versions of
the operating system or database, because the code isn't dependent on either.
Development for the Web always required additional programming languages, such as
knowing J avaScript, and also required additional knowledge of Web page design. Now,
everything is in the same studio, and the applications front-end is designed in the same way
as any other Client/Server application.
The good news is that developers can have access to this technology from the same familiar
and productive toolkit we've been using for years. Rich Client programming is very similar to
regular Magic xpa online programming, and you will be amazed at how quickly you can start
using this technology.
So welcome to class, and let's get started!
What Is Rich Client?
Rich Client is part of Magic xpas "rich" set of tools.
If you've been using Magic xpa, you know that it handles the detail work for you when you
are linking to, say, different kinds of databases. You can create a data source that can be
used in a program, but the actual physical data source ... ISAM, SQL, XML ... can be
determined at runtime or based on which components are used.
Rich Client extends this functionality so that you can run a program over the Web on various
hardware platforms, using the same sort of Magic xpa programming you are familiar with.
Magic xpa uses a thin client running on a .NET framework to accomplish this.


Why Use Rich Client?
So why would you use Rich Client?
Thin Client: A Rich Client program can run on any computer that is connected to
the Internet. Magic xpa does not need to be installed on the client machine.
Browser-Free: Your Rich Client programs will run over the Internet, but are not
dependent on any Browser software. This means, for instance, that you don't need
to worry whether the user is using Explorer or Firefox or which version.
" Rich" look and feel: The .NET client will have the native OS look and feel, and
includes a richer GUI interface than HTML.
Complex Programs: Rich Client programs can be more complex than your
standard Internet Browser programs. In fact, they look and work a lot like the Magic
xpa Online programs you are used to.
Platform independent: Rich Client works on the .NET framework. That means it is
not tied to one operating system or version of that operating system. Nor is it tied to
a version of a Browser.
Robust: Rich Client programs can handle high volume transactions and high
volumes of requests.
Context Management: the Magic xpa engine will provide the context management
for each user automatically, so each user has an independent session, similar to the
Magic xpa online environment.
Best of all, you can get all this functionality without a large learning curve. Rich Client
programs, as you will see in this class, are designed very much like regular Magic xpa Online
programs, even though they actually function very differently behind the scenes.


Chapter 2: Constructing a Rich Client Task
It's very easy to create a Rich Client task. Basically you will use the same techniques you
use for an online Magic xpa program, with a few changes because of the nature of Rich
Let's start by creating a very simple Rich Client task, and watching how it works. Then we'll
progress to more complex programs, so you can learn the differences you need to know.
Hello World, Rich Client Style

Let's start with the classic simple program:
Hello World.
Create a new program.

Next, select Rich Client for the Task type.
This is what makes the program run as a
Rich Client program.

Create at least one variable.

Because this is a Rich Client task, the
Main Form will default to Rich Client
Display. This is the form type that will be
used for Rich Client programs, rather than
the GUI Display type used for Online


Now create your form, as you usually
would, adding text and fields from the
Control and Variable palettes.
Now run your program as usual, using F7.

Running the Program

Here are the results. You will immediately notice a few things:
First, the Hello World! program is running in its own stand-alone Window. It is not part of the
runtime MDI. In fact, this is a stand-alone .NET program, and isn't running directly in the
Magic xpa Engine at all. Although it is currently running on your machine, it could be running
anywhere in the world, over the Internet.
However, it is not running in a Browser window either. The program is not written in HTML. It
is written in .NET, and that means it will pick up the user interface standards for whatever
platform it is running on. The Hello World program could be running on any platform that
supports .NET framework.
This is a very different runtime environment, and there are a few things you need to know to
work with it successfully. But as you have seen, most of the programming is the efficient,
familiar Magic xpa coding you already know.
Leveraging Off What You Know
The nice thing about Rich Client is that a Rich Client program is very much like an Online
task, from a development point of view. You don't need to learn a new paradigm, and the
skills you already have will remain very useful.


A Rich Client Browser List

Now, try a Rich Client program that is a little more complicated. In this section, you will
generate a Line Mode program to display records.
Use Ctrl+G to bring up the APG, and select Option =Rich Client

Now when you run the program, you will see an entire list of customers, running in the Rich
Client .NET environment.
How the Task Flows
Let's take a closer look at what is going on when this task operates.
Keep in mind that the actual "Customer List" client program would normally be running
somewhere else, not on your server machine. That means the program doesn't have access
to the database directly; nor, necessarily, to the Windows environment. However, it isn't a
Citrix-style "screen scraper" either. Instead, some operations are executed in the client
environment, and some are executed in the server environment. While this all happens
automatically, it is important for you to know what is happening so you can optimize your
programs if needed.


Server A new context is created for this task.
Task Prefix Server Before the client task starts, the Magic xpa engine on the
server opens the database tables, initializes the Virtual
variables and using the Range and Locate values, creates the
initial Data view.
The client task hasn't started yet. All operations execute on the
Client and
While the user is working with the task, the .NET engine will be
working with the local XML that was sent, to execute
operations and display data.
However, some operations will also be executed on the server,
where needed.
During the User Interaction phase, Record Prefix and Suffix are
executed according to the same criteria used for Online tasks.
The client doesn't need to fetch a record from the server each
time since a group of records was sent in the initialization of
the task.
Task Suffix Client and
The Rich Client task has already terminated. Operations that
are executed can be executed on either the client or the server,
depending on the operation. After the Task Suffix is finished,
there is access to the server to close the task there.
We'll take a look at how the various handlers work in the Performance Awareness chapter.
Using Colors and Fonts
You can use colors and fonts as you usually would in Magic xpa. The colors and fonts will be
passed to the client program. If this program doesn't have access to a specific font, then the
operating system decides on a default font to display.
You can avoid this by choosing fonts that are common among different operating systems; or
at least those you are intending to support.


Chapter 3: Performance Awareness
In the Rich Client paradigm, processing is split between the server and the client. The
communication between the two is done by sending a compressed XML file. This
communication bus can create a bottleneck, which can affect program performance. So, to
create efficient programs, you need to minimize the amount of back-and-forth
For instance, DBMS access happens on the server, but user interaction takes place on the
client. Ideally, once the data is sent to the client, the user could tab from field to field without
any further interaction to the server, until the record is ready to be committed. However, if
you were to add a DBExist() function inside a condition that is evaluated in a Control Suffix,
then access must be made to the server every time the user tabs out of that field, which
would slow down the user interaction.
Fortunately, you don't need to memorize what can and cannot be done, or what is and is not
efficient. There are tools within Magic xpa to make it more obvious what is going on. In this
section we'll show you how to use those tools.

When logs are used, each request is written to the logs, so when performing lots of
requests (such as in a non-interactive program), the performance may look slow.

Some of the areas we'll be covering:
Data View: The Data View is established before the task starts, and this can affect
how the Variables are handled.
Functions: Each Function will be client side, server side, or Neutral.
Expressions: The Side of the Data View and Functions will determine the Side of
the Expressions.
Handlers: Where a handler is executed will depend on where it is called from, and
the Operations and Expressions it uses.
Basic Building Blocks
A Magic xpa task is built in three basic sections. In a Rich Client task:
The Data View is built on the server.
The Forms interact with the user.
Some Logic handlers execute on the server, some on the client, and some are


We'll take a look at each of these sections in turn.
However, variables, functions, user functions, and expressions are used in all of these
Variables are declared in the Data View. Usually they are neutral, but some are
Functions are built-in to Magic xpa, and by their nature are client-side, server-
side, or Neutral.
User functions are created by you, the developer, and their side depends on the
operations and variables they use.
Expressions are built using the items above. These are especially important
because they are used in properties all over the task, in Ranges, Inits, Conditions,
Controls, and Forms.

In this section we'll take a look at these basic building blocks.

Variables are declared in the Data View section, and they are usually neutral. The Data View
is built on the server, but as the program interacts with the user, the values change. These
changes are stored on the client and sent back for storage at the appropriate time, when the
transaction is closed.
However, for some variables, every time the variable changes on the client, server access is
required immediately. Such variables are called server-side variables. These variables have
an "S" next to them, and are shown in a contrasting color, as shown in the image above.
This can happen if the variables are used in the Range/Locate of a Link. Each change of the
variable value will execute the link again; hence there will be access to the server. In the
example above, we have a Customer Code that is used to link to a Customer Record. If this
Customer Code is used in an expression, it will cause that expression to be server-side.
In a Rich Client program, if the data view contains BLOB variables with lots of content, the
BLOBs will be passed between the server and clients (like all other variables), and this might
slow down the program.
It is advised not to define the BLOBs in the data view if they are not used, or you should
create a new Batch task that handles them if they are to be used on the server side.



First, let's look at functions. They are the
smallest building-block of an expression,
and the Side of the expression will depend
on the functions (and variables) in it. Each
Magic xpa function is client-side, server-
side, or Neutral. You can find a list of
these in the Magic xpa Help.
However, when you select a Function, you
can see its execution side in the Function
List, listed just to the right. It will say:
Server & Client (i.e. Neutral)

User Functions
Functions that are written by the developer are evaluated according to their location and
what operations they contain.
If the function is defined in the same task as the expression that uses it, then, the expression
will have the same side as the function. If the function is defined in the Main program or a
component, then the expression that uses it will be set to Unknown.
User functions cannot contain both client-side and server-side operations.
Expressions are built from one or more functions and variables. The side of the expression is
determined by the side of the functions and variables.
Every expression can be categorized as being Client-side, Server-side, Neutral, or Mixed.

Client-side expressions can only execute on the client.
Server-side expressions can only execute on the server.
Neutral expressions, however, can execute in either place. They will execute on
the server if the operation is being executed on the server; or on the client if the
operation is being executed on the client.
Mixed expressions contain elements from the server and from the client.
It is important to know what kind of expression is being used. Expressions are used in many
different places within a task. If the expression is a server-side expression, but is being used
in a place that would require it to be evaluated on the client, the client has to stop and send
a request back to the server before processing can continue. In some cases, the syntax-
checker will disallow the process; in other cases, it is allowed, but it will be slow.


Every expression is marked as to where it
will be executed:
S =Server-side
C =Client-side
M =Mixed
blank =Neutral
This is important to know, because the expression will be used in an operation, a property, or
an Init value. You want to make sure that the side of the expression matches where it is
Data View Section
The Data View is assembled on the server. The actual records and fields that are used are
included in the XML that is sent to the client.
However, there are settings that affect the Data View in the Rich Client, such as:
Range and Locate
The Init Property
Link Operations

Range and Locate Expressions
Range and Locate expressions, like Inits, are sometimes evaluated on the client, and at
other times on the server. Therefore, the expressions used in Range and Locate need to be

For instance, in this example, we are using a MarkedTextGet() function in a Range. This
generates a syntax error, because we are using a client-side function in a server-side


To solve this problem, we create a parent task that sets a variable using the desired function.
Then we can either reference that variable directly or pass it in as a parameter for use in the
The Init Property
Client-side expressions cannot be used in the Init property. If you need to use client-side
expressions in an Init property, use an Update Variable operation in the Record Prefix.

It is allowed, but not recommended to use a server-side expression in the Init
property because it will cause an access to the server whenever the init should be
performed (for example: init on a real field when the task is in Create mode).

For instance, in this example, there are three fields with Inits.
The first one uses a Neutral expression, which has no marking to the left. This one is
The second Init uses the Menu() function, which creates a client-side expression.
This will generate a syntax error message.
The third Init uses CallProg(), which makes a server-side expression. This will also
generate a syntax error message.

If you do need to use client-side or server-side expressions in an Init, you need to use an
Update Variable operation instead.
For Server-side expressions, it is recommended to do the update in Task Prefix in
order to avoid extra access to the server.
For Client-side expressions, do the update in Record Prefix.
If your Init is for a newly-created record, you should do the update in Record Prefix, using
Stat(0,'C'MODE) in the Condition property.


Link Operations
Although the Link operation is not a procedural operation, it is a server-side operation. This
means that every time a Link is recomputed, the Rich Client refers to the server to execute
the new link.
Any recomputation of a Link operation requires the Rich Client module to
address the server engine and fetch the new record. This means that using
too many Link operations may be costly in terms of server interaction.
Therefore, it is recommended that you limit use of the Link operation. In
many cases you may be able to substitute the Link operation with a Data
control a selection control like a combo box that displays the value of a
range field taken from a table.
You can also use an Inner Join operation instead. In this case, the operation
is fetched from the database along with the Main source and sent to the Rich
Client module as a single chunk of data.
Tracking the Task Flow
As we have seen, the Rich Client operation is rather seamless. It is not easy to tell, from the
user's standpoint, where the logic is executing.
However, as a developer, you need to know this so that you can optimize your programs.
You can use most of the same operations and functions that you would use in ordinary online
programming. Most of the logic will be executed on the client. Some of it, however, will be
executed on the server.
How to Tell What Is Executing on the Client

In the left hand portion of the Logic handler, you will see a one-letter code. This code tells
you where the item will execute:
S =Server
C =Client
M =Mixed
U =Unknown
E =Error
Blank =Neutral


Colors are used to give a visual indication of where the lines will execute.
Items that are executed on the server will be shown in Studio Color 10, which
by default is pink. Neutral lines will have the same color as the line above
them, since they will be executed on whichever side is currently doing the
The flow itself can vary, since some of the operations may have a condition
that will evaluate to FALSE, so they will not be processed.
Forms and Controls
Forms and controls are interactive to the user, and so are client-side expressions.
The issue here has to do with Control Properties. For instance, there are properties that
control whether or not a control is visible, or if it is disabled, or that change the font or color of
the control. When these properties are set using an expression, the expression is constantly
being re-evaluated.
If a server-side expression were to be used in one of the properties, communication would
have to happen every time the control was evaluated. Therefore, you cannot use server-side
expressions in a control; you will get a syntax error. Server-side expressions are marked with
an 'S'.
Using Server-Side Expressions

For instance, in this example,
CallProg() is a server-side function,
and so cannot be used in a client-side
Control property. This will generate a
syntax error.


To solve this problem, we use a variable to hold the value of the expression, and update it
in Task Prefix. Since Task Prefix is executed on the server, this operation will not cause an
additional access to the server.
Other Issues with Controls
There are other issues to think about with forms, specifically if you are using subforms. When
you use a subform, the subform will be refreshed according to certain rules, as covered in
Working with Multiple Tasks.
Table Controls
When you have tabular data, the Preload View task property can be used so that all the
table lines are loaded before the task starts. This will minimize access to the server as the
user browses the table. How beneficial this is depends on the size of the table; if the table is
too large, the initial load time might not be worth it.
Tree Controls
You can use the Node Preload Tree Control property to fetch all the records in the tree from
the server, before the task starts. This will minimize server interaction. As with the Table
control though, if the dataset is too large, the wait time for the initial load might outweigh the
benefits of faster tree interaction.
As we have seen, for many of the handlers, the execution side will depend on the operations.
However, some of the logic units are fixed as to where they execute.
Task Prefix Server
The Task Prefix is executed when the task initializes. It is a pure server-side handler and no
client-side operations may be performed here.
Before the client task starts, the Magic xpa engine on the server opens the database tables,
initializes the Virtual variables and, using the Range and Locate values, creates the initial
Data View.
The client task hasn't started yet. Operations that are executed, execute on the server.
The client-side program and the data in the Data View are packaged into a small, encrypted
XML package, which is sent over the Internet to the client machine.


It is important to remember that the execution of the Task Prefix, the initialization phase of
the task, is executed on the server side as a whole. This means that in the initialization
phase, any Call operation to a Rich Client task will be subjected to the following rule:
All Call operations will be executed at the designated time, but the Call tasks window is
opened on the client side after completion of the Task Prefix. This means that all Call
operations will take place after the other operations are executed.

Using a Client Operation

Since Task Prefix is always server-side, you can't use client-side functions in these tasks. In
this example, we are using the client-side CtrlGoTo() in Task Prefix, which is not allowed.

To fix this problem, use a Raise Event in the server-side handler, with Wait=No. This way,
the server-side handler will execute on the server. The event itself, however, will be executed
on the client.
Unidentifiable Events in Task Prefix
You need to be careful with Raise Events in Task Prefix. When an event is raised, the syntax
checker cannot always determine where the event will be handled. We cover this more in
Raise Event in Task Prefix.
Task Suffix
The Task Suffix logic unit is performed when the task terminates. It can be either server-side
or client-side, depending on the operations within.
Rich Client tasks defined with a non-Modal form that are called from the Task Suffix logic unit
will be run and immediately closed because the calling task has already been terminated.


Variable Change

Variable Change handlers are executed each the time the user browses the records. The
handler is Neutral; however, it is recommended not to use server-side operations in it, to
avoid accessing the server every time the variable is changed. There are two phases to
Variable Change: the recomputed phase and the control change phase. So if a server
access is made, as in this example, the access will happen twice. Therefore, only client-side
or neutral operations should be used.
Control and Record Level

Control and Record Prefix and Suffix operate according to the same rules as for online
programs. When the user is working with a record, Control and Record Prefix and Suffix
execute as the user moves between controls and records. This sort of interaction should
happen on the client side, without the need for server interaction.
These logic units therefore, like Variable logic units, should ideally only have client-side or
Neutral operations. In this example, we have server operations in both Record Prefix and
Control Prefix. These should be moved, if possible, to Task Prefix.
Error Level


An Error level logic unit is executed when the corresponding DBMS error is encountered.
This logic unit is executed on the server.
The Rollback option that displays a confirmation dialog box cannot be executed on the Rich
Client. This means that the first parameter of the Rollback function will be ignored. Also the
Message property on the Error Event will be ignored.
So, if you wish to show the user the error, you can use an Async Event (Wait = No). This will
cause the event to be executed after the error handler logic is finished.
For more information about Error Handling, refer to the Error Handling section in the Magic
xpa Help.
System and User Events
For System and User events, where a given Event handler will execute depends on where
the operations within it execute. Let's take a look at a simple example.

Here is an Event handler that can execute on either side. Such a handler is considered
Neutral. It will execute wherever it was called from, without the need for communication with
the other side. There is no character next to Event header line. The Update operation is
considered Neutral also. It can execute on either side.


Now, if a Verify operation is added, the Event handler becomes client-side, and is marked
with a "C". This is because the Verify operation can only execute on the client, since it needs
to give a message to the end user. The Update operation is still Neutral and will execute
wherever it was called from. If the Verify operation needs to be executed (i.e. if the Condition
on the Verify operation evaluates to TRUE) then the Verify operation will be executed on the


If a Call Program to a Batch task is added instead, the Event handler becomes server-side,
and is marked with an "S". This is because Batch tasks always execute on the server.

But what happens if the two are mixed? If client-side and server-side operations are both
used, the event is considered Mixed and is marked with an "M". Mixed operations are to be
avoided when possible, because the communication between the client and server will make
the task run more slowly.

With some operations, it is impossible to know where the execution will take place. This
Raise Event operation, for example, may be handled in this task, in a parent task, in the Main
program, or even in a component.


Handler Operations
Each operation can be Server-Side, Client-Side, Neutral or Unknown. Neutral operations
can be executed on either the server or the client.
Operation Where it

Verify Client Always on the client.
Call Batch Server Always on the server.
Using the
This is considered as Mixed, since there is
immediate access to the client to close the
task that currently runs in that subform.
Rich Client
Mixed Executes partly on the client and partly on the
server. It will access the server to load the
task, but then go to the client to start it, and
the caller task is halted.
Rich Client
Window Type=Not
Server Access the server to load the task. Then the
process continues, without waiting for the
called task to run.
Invoke UDP Server Executes partly on the server.
Web Services Server Executes partly on the server.
OS Command Depends Depends on the Execute On property.
COM No Not supported.
Evaluate Depends Depends on the operation being evaluated.
Block Depends Depends on the Block expression.
Update Depends Depends on the variable being updated, and
the Expression used for the Update.
Raise Event Depends Depends on the handler for the event being
Form Input, Output No Not supported. You can run reports on the
server and display the results on the client.
See Displaying a PDF.

Operations are also affected by the expressions used in their properties: for
example, the Condition property.


Raise Event

Usually, Magic xpa can tell where a Raise Event will be handled. For instance, in this
example, the event is handled in this task. The handler for F12 is Neutral, and has the
Propagate property set to No, so the Raise Event is also Neutral.

However, if the handler for F12 is server-side, then the Raise Event will also be server-side.
That forces our F11 handler to also be server-side.


In this example, however, there is no handler for the F12 event in this task. If the Studio
cannot determine where the Raise Event will be handled at Runtime, it is marked Unknown.
This happens when:
The event's handler is in a different task. It is not possible during the
development stage to know which task will handle the event during runtime. It
depends largely on the runtime tree.
The handler of the event in the current task has a Propagate property of Yes.
Once again, it is not possible during the development stage to know which task
will handle the event during runtime. This also depends largely on the runtime

Notes on Raise Event:
If a Raise Event operation with Wait = No is part of a sequence of
server-side operations, it will be performed after all of the events,
so it is considered to be Neutral (because it does not cause
immediate access to either side).
When a server operation sequence contains a Raise Event that is
unknown, an error may occur in runtime.

Raise Event in Task Prefix
Task Prefix is always executed on the server.

If you enter a client-side operation in the Task Prefix, this will generate an error:
Server-side handler cannot contain client-side operations. You can set the Wait property to
No to execute this operation after the Task Prefix operations.
The only way you can have a client-side operation is to set to Wait=No. Then, after all the
rest of the Task Prefix operations have been executed, the operation will be executed, when
control returns to the client.


If an Unknown-side operation is in Task Prefix, you will get a warning:
Note that if an Unknown-side operation is defined on the server handler and is evaluated to
a client-side at runtime, an error will occur.
At that point it is up to you to ensure that the Unknown-side operation is really server-side.

However, if you set the Raise Events to Wait=No, then the issues go away. The client-side
events will be raised on the client, after the server-side events have been raised on the
Call Operation
Your Rich Client task can call another Rich Client task in much the same way you would do
this for an Online program, using the Call operation and passed arguments. A called program
can be displayed in a Subform or Frameset, run as a separate window, run as a Modal
window, or even run in parallel.
Calling Another Rich Client Task

When one Rich Client task calls another, it is considered a Mixed operation. The server
needs to package the task, and it needs to run on the client.
Batch Tasks

Batch tasks are completely server-side. So for instance, if you want to create a complex
report, the report batch tasks would run on the server and would be very efficient. The final
result, the report, you could display on the client after the batch tasks finish.
A Call operation to a Batch task is always synchronous. This means that the client waits until
the Batch task is completed. The Start and Stop Execution dialog boxes are not supported
for Batch tasks that are called from a Rich Client task.


Call Operations in Task Prefix

If you try to call a Rich Client program from the Task Prefix, you will get an error. The Task
Prefix cannot run a client-side program.
You can, however, use a Raise Event with Wait=No, to allow the called program to execute
just as the task starts on the client, as shown in Using a Client Operation.
Invoke OS Command
An Invoke OS Command is an interesting operation. It basically calls a command in the
native operation system. If you are running on one machine, it's obvious. But in a Rich Client
environment, what does it mean? In fact, you may want to execute an Operating system
command on the client, or on the server.
It is up to you to specify which environment will handle the command.
Invoke Server

Here we have a simple OS command that shows the current directory, and redirects it to a
temporary file. The question is: are we showing the directory on the server machine, or on
the client machine? This is controlled by the programmer, who sets the Execute On
property. Here, it is set to server. That makes this Invoke Command a server-side operation.


Invoke Client

Here we have the same operation, but the Execute On property is set to Client. This makes
the operation client-side. The directory being displayed will be on the client machine,
wherever that happens to be.
Uses for Invoke OS
You can use the Invoke OS operation for running any operating system event on the client or
server. In the examples above, the same command was executed:
dir > C:\Temp\Dir.txt
But in one instance, the server directory will be listed, and in the other, the client directory will
be listed.
Note that there are also Magic xpa functions for accessing the operating system, so directly
executing operating system code with Invoke OS isn't commonly needed. For instance, if you
want to access the value of an operating system environment variable, you can easily use
the OSEnvGet() function.
OSEnvGet() will fetch the server environment variables. A separate version of this function,
ClientOSEnvGet(), will fetch the client environment variables. Other pairs of functions allow
you to access file information (FileInfo() and ClientFileInfo(), for instance).

Block Operation

The Block operation will execute client-side or server-side, depending on the Condition


Optimizing Block Operations

When you have a Block IF operation, it's good to group the client and server side together.
The module will test each condition until a TRUE line is found. So in this example, if no
condition was TRUE:
1. Executes on the client.
4. Executes on the server.
6. Executes on the client.
8. Executes on the server.
10. Back to the client.

Now, with a little shuffling, we can change that to:
1, 4 Execute on the client.
6, 8 Execute on the server.
10 Back to the client.


We could further optimize this by using a variable to hold the INIGet(), so that it doesn't need
to execute twice. If the INIGet() is done in Task Prefix, the comparison done in the Block
could be client-side, and no accesses to the server would need to be done during the Block
until and unless the Batch task is called.
The Block Loop

It is not a good idea to have both client-side and server-side operations in the same loop, as
shown here, because this will require multiple jumps between the server and the client to
perform the operations.
Verify Operation

The Verify operation is a client-side operation. You can use it to display messages to the
user in a dialog box, or on the status bar.
If you choose to display a message using Display=Status, keep in mind that the status bar
will be the status bar of the SDI window. If you aren't using an SDI window, then the
message won't display. If you use Display=Box, then a popup box will appear, as it would in
an ordinary online program.
Because the Verify operation is client-side, you can't use it in the Task Prefix logic unit in a
non-Offline task.
Update operations are Neutral. Their side depends on the expression being used and the
variable being updated.
The Side of an Update operation depends on:
1. Where the handler is being executed.
2. The Functions and Variables in the Update Expression.
3. The side of the Variable being updated.


The "side" status of an Evaluate operation depends on what Expressions are being
executed. An expression may consist of one or more Functions and Variables, and each of
them will be client-side, server-side, or neutral.

Here we have an AddDate() expression, which is Neutral. So, the Evaluate Expression is
also Neutral.

However, if the expression is a FileDelete(), the operation becomes server-side. FileDelete()
is a server-side function.


ClientFileDelete(), however, is client-side. So now, the Evaluate operation becomes client-



It is also possible to create expressions that combine client and server-side functions or
variables. In this example, the Evaluate Expression is considered in error, and is marked with
an E. This is because it uses a Mixed expression, which is marked with an M. A Mixed
expression contains items that must be executed on the server (FileExist) and items that
must be executed on the client (ClientOSEnvGet).
Mixed Operations

A mixed operation is one in which a server-side operation or expression is used in
conjunction with a client-side operation. There are a few situations in which this may arise:
A client-side operation, such as Verify, uses a server-side function in one of the
expression properties for the operation, such as the operation condition. (As seen
in the F10 event above.)
A server-side operation uses a client-side function in one of the properties, such
as the condition expression. (F11 event above)
Mixed expression: A single expression may need to use both client-side and
server-side functions. (F12 event above)
In these cases, you will get an error message from the syntax checker.

To implement this sort of logic, you need to use more than one operation, holding the result
of the expression in a variable. The variable should be updated wherever it makes the most
sense ... in a sequence of operations that are on the same side as the expression.
In our example, we have a variable, v.Is a weekend, which is updated in the Task prefix with
a CallProg(). This gets used by the F10 handler, which is now purely client-side.


Another variable, v.Client report has been run, is updated in Record Prefix. That allows the
Call Program in F11 to be purely server-side.

Similar logic is used for the Mixed expression used in F12. The original expression was
Mixed, and so marked with an M.

In our updated version, we hold the ClientFileExist() function result in a variable, which is
updated in Record Prefix (or wherever is convenient on the client side). This makes the
expression purely server-side, so it works.

To repeat: If you are unsure if a given function is client-side, server-side, or either,
look in the function list. When the function is displayed, the Side is listed on the lower


Grouping Operations

When you do have an event handler that is mixed, it's best to group the server and client
operations as much as possible, to minimize network traffic. Here we have a series where
the Rich Client module will:
0. Start out on the client (where the session is executing when the event is raised).
1. Update variable with an INIGet: on the server.
2. Verify warning: back on the client.
3. Call program: on the server.
4. Display the program: back on the client.
This is four trips back and forth.

By slightly changing the code, we change this to 2 trips:
0. Start out on the client, as before. Stay on the client to execute the Verify.
1. Go to the server for the INIGet. Stay on the server to fetch the program.
2. Come back to the client to display the program.
Of course, how much optimization you can do depends on the logic of the program.


Task Settings
Most Rich Client task settings are the same as the settings of an Online task; although some
Online task settings are irrelevant to a Rich Client task. However, other settings are only
relevant for a Rich Client task. This section describes some of these settings:

Main Display: As with a regular Online task,
you can define several forms and, using the
Main Display property, you can provide an
expression that evaluates to the form number.

Icon File Name: As with a regular Online task,
you can define an icon to be displayed in the
Rich Client task. If there is no icon defined for
the task, the icon displayed will be the icon
defined in the application properties.

Transaction Mode: Must be Deferred or
Within Active Deferred. This is explained in
more detail in Transactions.
Preload View: This property defines whether
to retrieve the entire data view in advance.
Once the value is set to TRUE, the server will
fetch all relevant records from the database
during task initialization. This is very useful for
small tables.
When Preload View is set to TRUE, it is good
practice to make the chunk size large enough
to hold all the records fetched from the


Chunk Size: The Chunk Size Expression
property defines the number of records to be
passed to the client upon each request for
additional records.
For example, if this property is set to 100,
when the task opens, the server will pass the
first 100 records to the client. This allows the
end-user to browse the first 100 records
locally. When the end-user tries to scroll
beyond a given range of records, the client
contacts the server and receives an additional
batch of 100 records.
Each chunk of records is accumulated on the
client as a local cache of records. If the end-
user goes to the end or beginning of the table,
the local cache is cleared and the cache
accommodates a single batch of records.

The chunk size is not supported for local databases.
Defining a chunk size that is too large may slow performance. For each data
transfer, a lot of data will be passed from the server to the client. On the other
hand, if the record length is large (for example, it may contain a number of
large Blob variables) you might want to consider decreasing the chunk size.


Client Functions
Accessing Client Files and Folders
A set of functions enable you to access client files. These functions are:

Retrieving Local Environment Settings
Often it is necessary to retrieve environment settings or variables, such as the client
temporary directory. The following functions enable this:
Setting Local Environment Settings
To set environment settings, use the following function:
Measuring Session Activity
To gather statistics about the current session, you can use the following function:


Chapter 4: Working with Multiple Tasks
You can call other programs from within your Rich Client task using the Call operation. The
programs you call need to be either Rich Client or Batch tasks. You can use the same types
of programs you would use in Online programming:
Selection programs can be used as you would for Online applications.
Modal Windows can be used to disallow access to other Windows until the
Modal window is closed.
Parallel tasks can be run.
You can also implicitly call programs, using subforms or frames, as we will see. One subform
or frame can display different programs at runtime using the Destination Property.
The Window Type
You can set one task to run in different ways at Runtime. For instance, you can have a task
that runs in a subform, and also runs standalone. Most of this happens automatically,
because of the way subforms operate.
However, if you want a task that will run using different Window Type properties, you need to
set up two different forms for that task. Then, use an expression in the Main Display property
to choose which form to run.

Calling Other Programs
Called Task Initialization
Task Prefix is always executed on the server. Therefore, when you call a Rich Client task or
program, current processing on the client has to pause while access is made to the server.
The called task's Task Prefix is executed on the server and the window opens on the client.
Calling Batch Tasks
You can call batch tasks from a Rich Client task. The Rich Client task will halt processing
until the Batch task is completed.
Batch tasks always run on the server. You need to keep this in mind if, for instance, you are
using operating system files. IO File names will refer to names on the server machine. There
are special functions to help with this, covered in Accessing Client Resources.
The Start and Stop Execution dialog boxes are not supported for Batch tasks that are called
from a Rich Client task.


Context Management
When you start the first Rich Client task, it runs in its own context. The context logs the state
of the task from the moment it is activated until the moment it is terminated. Each context is
assigned its own unique Context ID.
When you start a Parallel task, a new context is created, with its own new Context ID. Child
tasks of the parallel task will be opened in that same context (unless the Child task is also set
to run in parallel, in which case it will open yet another new context).
Each context is isolated from the others. The task tree, database cursors, SetParam data,
and data manipulation statements are all tracked individually for each context.
Magic xpa tracks the activity in each context. The server will identify each client request as
belonging to a specific context. Information about which tasks and subtasks are open,
database cursors, and data manipulation statements, are all maintained for each context.

Once a context is created on a Magic xpa engine, all the requests from the
client will always reach the same engine.
When using external HTTP load balancer, you need to ensure stickiness
between the client and the server that is the ability of the load balancer to
direct requests from each client to the Web server in which the initial request
was created. To support this, each RIA request contains a header named
MgxpaRIAglobalUniqueSessionID. This header keeps the same unique
value in each HTTP request of a given end-user session. The header
contains a different unique value for each client instance. External HTTP load
balancers can use this to support stickiness.

Context Inactivity Timeout
The context information kept on the server side requires memory resources. To relieve the
server from having to keep numerous contexts that might use too many system resources, a
timeout can be set for the context.
The Context Inactivity Timeout setting can be found at Options\Settings\ Environment\Server.
This setting determines the time interval in which the client is checked for inactivity. Context
inactivity is defined as an absence of client/server interaction during the life of a Rich task.
The Context Inactivity Timeout is set in 10ths of a second. The default setting is 36000 (1
When the context timeout is reached, the context is cleared from the server. By setting a
reasonable timeout, you can prevent abandoned contexts from stacking up on your server.
When a Rich Client task is invoked from the Studio, the Context Inactivity Timeout is infinite.


Parallel Processing

Concurrency in a Rich Client task works slightly differently than in an Online task. A Rich
Client task runs in parallel with its parent task and all other tasks in its runtime task tree. So
in this example, Task 1 calls Task 2, which calls Task 3. However, once they are all open,
the user can click between the three windows at will.
However, in a non-Rich Client online program, clicking on Task 2 would automatically stop
Task 3, unless we used a subform or specified Close Task Window = No. If you want to
make the windows work more like online programs in this regard, you can set them to Modal.
This will force the user to exit the lower-level task before making changes in the higher-level
For both Rich Client and Non-Rich Client task trees, closing the top level task closes the
entire tree. So in this example, closing Task 1 would also close Task 2 and Task 3. If you
want to allow all three tasks to be truly independent, you can set the Parallel property to Yes.
However, doing so creates an entirely new context to manage, so you should use this feature
only when it is needed.
Non-Interactive Tasks
Batch tasks are executed on the server and cannot call Rich Client tasks. Sometimes, there is a
need to run a batch process on the Client side, which will call an interactive task. This can be
achieved by unchecking the Interactive property in the task properties.
A non-interactive Rich Client task is similar to a Rich Client task except that it will process the
records automatically without waiting for user input, and will end when the last record is processed
or according to the End Task Condition property.



Subforms allow you to merge two tasks, so that several tasks can run on the same Form.
They are often used to display tables, as in our Order Entry example.
The methodology for adding a subform is the same for Rich Client as it is for Online tasks.
The task used in the subform must also be a Rich Client task.
Subform Initialization
When the parent task starts, Task Prefix and Record Prefix of the parent task are executed.
Then, in the subform, Task Prefix is executed, and Record Prefix is executed for the first
Subform Refresh
Subforms in Rich Client follow the same refresh rules as for Online tasks. If Automatic
Refresh is set to Yes, and arguments are passed, then the subform automatically refreshes
when the values in the arguments change. The Subform Refresh event can also be used to
refresh a subform.
When the subform is refreshed, however, the Task Prefix is not executed. Record Prefix is
executed for records that are being re-read.
Refresh When Hidden Property
Magic xpa provides the Refresh When Hidden control property, which governs the subform
initialization and automatic refresh timing.
When this property is set to Yes, there is no difference whether or not the subform is visible,


The subform's task initialization will be executed after the Record Prefix of the first
record in the data view.
The subform refresh will be done according to the Automatic Refresh property.
When this property is set to No, the subform's task initialization and automatic refresh will
only happen if the subform is visible. This means that:
Before executing each subform's task, its visibility will be checked and if it is invisible,
the subform's task will not execute, and will be deferred. Once the client requires the
subform to be displayed, there will be a call to the server, and the subform's task will
be displayed for the first time.
The execution of the subform's Task Prefix will also be deferred to the first time that
the subform is visible.
If the subform's visible expression is a client-side expression, then when the task
loads, the subform will be regarded as visible.
Note: The Subform Refresh event is not affected by this property, so when manually raised
the subform will be refreshed.
Tabbing Cycle Property
Magic xpa also provides the Tabbing Cycle task property, which determines what happens
when pressing the Tab key from the last parkable control of the subform. The behavior of
tasks running in a subform/frame is determined by the property defined in their task and not
in the parent task.
The Destination Property

A subform can be used to display different programs at Runtime.


This is done by using a Call Operation
property: Destination. When a
program is called that is set to run in a
subform, that program runs in the
subform named in the Destination
property. If another program is called
to run in the same subform, the first
program is closed and the second one
then runs in that subform.
The Destination property can refer to
a subform or a frame. It references the
Control Name or Frame Name. In this
example, there are three different
tasks that can run in the subform,
depending on the value of the Display
Task variable.
Note that the Calls are Mixed side. Whenever the subtask is called, the server must be
accessed. Using a Variable Change as in this example will generate a syntax warning as
such calls could be inefficient.
You can also use this technique with Frames.

Exiting the Subform
One thing that is different about subforms in Rich Client is that when the subform is exited,
the parent task also exits. If the Exit internal event is raised, or the user presses Escape in
the subform, the parent task will also exit. This is also true for Frames. If you want to prevent
the task from exiting when the user presses Escape at a lower level, you can create a
System event for the Escape key, with Propagate=No.



To create more sophisticated forms, you can use Rich Client Frame Sets. These enable
you to divide a task into multiple sections, each of which displays a different program. The
programs displayed in each frame must be Rich Client programs or subtasks.
Frames work similarly to subforms. However, with a frame, the user can easily resize each
section by dragging the divider bar.
Frames can be nested, and also used in conjunction with subforms and tabs, to create rather
elaborate user interfaces. In this example, we use a frame on the left to allow the user to
browse Customer, Orders, and Products. The selection is then displayed in the frame on the
The Form Type

To create a Rich Client frame, you first
need to choose Rich Client Frames
as the Interface Type for your form.

Now, when you open up the form, you
will see a Frames palette. You can
choose the format you want to use by
clicking on it. Here, the frameset is two
vertical frames.
Note that these frames can also be
nested, so there are many more than 6
possible combinations at runtime.

The Frame Connect To

Each frame can then be connected to a
Program, Subtask, or Form. This works
very much the same as it does for subforms.
You can use Arguments and Automatic
The Form type is used when you want to
display data from the current task, without
calling a subtask.
You must choose something to display in each frame. If you want to change what is
displayed in the frame at runtime, create a blank or "dummy" task that will display when
nothing else is called.


Frame Name

Each frame can also be given a Frame name. This is used to display a program in a
particular frame.
In this example, we have two frames. The Menu list displays on the left. It is the only program
that ever displays in the frame. On the right, we call a dummy program that displays nothing.
At runtime, we'll fill in this space with a program, depending on what was called from the
Menu list.

Calling the Program

Now, when you call the program, all you have to do is specify which frame it will display in.
Here, the program "Customer Display" will be displayed in the frame named "Right".


Rich Client programs use Deferred transactions. It is not possible to use Physical
transactions, because the DBMS is on the server.
In a Deferred transaction, Magic xpa saves up the changes made to the data, then commits
them when the transaction ends. If the transaction is rolled back, then the retained
transaction information is discarded. This behavior in Rich Client is the same as that in
Online programs.
However, there are some differences in the way transactions are handled in Rich Client. In
this section we'll look at the similarities and differences.
Transaction Begin

The Rich Client module handles any modification of data, whether it is updating a record,
creating a new record, or deleting a record. All data manipulation statements are kept by the
Rich Client module and are transmitted to the server according to the settings in
Transaction begin:

Before record prefix: Changes are committed after exiting a record in a Record
level transaction.
Before task prefix: Changes are committed after closing the task in a Task level
Transaction Mode

The Transaction Modes you can use in a Rich Client task are:
New Deferred
Within Active Deferred


Transaction Mode = None is exactly what it sounds like. No transaction is opened. You
should use this on tasks that do not save any data, to prevent accidentally opening a
transaction "wrapper" that might bundle transactions in a child task. This is especially true if
you are creating a main background screen or when creating a background frame.
New Deferred
When the Transaction mode is New deferred, a new transaction is opened whether or not a
transaction is opened in the parent task. The child transaction is committed at the child level,
regardless of what happens in the parent transaction. If a transaction begins, then:
A new Deferred transaction will begin.
Any changes made in this transaction will be committed after the transaction is
closed (regardless of the caller transaction).
The caller transaction can be closed even if this transaction is still open. Closing
the caller transaction will not affect this transaction.
New transactions will have their own transaction cache. The transaction cache will
not be shared among them, and any changes made in one transaction will not be
seen in the other transactions.
Within Active Deferred
When the Transaction mode is Within Active, then this transaction becomes part of the
parent's transaction (if any):
If a transaction is already opened, then the task will be part of that transaction.
If a transaction is not opened, then a new deferred transaction will begin.
If the parent task's transaction is rolled back, then the child's transactions will also be rolled
This should be used with care, because it is possible for one parent task to have many
transactions open in child tasks, all being saved up. Unless there is a good reason to roll
back more than one task level at a time, New Deferred is safer.


Comparison of Online and Rich Client Transaction Modes

Online Comparison
None Physical/
No transaction is opened.
Deferred At the parent level, the New Deferred and Deferred work the
same: both open up a new transaction.
At the subtask level, Nested Deferred works for online task as
New Deferred does for Rich Client programs.
These work the same in both Online and Rich Client. The
current task's transactions become part of the parent's
... Physical There is no Physical transaction mode for Rich Client
programs. The Deferred transactions will be committed to the
Physical database when the transaction closes.
Note: The Transaction mode for local data sources behaves differently, as described below.

Local Data Sources
The transaction for local data sources behaves as a physical transaction. All the tasks that
include a local data source will be on the same transaction. (This is planned to be changed in
future versions.)
Commit of the local data is done according to the task that opened the transaction. If a
transaction is also opened in sibling tasks, then the data of these tasks will also be
committed. (This is planned to be changed in future versions.)
Rolling back a task that has a local data source will roll back:
All the tasks that have a local data source. (This is planned to be changed in
future versions.)
The deferred transaction of a parent task.


Chapter 5: MDI in Rich Client
You can use an MDI environment for your Rich Client application by specifying it.

1. In your Main Program, add a form.
2. Choose 0 as the Class and Rich Client MDI Frame as the Interface Type.
3. In the Form Properties, select the pulldown menu you want to use for your Rich Client
application. You can also choose the MDI background color, image, or gradient style.
4. In Main Program->Task Properties->Interface, check the Open Rich Client MDI
Frame property. This causes the MDI frame to open when the Rich Client application is
5. In your programs, set the Window Type to MDI Child or Fit to MDI if you want them to
operate within the MDI borders.

This also works within the Studio, when you press F7 to test a Rich Client program or Ctrl+F7 to
test the application.
Note: When you have the MDI environment activated in the Main program, you do not need to
specify a Start Program Name when you publish your Rich Client application.


Chapter 6: The Browser Control

Accessing Other Applications
Working in a Rich Client
environment, the data is on the
server, and it is displayed on the
However, you might need to
display data on the client using a
different application. For instance,
you might want to display a report
in a PDF, or in an Excel

The Browser Control
One way to handle this is to use
the Browser control. This control
acts like the Microsoft Explorer
ActiveX object.

If your browser content is too large for the control, and you want to get rid of the
scroll bars, you can use the following Style:
body { margin: 0px; overflow:hidden }


Browser Control Properties

The Browser control has very simple properties, most of which are the same as those used
by other controls. The Data property is an alpha variable that holds the name of the website
or file that will be opened in the Browser.
Browser Control Event

There is also a Browser Control event, called Browser Status Text Change. This is
triggered whenever the text on the Browser Status line changes. It returns the text that would
be on the status line, in a Unicode Blob.

Note: The Browser Status Text Change event is how the Rich Client module
receives information from the browser.
By using J avaScript, we can change the value of the status bar and by doing that
pass data back to the Rich Client module where it will be manipulated


Browser Control Functions
The Rich Client module has a few functions that give the developer more flexibility over what
is displayed in the control:
BrowserSetContent This function sets the content displayed in the control with
new HTML text. This is different than updating the control itself with a new URL.
BrowserGetContent This function gets the content displayed in the control.
This is used together with the BrowserSetContent function to retrieve the
content, manipulate the text and return the content.
BrowserScriptExecute This function executes a VBScript or J avaScript
function in the Browser control.
Displaying a PDF
This Browser control can be used when creating reports. Obviously, the end-user will want to
print reports at their site, not wherever the server happens to be. However, the Magic xpa
printer setup will be referring to the printers on the server.

1. Create a directory that will hold your PDFs on
the server. For example, C:\PDF.

2. Create an alias for your website that points to
the disk directory. Here, the alias is named "PDF".

3. Now you can reference the PDF from within the
Browser on the server machine.


4. When you print the report, use an Expression to specify a filename within the C:\PDF

5. Set the PDF property to Yes.
This will make the GUI report
print to the PDF directory on the
server, in PDF format.

6. Now, after you run the report,
you can open the PDF in the
browser, using

See also: The RRC08 sample program in the RIA samples


Chapter 7: Application Monitoring
It is possible to develop robust and complex Rich Client programs. When you need to figure
out complex logic or a strange problem that develops at runtime, Magic xpa has built-in tools
to help you.
The Debugger
Magic xpa has a robust debugger and logging system. This is especially useful as you are
learning about Rich Client, because you can analyze exactly what your program is doing,
and use breakpoints to stop the program when needed. If you are not yet familiar with the
Debugger, you can read about it in Mastering Magic xpa.
When you are using the Debugger with Rich Client, be sure to set the Client Activity
property to Yes. Otherwise, you will only see the server activity.
The Debugger can also be run remotely, after your application is deployed. Again, if you
haven't used this feature, you can read more about it in Mastering Magic xpa.
Server Synchronization
Logging a server simply displays the local operations. However, logging a client requires it to
transfer its operations to the server to be viewed within the Activity Monitor.
Each client context keeps a log of its own operations in cache memory. The Rich Client
module will flush the operations to the server in the following cases:
The next Rich Client module interaction with the server.
At the end of a handler. For example, at the end of the Record Prefix handler, the
Rich Client module will flush the operations to the server.

Keep in mind that running the Debugger does cause a performance slowdown.
You can turn off the Debugger when you are not using it, by clicking on the
Debug Mode entry on the Debug menu or


Client Crashes

Sometimes it happens that a client crashes and, as such, the last sequence of operations
may be lost. We need to understand which operations were executed before the crash.
These operations have not yet been flushed to the server and so are not visible in the Activity
To debug client-side crashes:

1. Set the LogClientSequenceForActivityMonitor flag in the HTML file to Yes. The HTML
file is created when you use the Rich Client Deployment Builder. If the flag is set to Yes,
client activities will be written to a local log file on the client. This log file will include all the
information that was not yet sent to the server. The log file will be deleted after each
event execution or when the application is terminated.
2. Launch the application again. Magic xpa will scan for existing log files. If there are any log
files from the last crash, they will be sent to the server (and appear in the Activity
3. When a crash occurs, exit all other parallel processes (so that their log files will be
deleted normally).
4. Restart the application and the log file with the last client sequence will be sent to the
server (and appear in the Activity Monitor).
5. The Activity Monitor will be updated with the client log, and now you can see the location
of the problem.
Note: The Activity Monitor's lines are pink for the server and white for the client.
Displaying Session Statistics
In Rich Client forms, whenever a status bar is displayed, it can show information regarding
the recent network activities. This is available when hovering with the mouse pointer over the
right area of the status bar. When a program is executed from the Studio, this option is
always conditioned by the keyword [MAGIC_RIA] DisplayStatisticInformation=Y. When a
program is executed at Runtime, you can enable this by specifying
DisplayStatisticInformation=Y in the <app_name>.publish.html file used to launch the


Chapter 8: Deploying Your Application
As we have seen, you don't need to know much about .NET to create and test a good Rich
Client application. However, when you go to install your application, it's helpful to be familiar
with the environment in which it executes.
When working with Rich Client applications, there are elements of your application that you
need to expose to the outside world, but there are other elements that you dont want to
make available. Therefore, to provide for a secure environment for your Magic xpa Rich
Client application, the elements of the application are separated into two:

Internal resource files These are the files that only need to be accessed by the
runtime engine, such as the ECF, Color, Font, Users, and local INI. The internal
files should be adjacent to the ECF, such as in the Projects folder, and not
accessible by the Web server.
External resource files These are the files that need to be accessed directly by
the client, such as the HTML file and manifest file, HTMLs, and PDFs. The
external files are supposed to be available to the Web server and exposed using a
Web server alias, the Published Applications alias that you provided in the Rich
Client Deployment Builder.
Preparing for Deployment
The Rich Client application needs to be deployed so that it can execute in a true deployment
environment using the .NET framework in conjunction with the Rich Client deployment
Since the Rich Client environment is intended for use on the Internet, it is useful to
understand the technology that is being used.
Rich Client Modules
All task information and data is handled and executed using .NET module. This module
serves as the actual client engine.
Rich Client Folders
The installation procedure creates the following subfolders in the Magic xpa installation
Scripts: Holds the Internet requester files and RIA prerequisites files
RIACache: Holds the cache data for tasks, images and menus
PublishedApplications: Holds the RIA modules and files that should be
exposed, such as the HTML and manifest files
Although these are installed under the installation directory, other locations can be used. This
is managed by the Web aliases explained in the next section.


Web Aliases
Web aliases are required to deploy a Rich Client application:
MagicScripts: Points to the Scripts directory
MagicRIAApplications: Points to the PublishedApplications directory
These locations can be changed to meet your application requirements.
Environment Settings
The Rich Client cache location may be tweaked to suit your needs. This is manipulated in the
Magic xpa environment settings, under the Server tab:
Rich Client Cache Path: Defines the location where the Magic xpa server will
write the Rich Client cache files.

The Modules
Distributed Application Architecture: Provided by Magic xpa.
The Web Server: You need a Web Server to receive the requests from remote clients. The
Web Server forwards the request to the Magic xpa Server.
Magic xpa Internet Requester: A module that acts as an intermediary between the client
and the Magic xpa server. This module can pass the request and the data to one idle Magic
xpa server in a pool of servers, thus distributing the load.
Magic xpa Request Broker: Maintains the pool of Magic xpa servers. Magic xpa provides
you with a middleware agent known as the request broker. The request broker handles all
the available Magic xpa server engines and directs each request from the Magic xpa Internet
requester to the available server engine. The request broker provides load balancing and
recovery capabilities to handle any fail over.
Magic xpa Server: The Magic xpa server lies at the heart of Interactive Rich Client
Application deployment. It is the actual runtime unit, which handles each request and
executes the entire application logic for each type of request it receives. The Magic xpa
server needs to know the location of the request broker, connect to it, and then make itself
available to the Magic xpa Internet requester.
The Magic xpa server engine is designed to handle multiple requests using a single engine
process. This is achieved using the multi-threading capabilities of the Magic xpa Server


Distribution of the Modules
The above modules can be installed on the same machine or distributed among different
machines, even on machines using different operating systems.
The installation procedure for Magic xpa and the Magic xpa server automatically installs all
the required modules and configures the system to prepare the infrastructure for deployment.
The Web requester, among other things, handles the requests that arrive from the client side.
The Web requester can reside on a different machine than the Magic xpa engine.

FIGURE 1: This image illustrates how a Rich Client communicates with the server, and how
the back end interacts with the distributed Magic xpa modules.
Windows Deployment
RIA applications require the following prerequisites to be installed on the client:
Microsoft .NET Framework Common Language Runtime (CLR) 2.0 SP2 or
above The .NET framework is already installed on Windows Vista SP1 and
above, so you do not need to install it manually.
The installation packages for these prerequisites are available in the Scripts\RIA folder, so
they can be manually installed. The HTML file generated by the Rich Client Deployment
Builder contains reference to these files for easier installation, as explained later on.
When using .NET framework V2.0 SP2, you also need to install the Microsoft Visual C++
2008 Redistributable. You can install them by running the NetFx20SP2_x86.exe and
VCRedist_x86.exe files from the Scripts\RIA folder.


ClickOnce is a deployment technology developed by Microsoft that enables us to execute
.NET applications directly from the Web but is not bound by the constraints of the Internet
browser. The technology enables a client application to be run not only from the Internet, but
also from a desktop environment, giving us the best of all worlds.
One of the benefits of using the ClickOnce technology is that it provides a way to deploy and
upgrade applications without requiring administrative rights (except for prerequisites, such as
.NET Framework).

If the server does not have .NET installed on it, you need to define the following
MIME type extensions:
.manifest application/x-ms-application
.application application/x-ms-application

.NET Manifest File
Once we have the framework for deploying the application, we need to define how to deploy
our application. In other words, we need to tell ClickOnce how to take our Magic xpa
application and deploy it for use. This is done via a .NET manifest file that contains a set of
rules that defines how the ClickOnce launching mechanism should be implemented.
Magic xpa Rich Client Deployment Builder
Magic xpa provides a tool called the Rich Client Deployment Builder, accessed from the
Options/Interface Builders menu of your project, which enables you to easily define the
.NET manifest file.
The tool, which has a wizard-like interface, guides you through the necessary steps to create
the resulting HTML and a manifest file. In this wizard, you define the name of the Rich Client
module that will be invoked by Click Once. A single Magic xpa application may have multiple
Rich Client modules and multiple manifest files.
Within the tool, you define the initial program that will be invoked when the Rich Client
module is loaded. The External property for this program must be selected.
The Rich Client Deployment tool creates two external files:
Manifest file: This is the file that is invoked by ClickOnce.
HTML file: The HTML page first checks to see whether the ClickOnce is installed
on the client and then launches the application defined in it. You can, of course,
amend the HTML page to suit your own needs or use the code within a different
HTML page of your own.


The manifest file and the HTML file should be located in the same folder on
the Web server.
You should always re-create the manifest file when upgrading the Magic xpa

Securing the Manifest File
To run a .NET manifest file, it must be properly signed by a certificate. This can be done by
specifying the certificate and its password when using the Rich Client Deployment Builder.
Note that it is highly recommended not to use the test certificate provided with the Magic xpa
installation, since the publisher is not verified in that way. Instead, you should use your own
certificate so that the publisher will be verified.
Magic xpa Settings for Rich Client Deployment
Deployment Mode
To correctly deploy a Magic xpa Rich Client application, you should define the Deployment
Mode, found under Environment\System tab, as Background. Online mode is suitable for
debugging your application from within the Magic xpa Studio.
Initial Program
We previously stated that this program needs to have its External property checked since it
is the program that we want to invoke externally.
It is good practice to define the form of this program as an SDI.
When this program loads, a new context will automatically be opened for it and all
subsequent programs will execute within its task tree.
Const File
When running an application on mobile devices, you cannot use a Hebrew const file for the
Running the Rich Client Application
After the deployment, the application can be accessed by launching the URL that points to
the HTML file. The activation of the application via a URL is only required when running the
application on the machine for the first time. After the first launch, ClickOnce creates a new
entry for the application in the Start menu, and you should use this entry to launch the
application. Therefore, the dependency on a browser that can launch ClickOnce is only for
the initial load.
Known browser problems:
Google Chrome This browser downloads the deployment manifest file into a
download area, from which it cannot be executed due to Chrome security


Firefox This browser provides an add-on to execute ClickOnce applications:
Other known issues:
ClickOnce only supports Integrated Proxy Authentication.
Offline Issues:
If your application is designed to run in offline and you are deploying it using
ClickOnce, then the published web page (html file) and deployment manifest
(application file) still need to be available for the client.
User Authentication
User authentication is based on the same implementation as the Online environment and, as
such, is dealt with in the same way.
When launching the application, the Magic xpa Runtime checks via the Magic.ini settings
whether user authentication is required. If a logon dialog box is required, the Runtime engine
displays the Magic xpa Logon dialog box.
Retrieving Environment Variables when Loading the Application
To retrieve environment variables when loading the application, you can specify the
environment variable in the HTML file in the envvars argument. This can be done via the
Rich Client Deployment builder.
These environment variables will be sent to the server and be available even before the Rich
Client module gets to the client side (as opposed to the ClientOSEnvGet function). By using
this method, you can retrieve the variables using the GetParam function and condition initial
programs accordingly.
Passing Parameters to the Application
You can pass parameters to a Rich Client application by specifying them in the entry point
These parameters can then be used by the GetParam() function.
For example, when running a Rich Client program via the following URL:
http://server/MagicRIAApplications/project/project.application?N1=v1&N2=v2 ,
the v1 value can be retrieved by evaluating GetParam('N1') and v2 by GetParam('N2').


Chapter 9: Developing Offline Applications
Adding Offline capabilities with local data sources to your application can improve the
performance of your application and reduce network traffic.
Refer to the Developing Offline Applications concept paper for more information.


Chapter 10: Developing RIA Applications for Mobile
Connecting to your application with your mobile can be very useful. You can use RIA
technology to develop your application to be deployed on a mobile device, and still have the
same look and feel of your desktop RIA application.
Refer to the Developing Mobile Applications concept paper for further information.