RIA Tutorial.pdf

download RIA Tutorial.pdf

of 61

Transcript of RIA Tutorial.pdf

  • Rich Internet Application Tutorial

    Rich Internet Application Tutorial

  • 2

    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.

    Magic is a registered trademark of Magic Software Enterprises Ltd. Btrieve and Pervasive.SQL are registered trademarks of Pervasive Software, Inc. IBM, Topview, iSeries, pSeries, xSeries, RISC System/6000, DB2, and WebSphere are trademarks or registered trademarks of IBM Corporation. Microsoft, FrontPage, Windows, WindowsNT, and ActiveX are trademarks or registered trademarks of Microsoft Corporation. Oracle and OC4J are registered trademarks of the Oracle Corporation and/or its affiliates. Linux is a registered trademark of Linus Torvalds. UNIX is a registered trademark of UNIX System Laboratories. GLOBEtrotter and FLEXlm are registered trademarks of Macrovision Corporation. Solaris and Sun ONE are trademarks of Sun Microsystems, Inc. HP-UX is a registered trademark of the Hewlett-Packard Company. Red Hat is a registered trademark of Red Hat, Inc. WebLogic is a registered trademark of BEA Systems. Interstage is a registered trademark of the Fujitsu Software Corporation. JBoss is a trademark of JBoss Inc. Systinet is a trademark of Systinet Corporation. Android is a trademark of Google Inc. BlackBerry is a registered trademark of Research in Motion Limited. iPod, iPad, iPhone, iTunes, and Mac are registered trademarks of Apple Inc.

    Portions Copyright 2002 James 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 http://freeimage.sourceforge.net for details. This product includes software developed by the Apache Software Foundation (http://www.apache.org/). This product includes software developed by Computing Services at Carnegie Mellon University (http://www.cmu.edu/computing/). 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 (http://www.openssl.org/). 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 Reserved.

    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.

  • 3

    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 JavaScript, 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.

  • 4

    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.

  • 5

    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 Client.

    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 programs.

  • 6

    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.

  • 7

    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.

  • 8

    Initialization Phase

    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 server.

    User Interaction

    Client and Server

    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 Server

    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.

  • 9

    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 communication.

    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.

    Note: 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:

    Forms

    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 mixed.

  • 10

    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 sections.

    Variables are declared in the Data View. Usually they are neutral, but some are server-side.

    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

    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.

  • 11

    Functions

    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

    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 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.

  • 12

    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 used.

    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:

    Variables

    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 neutral.

    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 property.

  • 13

    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 Range.

    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.

    Note: 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 OK.

    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.

  • 14

    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

  • 15

    Note: 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 processing.

    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.

  • 16

    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 Subforms 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.

    Handlers

    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.

  • 17

    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.

  • 18

    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

  • 19

    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.

    Neutral-side

    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.

    Client-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 client.

  • 20

    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.

    Mixed-side

    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.

    Unknown-side

    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.

  • 21

    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 executes

    Verify Client Always on the client.

    Call Batch Server Always on the server.

    Using the Destination property

    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 Window Type=Modal

    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 Modal

    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 Raised.

    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.

  • 22

    Raise Event Neutral

    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.

    Server-side

    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.

    Unknown

  • 23

    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 tree.

    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.

  • 24

    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 server.

    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.

  • 25

    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.

  • 26

    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 expression.

  • 27

    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.

  • 28

    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 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.

  • 29

    Evaluate 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.

    Neutral

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

    Server-Side

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

    Client-Side

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

    Error

  • 30

    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.

  • 31

    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.

    Note: 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 right.

  • 32

    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.

  • 33

    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 database.

  • 34

    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.

    Note:

    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.

  • 35

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

    ClientBlb2File

    ClientDirDlg

    ClientFile2Blb

    ClientFileCopy

    ClientFileDelete

    ClientFileExist

    ClientFileInfo

    ClientFileListGet

    ClientFileRename

    ClientFileSize

    ClientFileOpenDlg

    ClientFileSaveDlg

    ClientFileToServer

    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:

    ClientGetUniqueMachineID

    ClientOSEnvGet

    Setting Local Environment Settings To set environment settings, use the following function:

    ClientSessionSet

    Measuring Session Activity To gather statistics about the current session, you can use the following function:

    ClientSessionStatisticsGet

  • 36

    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.

  • 37

    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.

    Note:

    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 hour).

    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.

  • 38

    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 task.

    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.

  • 39

    Subforms

    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 record.

    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, meaning:

  • 40

    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.

  • 41

    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.

    Frames

  • 42

    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 right.

    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 Refresh.

    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.

  • 43

    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".

  • 44

    Transactions

    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.

    Transaction Mode

    The Transaction Modes you can use in a Rich Client task are:

    None

    New Deferred

    Within Active Deferred

  • 45

    None 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 back.

    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.

  • 46

    Comparison of Online and Rich Client Transaction Modes

    Rich Client

    Online Comparison

    None Physical/None

    No transaction is opened.

    New Deferred

    Deferred At the parent level, the New Deferred and Deferred work the same: both open up a new transaction.

    Nested Deferred

    At the subtask level, Nested Deferred works for online task as New Deferred does for Rich Client programs.

    Within Active

    Within Active

    These work the same in both Online and Rich Client. The current task's transactions become part of the parent's transactions.

    ... 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.

  • 47

    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 run.

    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.

  • 48

    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 client.

    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 spreadsheet.

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

    Hint: 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 }

  • 49

    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 JavaScript, 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 accordingly.

  • 50

    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 JavaScript 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.

  • 51

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

    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 http://localhost/pdf/test.pdf.

    See also: The RRC08 sample program in the RIA samples

  • 52

    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.

    Note: 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

  • 53

    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 Monitor.

    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 Monitor).

    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 .publish.html file used to launch the application.

  • 54

    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 module.

    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 folder:

    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.

  • 55

    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 engine.

  • 56

    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

    Prerequisites RIA applications require the following prerequisites to be installed on the client:

    IIS

    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.

  • 57

    ClickOnce 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).

    Note: 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.

  • 58

    Note:

    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 engine.

    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 server.

    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 restrictions.

  • 59

    Firefox This browser provides an add-on to execute ClickOnce applications: https://addons.mozilla.org/he/firefox/addon/1608 https://addons.mozilla.org/he/firefox/addon/9449

    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 URL.

    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').

  • 60

    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.

  • 61

    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.

    Rich Internet Application TutorialChapter 1: IntroductionWhat Is Rich Client?Why Use Rich Client?

    Chapter 2: Constructing a Rich Client TaskHello World, Rich Client StyleRunning the ProgramLeveraging Off What You Know

    A Rich Client Browser ListHow the Task Flows

    Using Colors and Fonts

    Chapter 3: Performance AwarenessBasic Building BlocksVariablesFunctionsUser FunctionsExpressions

    Data View SectionRange and Locate Expre