Creating a custom form designer - delphi

I'd like to create a custom "datamodule" in Delphi, a TDataModule like (maybe inherited) class which would have a custom grid based design interface (one component per line, some properties as columns). Is this possible? Where should I start?
I'm currently using Delphi 2007.

Maybe it is possible. An example of a XML Frame Designer can be found on the page New IDE Building Blocks. Well this example is for Delphi 5, but it might be a good starting point.

As Nick Hodges pointer out here:
Drawing on a DataModule in Delphi
it would be difficult to paint on the TDataModule descendant. Not impossible probably, but not worth the trouble for sure.
I would consider designing a completely new TDataModule from scratch, so you would have complete control over it. Sure a lot of work probably, but in the end it would pay off.
You can find TDataModule class in the Classes.pas unit. But this is just the runtime part of the code. Other parts are IDE related. You can find units related to ToolsAPI in "c:\Program Files\Borland\BDS\4.0\source\ToolsAPI\" for BDS 2006 for instance. You can also derive you own data module from TDataModule and register it with RegisterCustomModule (DesignIntf.pas). I don't know much more on this subject, maybe others do. As I said it would not be easy to do something like that. But maybe with this initial information you can find what you want.

It's not possible exactly as you describe it. You can't place visual components like a grid on a data module. You need a form or frame for that.
If I were to do try to something like you're describing, I'd use a list box to hold a list of individual components, a couple buttons and a selection dialog box for adding and deleting components from the list, and the TJvInspector component from the JVCL for modifying properties. That would be a lot easier than trying to make a one-size-fits-all grid to handle the situation.

Related

How to get list of objects accessible to a project?

I'm trying to figure out how to access a list of objects available in the Delphi IDE (ie., from different namespaces) from within a component editor. (Also from the same editor form running independently.) LiveBindings do it, and there's a video where they say you have to have a unit listed in a uses clause in order for the LiveBinding editor to see the classes defined inside that unit. But it does not have to be a form.
I can access forms through the Application.components array, but that only gives me access to the TForm objects. Any classes defined in the same units with the form aren't visible, nor are classes defined in any units that are not forms.
Someone suggested the answer lies buried somewhere in the Open Tools API.
I thought there might be someone here who could shed a bit more light on the subject.
BTW, I'm using DXE5, but anything from version XE and up is probably the same.
NOTE: I did find a property somewhere that lists every single class and record defined in the entire freaking ecosystem. There are hundreds of them! That's not much help. Still looking.

Delphi component's programming

Does anybody know if it is possible to visually see and edit components at developing time? i would like to create a component based on TPanel, but i dont have any design window (or dfm) where i can visually add components on it, i found related threads in which some programmers claim its not possible.
Any ideas if its possible and how?
thnx
Nope. Using frames is the best you can do to develop compound components with the aid of the visual designers.
See this article http://etutorials.org/Programming/mastering+delphi+7/Part+II+Delphi+Object-Oriented+Architectures/Chapter+9+Writing+Delphi+Components/Creating+Compound+Components/
And specifically the section "Building Compound Components with Frames".
Make a project group.
Add a package to that project group.
Add/install a component in that package.
Add a VCL forms application to the project group.
Right click on a project group and choose build all.
This way you will be able to 'visually' track the progress of your component during the development.
An alternative to compound components is to use component templates.
They're not proper components, rather they're just a shortcut to you copying and pasting the components and their event handlers from one form to another. You can manipulate them using the designer though so they may be suitable for your purposes.
what you are asking is, I believe, is how to create components and interact with them at design time no ?(by example the behavior of datasets, properties of a form,etc).
here you have an example
http://www.podgoretsky.com/ftp/docs/Delphi/D5/dg/register.html
best regards,
Radu
I take this question to mean that you wish to develop a custom component and to do so visually rather than in code. If that is your question then I'm afraid that you can't do it.

Help with Delphi DFM generation based on Database Tables (Scaffolding?)

I'm new to delphi and I'm looking up on ways to learn more about delphi underlying technology plus make something useful here in my job in the process, also if anyone has any tip or see anyway i can improve my idea please fell free to speak your mind...
i want to do make some kind of Scaffolding for dfms, the ideia is the following: i want to generate based on a firebird database table - with well defined domains - the bulk of the Form .
I think the idea is too simple or i'm not seeing the big picture that makes it difficult, i'm trying not to reinvent the well, i've looked up on google but without good results, so if anyone could giveme a direction here i would be most grateful.
UPDATE:
#Larry Lustig thanks, i didn't think about delphi frameworks - i'm going to look them up.
i know something about form objects/handling and database metadata, but i'm unfamiliar with serilizing delphi objects to the HD. Any tips on Serialization and delphi frameworks (opensource so i could take a look :) ) would be welcome!
Sounds like an interesting idea.
Instead of writing a DFM form manually on disk I would use the following approach:
Get the structure of your table by examining the meta data.
Create a TForm and add a control to it for each column you want to represent.
Use Delphi's built in serialization to save the form to disk.
I haven't done this myself, but there are a number of run-time design frameworks that work using this idea.
This would only make sense if you need to build a lot of forms at design time. You can't use the DFM's in your executable's. If you want to build the forms runtime, I suggest you go with Larry Lustig's answer.
We have taken this one step further... we don't build forms. We only write the classes, add some attributes and create the forms at runtime. Users can change this preset form layout during runtime and save their own layout. Data binding between the controls and the database is done with the excellent tiOPF framework. Maybe something you can consider to use as well.

