araujoarthur 0 Posted Monday at 03:49 PM (edited) 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 Monday at 03:49 PM by araujoarthur Share this post Link to post
PeterBelow 247 Posted Monday at 04:14 PM 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. 1 Share this post Link to post
Anders Melander 1861 Posted Monday at 05:50 PM 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. ... 1 Share this post Link to post
Anders Melander 1861 Posted Monday at 10:09 PM 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 😕 1 Share this post Link to post
David Schwartz 440 Posted 4 hours ago (edited) I don't know if it helps, but I gave a talk at CodeRage9 where I covered this topic as part of a larger discussion. Here's a link to the sample files: https://www.dropbox.com/scl/fi/l3026lqvdaqgu9pwbgwey/CodeRage9_code.zip?rlkey=iim76ulqxf7shg2zv4zx155oc&dl=0 You can view it here Edited 4 hours ago by David Schwartz Share this post Link to post