Contents

Download

April 4, 2000

Hyper Object Page Environment

by Sergey Kucherov

Pattern Definition

Problem:

You need to create Client/Server application to support sophisticated business logic. You have to start testing and deploying first modules of the system before you have finished the development of the whole system and you do not want to reinstall client application every time you add a new module. Also, you do not want to use a web browser as your client application, because you want to be able to use Rapid Application Development features of Delphi.

You will need to design the client application to provide graphic user interface for applications, which are running on the application server. In other words you have to design applications, which will be able to show forms, which has been transferred from the server, but not embedded into client program.

Context:

The pattern is applicable in distributed environments where client platform is Windows 9x/Windows NT. There are no restrictions to server operational environment. The applications interface design required Delphi 3.x or higher.

Forces:

Because using Borland Delphi technologies the client can be only written on Delphi and executed on Delphi-supported platforms. There are no use for this pattern in case of necessity to build application with multi-platform support on client side.

Solution:

There is some innovative technical solution, provided by Borland Delphi development environment. Along with using Windows resources to store visual design component Borland offer ability to store components in text file, using Pascal syntax. Delphi 5 stores all forms in this format by default.

There is the capability to convert a source code to a component at run-time using two routines:

  • ObjectTextToResource reads source code from one stream and write a component in binary format to the output stream;
  • ReadRootComponent - method of a Reader class. Creates run-time component from binary format, created by ObjectTextToResource;
  • Using this algorithm one can transfer Delphi form from server to client and create run-time form on client side. There are following activities, which are necessary to support the form functionality:

  • All components, included in source form should be registered in client application by calling "RegisterClass" routine;
  • Because of this there are no way to recreate a form as a whole (because for each form Delphi creates new class). However, there are possibility to recreate panel, which will own all other components;
  • There is no way to recreate assigned events. To handle events, like pressing buttons, etc, one have to create special controls with additional properties to indicate possible actions (like "Post" or "Clear"). After recreating on client side, one have to assign special routines to handle events like pressing buttons;
  • There is possibility to transfer data along with components. It is make sense, if the data is a constant. For example, label captions and pictures. However, it is more comfortable to transfer modifiable data separately from components and assign it after form is recreated;
  • Examples:

    This is an example of "RemakeForm" method of an empty form in the client application. Input parameter contains component source code. If the form has read component successfully, then one discards old container and replace one by new one:


    function TFormClient.RemakeForm(Buffer: string): boolean;
    const
     BufSize = 4096;
    var
     stTxt, stRes : TMemoryStream;
     rdr: TReader;
     C: TWinControl;
    begin  
     Result := false;
     if Buffer = '' then Exit;

     stTxt := TMemoryStream.create;
     stTxt.Write(Buffer[1],length(Buffer));
     stTxt.position := 0;

     stRes := TMemoryStream.create;
     try
       ObjectTextToResource(stTxt,stRes);
       stRes.position := 0;
       stRes.readResHeader;

       rdr := TReader.create(stRes,BufSize);
       rdr.Owner := self;
       rdr.Parent := self;
       DisableAlign; // to prevent blinking
       try
         TComponent(C) :=
           rdr.ReadRootComponent (nil);
         if C=nil then
           raise Exception.Create(
                         'Invalid form definition');
         if FContainer <> nil then begin
           FContainer.Parent := nil;
           FContainer.Free;
         end;
         FContainer := C;
         FContainer.Parent := self;
       finally
         rdr.Free;
         EnableAlign; // redraw
       end;
     finally  
       stRes.Free;
       stTxt.Free;
     end;
     Result := true;
    end;  

    This is an example how to register components in a client application:


    initialization
     RegisterClass(TPanel);
     RegisterClass(TLabel);
     RegisterClass(TEdit);
     RegisterClass(TCheckBox);
     RegisterClass(TListBox);
     RegisterClass(TButton);
     RegisterClass(TScrollBox);
     RegisterClass(TImage);
     RegisterClass(TMemo);
     ...
    end.

    Resulting context:

    As a result of using such technology you will get "thin" client program, which supports variety of server application without recompiling or reinstalling. Client program should be developed using Borland Delphi 3.x or higher and executed on Delphi-supported platforms (now only Wintel). However, there is no restriction to server application development or operation environment as long as server able to produce source code for Delphi components in text format.

    Rationale:

    In a three-tier Client/Server environment, it is sometimes necessary for a client to be "thin", i.e. do not contain any code, related to business logic. Because of that, thin client should not keep fixed user interface, instead it have to retrieve interface from server. So far, there are only one standard for description of GUI interface - HTML. This format supported by Internet browsers. However, there this format is not flexible enough for business applications and requires a lot of programming on server side. This pattern decreases amount of programming on both sides.

    About the project

    Price Waterhouse MCS was in charge of software development and IT support for the Russian Federal Commission for the Securities Market (FCSM). As part of this contract MCS has developed Securities Market Licensing Information System. The system was designed as a set of modules, which operate in a three-tier client/server environment.

  • Programming environment:
    Borland Delphi Client/Server 3.0, Paradox 3.0, Lotus Notes 4.6;
  • Databases:
    Paradox 5.0, Microsoft SQL Server 4.0, Lotus Notes/Domino 4.6;
  • Team:
    15 system analysts and developers;
  • Duration: 2 years;
  • [HOPE]

    (*)