Where should I put my utility methods? How can I used my customized form? (Delphi)

I've been using Delphi for a little over a month, but I still do not know the proper way of doing things.
If I have methods which I can use on a lot of projects should I put them on a Unit, Form or DataModule?
I have not used a unit (in itself), New-> Unit. Should I put my utility methods there? If so, is there an example I can look at, a tutorial or whatever.
I've used DataModules in the past, though it gives me the impression that it should only be used when I'm dealing with databases and such.
Another thing, I'm customizing some forms (for instance a form with some TEdits that do specific things).
To use this, first I add this to the uses in the .dpr
CustomizedForm in '\CForm\CustomizedForm.pas' ;
then I add CustomizedForm to the uses in my mainform (where I'll be using it).
Is this the correct way to do it? I'm was just guessing, it seems to work though I'm not particularly confident that it's the proper way.
I put all mine in a unit called utils.pas. It works for me.
If you have different segmentations of utilities that some programs use but not others, you may want to create separate units for them.
Look at: Anatomy of a Delphi Unit
It is part of the excellent Beginner's Guide to Delphi Programming by Zarko Gajic that is very worthwhile to go through.
For the best "visual" introduction, see Nick Hodges' Thirty Camtasia Demos in Thirty Days. It is for Turbo Delphi which no longer is offered, but is still very similar to full Delphi and lets you visually get a feel for how to do things in Delphi.
Where you put things depends on what they do. The unit associated with a form should really only contain code that's directly related to the user interface that the form presents. Putting business logic directly into a form unit is considered bad practice for a number of reasons. If your utility methods aren't part of a specific form, it's best to put them in a Unit.
As for Data Modules, they're containers for holding non-visual controls. As the name implies, they were created for database access, but they can hold all sorts of other things. For example, at work we have a handful of data modules that contain TImageList controls, which hold lists of icons that are used in various places throughout the app. If you have any non-visual controls that you need to share with several different forms, a Data Module is the logical place to put them.
And yeah, it looks like you're doing the customized form right. If you have a second form that the first form needs access to, (to make it show up when you hit a button or menu item, for example,) then the first form's unit will need the second form's unit in its uses clause. (There are ways around this involving class registration techniques, but that's an advanced topic.)
You might want to avoid using the global form variable that Delphi likes to set up in a form unit, though. It makes your program start up more slowly, and using globals is another thing that's considered a bad practice. A form is an object like any other Delphi object, and you can create it with its constructor, call Show or ShowModal to make it appear, and then call Release or Free on it (read up on TForm.Release in the helpfile to know when you need to use it) when you're done with it.
For starters, create a few different units based on categories - StringUtils.pas, MathUtils.pas, DateTimeUtils.pas, etc - put your functions into those units according to category and be sure to include all the prototypes in your interface section so they'll be visible to other units (but don't get too caught up in how to categorize things...) and keep all your util units in a separate, dedicated directory. Then, point your Delphi or Project library paths to that directory and you'll be able to use the functions in all your utility units. Eventually, you may want to make the units into classes with class functions or persistent structures etc. I myself generally create a project group that includes a package called MyProjectUtils.bpl and I put all my utility units and classes into that package. I never actually deploy it as a package, but since they are wrapped up together I can always check that they all compile properly and they are all available immediately for browsing in the IDE, etc.

Interposer class

Do I need to put my Interposer class in
all the form that will the particular class ?
Say I want to re-implement TPanel, I redeclare
it as TPanel = class(ExtCtrls.TPanel) in the unit.
Do I need to do this in all the unit that uses
TPanel ?
Thanks in advance !
You yourself have acknowledged that this is a hack. It's not meant to scale well. It's meant for one-time cases where it's not worth the trouble to "do it right" by writing a bona fide custom control.
You can try putting your new class declaration in a separate unit. Make sure that unit appears on uses clauses after the VCL unit that declares the "real" version of the class. If that doesn't work, then yes, you need to make new declarations in every unit that uses the hack.
Since you're doing this to turn TLabel into TStaticText, you'd probably be better off simply changing your TLabel controls into real TStaticText controls on your forms. (That was the answer the last time you asked about this.) That way, the program you ship will be the same program you tested. Otherwise, you're testing a program with one kind of control and shipping one with another.
If you want to design a new component, you'll have to give it a unique name. Otherwise the form designer and the serialization code won't be able to tell them apart. Call it TRoderickPanel or something. Then just replace all your TPanel objects with TRoderickPanel objects on every form that uses them. (GExperts adds a right-click option that makes this much easier.)
Depending on the functionality you are trying to add, you could consider using a class helper. If what you need cannot be done that way, I'd just bite the bullet and create a new class like Mason said. Replacing it right through your code is not that hard really, given that form files are also stored as text.
If you also have Visual Studio installed, that actually has a "Replace in files" command. On top of that I'm sure Google will be able to help you out with stand-alone tools. And I haven't used GExperts in a while, but I'm almost certain that had a "Replace component" command.
This is a far better solution for the long term. If you can use a class helper for what you need, that may be quicker, simpler and less work.
I would instead use the GExperts wizard to replace components to get the behavior you are wanting. Doing what you are suggesting would require re-registration of the components so that the DFM loading mechanism created the proper components, and if I'm not mistaken, the component registry doesn't allow duplicates so would generate an exception. What your suggesting works well with classes, but not components used on a form.
You can put your interposer class into a Unit and add that unit on the uses clause of all units where your interposer needs to act. Pay attention to add this unit AFTER the unit ExtCtrls on the uses clause, otherwise, it will not work

Resources