Jump to content
araujoarthur

How can to set up an umbrella unit?

Recommended Posts

I've been wondering, if within my project I have a structure that looks like:

Forms.Dialogs.pas
  - Forms.Dialogs.BaseDialog.pas

  - Forms.Dialogs.IncludeDialog.pas

  - Forms.Dialogs.WarnDialog.pas

  - Form.Dialogs.ErrorDialog.pas

Is it possible to make IncludeDialog, WarnDialog and ErrorDialog available upon uses of Forms.Dialog?

Edited by araujoarthur

Share this post


Link to post
13 minutes ago, araujoarthur said:

I've been wondering, if within my project I have a structure that looks like:

Forms.Dialogs.pas
  - Forms.Dialogs.BaseDialog.pas

  - Forms.Dialogs.IncludeDialog.pas

  - Forms.Dialogs.WarnDialog.pas

  - Form.Dialogs.ErrorDialog.pas

Is it possible to make IncludeDialog, WarnDialog and ErrorDialog available upon uses of Forms.Dialog?

I assume Forms.Dialogs.pas is a unit not defining a form build in the form designer?

In this case I would export functions from that unit that internally create and show(modal) one of the specific form classes, setting any needed setup values from parameters passed to said functions and returning any data entered/selected by the user as function result or in var or out parameters. This way other units need not require the specific form class units in their uses clause, only Forms.Dialogs.

Note that the dialog forms would not be autocreated in this setup, the exported functions would all create, show, and then free a new instance of their dialog form.

  • Thanks 1

Share this post


Link to post
1 hour ago, araujoarthur said:

Is it possible to make IncludeDialog, WarnDialog and ErrorDialog available upon uses of Forms.Dialog?

Not directly; Delphi unfortunately doesn't support "wildcard" includes like that.

 

The way I do it, for something like dialogs, is to associate each dialog with an interface and then separate the implementation of the dialog from the interface:

unit Foo.Dialogs.Bar.API;

type
  IFooDialogBar = interface
    ['{4279694B-C3D6-4B2A-A134-CEACDF6185AF}']
    function Execute: boolean;
  end;
unit Foo.Dialogs.Bar;

interface

uses
  Forms,
  Foo.Dialogs.Bar.API;

type
  TFormFooBar = class(TForm, IFooDialogBar)
    // ...other stuff here...
  private
    // IFooDialogBar
    function Execute: boolean;
  end;

implementation

function TFormFooBar.Execute: boolean;
begin
  Result := (ShowModal = mrOK);
end;

 

In order to create the dialog you could use a factory function like Peter suggested:

function FooDialogBar: IFooDialogBar;
begin
  Result := TFormFooBar.Create(nil);
end;

You will then have to manage the lifetime of the dialog somehow. Since you are accessing the dialog object via an interface you can't just free it once you are done with it. It will have to be done via reference counting.

Unfortunately the default TComponent reference counting will not do it so it will have to be modified (overridden).

 

I have a dialog manager that takes care of all this without the need to modify anything. It handles both modal and non-modal dialogs. I'm in the process of adding it to the translation manager project, so the code it will probably be public later tonight or tomorrow.

 

The dialog manager is used like this:

// Register the dialog API in the initialization section of the disloag unit
initialization
  DialogManager.RegisterDialogClass(IFooDialogBar, TFormFooBar);
end;
...
  // Create dialog
  var DialogBar := DialogManager.CreateDialog(IFooDialogBar) as IFooDialogBar;

  // Display dialog
  if (DialogBar.Execute) then
  begin
    ...
  end;
  
  // Lifetime is controlled via reference counting.
  // When interface goes out of scope, the dialog object is destroyed.
...

 

  • Thanks 1

Share this post


Link to post
4 hours ago, Anders Melander said:

the code it will probably be public later tonight

The API: https://bitbucket.org/anders_melander/better-translation-manager/src/master/Source/amDialog.Manager.API.pas

The implementation: https://bitbucket.org/anders_melander/better-translation-manager/src/master/Source/amDialog.Manager.pas

 

And here's the commit that introduced it: https://bitbucket.org/anders_melander/better-translation-manager/commits/c1341cb4eaaab433ee1680fcbd22e5dc570a5b97

It contains a few examples of changing some modal dialogs from traditional Create/Free to interfaces & DialogManager.CreateDialog.

 

As usual, sorry about bitbucket 😕

  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×