home *** CD-ROM | disk | FTP | other *** search
/ PC Format Collection 48 / SENT14D.ISO / tech / delphi / disk15 / bdedll.pak / DLLUNIT1.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1995-08-24  |  4.0 KB  |  137 lines

  1. unit Dllunit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  7.   Forms, Dialogs, StdCtrls, Buttons, Grids, DBGrids, DB, DBTables;
  8.  
  9. {
  10.   Note that the TDllForm1 form is always used modally.  Borland does not
  11.   recommend using a modeless form from a DLL because the OnActivate and
  12.   OnDeactivate mechanisms do not work when control is transferred between
  13.   a DLL owned form and another DLL or EXE owned form.
  14. }
  15.  
  16. type
  17.   TDllForm1 = class(TForm)
  18.     Table1: TTable;
  19.     DataSource1: TDataSource;
  20.     DBGrid1: TDBGrid;
  21.     OKBtn1: TBitBtn;
  22.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  23.   private
  24.     { Private declarations }
  25.   public
  26.     { Public declarations }
  27.   end;
  28.  
  29. const
  30.   DllErrorUnload = 'The DLL must first be unloaded before re-use';
  31.   DllErrorInUse = 'The DLL is already in use by another application';
  32.   DllErrorViewingTable = 'The table could not be viewed: %s';
  33.  
  34. var
  35.   DllForm1: TDllForm1;
  36.  
  37. {
  38.   UseDLL should be called to verify that the DLL may be used by the
  39.   current application.
  40.  
  41.   ExitDLL should be called before the DLL client exits.  It CANNOT be
  42.   called from a DLL WEP.
  43. }
  44.  
  45. function UseDLL: string; export;
  46. procedure ExitDLL; export;
  47. function ViewTable (const TableName: string): string; export;
  48.  
  49. implementation
  50.  
  51. var
  52.   Task: THandle;
  53.   Unloaded: Boolean;
  54.  
  55. {$R *.DFM}
  56.  
  57. {
  58.   Exceptions that are raised across a DLL call boundary cause an application
  59.   termination.  Therefore they are caught here and converted to an error
  60.   return.  The caller may convert back to an exception (if written in Delphi
  61.   or C++) or pass the result back through some other error handling mechanism.
  62.  
  63.   Note that if ViewTable may be called by a C client, the TableName parameter
  64.   should be a PChar rather than a string, and all error returns should be PChar,
  65.   integer, or some common inter-language type.  Here the types are string to
  66.   make the code just a little more straightforward.
  67. }
  68.  
  69. function ViewTable (const TableName: string): string;
  70. begin
  71.   try
  72.     if not Assigned (DllForm1) then
  73.        DllForm1 := TDllForm1.Create (nil);
  74.  
  75.     with DllForm1 do
  76.     begin
  77.       Table1.TableName := TableName;
  78.       Table1.Active := True;
  79.       ShowModal;
  80.       Result := ''
  81.     end
  82.   except
  83.     on EResult: Exception do
  84.       Result := Format (DllErrorViewingTable, [EResult.Message]);
  85.     else
  86.       Result := Format (DllErrorViewingTable, ['Unknown error']);
  87.   end
  88. end;
  89.  
  90. { Deactivate the table before the form is closed }
  91.  
  92. procedure TDllForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  93. begin
  94.   Table1.Active := False;
  95. end;
  96.  
  97. {
  98.   Some services need to be de-initialized before the DLL WEP is called during
  99.   DLL unload.  BDE is an example of a service that cannot be de-initialized
  100.   from within the WEP.  The following routine must be called by the user of
  101.   this DLL to de-initialize this DLL and its services.  Once the
  102.   deinitialization occurs, the DLL cannot be used again until it is unloaded.
  103. }
  104.  
  105. procedure ExitDLL;
  106. begin
  107.   CallExitProcs;
  108.   Unloaded := True;
  109. end;
  110.  
  111. {
  112.   Many services require per-task initialization.  BDE is an example of such
  113.   a service.  If a service DLL uses other such services, it too may require
  114.   per-task initialization.  Since the VCL BDE Session variable is allocated
  115.   and initialized per-module rather than per-task, multiple applications
  116.   cannot simultaneously use a DLL that itself uses BDE.
  117.  
  118.   In this demo service, multiple access is protected against via
  119.   initialization and use validation routines.  Another application
  120.   (.EXE or .DLL in another task) cannot use this DLL until the first
  121.   application unloads the DLL.  For statically linked DLLs, the unload
  122.   occurs automatically during application termination.
  123. }
  124.  
  125. function UseDLL: string;
  126. begin
  127.   if Task <> GetCurrentTask then Result := DllErrorInUse else
  128.   if Unloaded then Result := DllErrorUnload
  129.   else Result := ''
  130. end;
  131.  
  132. { Initialize the task as soon as this service is loaded }
  133.  
  134. begin
  135.   Task := GetCurrentTask
  136. end.
  137.