GETTING STARTED - PLUG-IN CLASS TEMPLATE


MAKING THIS UNIT YOUR OWN:
  0) download the pas file here
  1) Delete all references to TTest01 and TTest02.
  2) Do a Global Search and Replace on TTest03 with 
     your own class name
  3) Provide your own file extension and mime type 
     in the [TMyClass]BuildMetaInfoList procedure.
  4) Override the ExecuteModule function to generate 
     your own html (or data) to stream back to the browser.
  5) Rename this unit. 
 

unit uE2WebPkgTest; 
  
interface

uses   PkgPluginMgrIntf, Windows, Messages,
       SysUtils,Classes, Forms, Dialogs,
       E2Primitives;
{$WARN SYMBOL_PLATFORM OFF}
{$WARN UNIT_PLATFORM OFF}
  type  Note: Three test classes are declared and all three 
              will be registerd by the plug-in Manager, but 
              only TTEST03 will recognized by Electron Server, 
              because of the specific interface declarations
  TTest01 = class(TPersistent)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  TTest02 = class(TInterfacedPersistent)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  Note the two COMPULSORY interfaces declared with this class  
  TTest03 = class(TInterfacedPersistent,
                  IMetaInfo,
                  IE2PageModule)
  private
  A method of IMetaInfo Interface Class
    class function GetMetaInfo:TStringList;
  public
    function GetMetaInfoList:TStringlist; virtual;
  A method of IE2PageModule Interface Class    
    function ExecuteModule(Thread:IE2ServerClientThreadPublic):Boolean; REINTRODUCE;
  end;

  TTest03Class = class of TTest03;
implementation

var TTest03MetaInfo:TStringlist;

const Const_Register_Class = 99999;
const Const_ClassType = 12345;

procedure LogThis(s:string);
begin
  //put your logging code here.
end;

 THE FOLLOWING PROCEDURE SHOULD NOT BE MODIFIED 

procedure SendData(copyDataStruct: TCopyDataStruct) ;
var
   processedHandle, receiverHandle : THandle;
   cbInt : integer;//callback value
begin
   cbInt := maxInt;
   receiverHandle := high(longword);//same as maxInt but type consistent...
   processedHandle := 0; //nothing processed yet.
   while receiverHandle <> 0 do
   begin
     if receiverHandle <> high(longword) then processedHandle := receiverHandle;
     receiverHandle := FindWindowEx(application.MainForm.Handle,processedHandle,PChar('TPlugInMgr'), PChar('E2Plugins')) ;

          //NOTE: In case of scenarios where multilple instances of the same app are running,
     //we will pass back the application handle in the "msg.From" parameter to
     //ensure that the correct app instance responds  to the msg.
     cbInt := SendMessage(receiverHandle, WM_COPYDATA, Application.handle{Const_Register_Class}, Integer(@copyDataStruct));
    end;

   if (receiverHandle = 0) and (cbInt = maxInt) then
     begin
       ShowMessage('CopyData Receiver NOT found!') ;
       Exit;
     end;

     if cbInt = 0 then
     LogThis('RegisterClassEx: '+String(copyDataStruct.lpData));
end;



 THE FOLLOWING PROCEDURE SHOULD NOT BE MODIFIED 
procedure SendString(s:string) ;
var
   copyDataStruct : TCopyDataStruct;
begin
   copyDataStruct.dwData := Const_ClassType; //use it to identify the message contents
   copyDataStruct.cbData := 1 + Length(s) ;
   copyDataStruct.lpData := PChar(s) ;

   SendData(copyDataStruct) ;
end;



 THE FOLLOWING PROCEDURE SHOULD NOT BE MODIFIED 
procedure registerClassEx(AClass:TPersistentClass);
begin
  registerClass(AClass);
  sendString(AClass.ClassName);
  //application should never be NIL...
  if application = nil then showmessage('Application is nil in Package');
end;




 THIS IS THE CRUCIAL PROCEDURE WHERE
 THE PLUG-IN CLASS IS ASSOCIATED WITH A 
 FILE EXTENSION AND A CONTENT-TYPE 
procedure TTest03BuildMetaInfoList;
begin
  //Build your metaInfo List here
  TTest03MetaInfo.add('ext=.test');
  TTest03MetaInfo.add('contentType=text/html');
  TTest03MetaInfo.add('pageTitle=Test Module');
end;




{ TTest03 }

 
 The following method is called by ElectronServer when it identifies an HTTP Request matching the 
 MIME (Content) Type of your plug-in class.  Notice that a "serverClientThread" interface reference
 is passed a param.  This interface reference is a "one-stop-shop" helper class providing all the
 information needed about the HTTP request.  There are additional methods to enable the developer
 to write data on to the outgoing stream that will be sent back to the browser.  See the link
 describing all the properties and methods available for IE2ServerClientThreadPublic.

Note: the code in this procedure is "contrived" for simplicity and for purposes of clear 
illustration of the mechanics of the product.

 
function TTest03.ExecuteModule(Thread: IE2ServerClientThreadPublic): Boolean;
var
  PageTitle:string;
begin
  PageTitle :=TTest03MetaInfo.Values['pageTitle'];
  result := false;
  with Thread do
  begin
    QueueStr('<HTML>');
    QueueStr('<HEAD>');
    QueueStr('<title>"Electron 2 Webserver: '+pageTitle+'"</title>');
     QueueStr('</HEAD>');
    QueueStr('');
    QueueStr('<BODY>');
    QueueStr('Server Hit Count: '+BrowserVars['ServerHitCount']);
    QueueStr('<p>ThreadID: '+BrowserVars['ThreadID']+'</p>');
    QueueStr(' -  Thread Hit Count: '+intToStr(thread.GlobalHits));

    QueueStr('<p>Greetings from the Test Module</p>');
    QueueStr('');
    QueueStr('</BODY>');
    QueueStr('</HTML>');
  end;
  result := true;
end;

class function TTest03.GetMetaInfo:TStringlist;
begin
  result := TTest03MetaInfo;
end;

function TTest03.GetMetaInfoList: TStringList;
begin
  result := GetMetaInfo;
end;





Note the use of the all-important registerClassEx() procedure,
that we use instead of the usual registerClass().  This is how we 
hook the RTTI registration of the plug-in class into our Plug-in Manager.

initialization

  registerClassEx(TTest01);
  registerClassEx(TTest02);
  //--Build Meta Info for TTest03-------------
  TTest03MetaInfo:=TStringlist.create;
  TTest03BuildMetaInfoList;
  registerClassEx(TTest03);
finalization
  TTest03MetaInfo.free;
  unregisterClass(TTest01);
  unregisterClass(TTest02);
  unregisterClass(TTest03);
end.